Hardening Your MODX Site

I don’t claim to be an expert on hardening web sites, but I thought I’dMODX logo write about something a little concerning, basically I’ve learned about how MODX protects your web site from malicious code, and more importantly how and when it doesn’t.


MODX Security at Work

All standard MODX pages are delivered via index.php.

The code in index.php does this:

[code language=”php”]

/* At the beginning */
if (!defined(‘MODX_API_MODE’)) {
define(‘MODX_API_MODE’, false);

/* At the end */

That means that for every request to your site (with an exception we’ll discuss in a bit), the first thing that handleRequest() does (after loading the error handler) is call sanitizeRequest(). Here is the whole sanitizeRequest() function:

[code language=”php”]
public function sanitizeRequest() {
$modxtags = array_values($this->modx->sanitizePatterns);
modX :: sanitize($_GET, $modxtags);
if ($this->modx->getOption(‘allow_tags_in_post’,null,true)) {
modX :: sanitize($_POST);
} else {
modX :: sanitize($_POST, $modxtags);
modX :: sanitize($_COOKIE, $modxtags);
modX :: sanitize($_REQUEST, $modxtags);
$rAlias = $this->modx->getOption(‘request_param_alias’, null, ‘q’);
if (isset ($_GET[$rAlias])) {
$_GET[$rAlias] = preg_replace("/[^A-Za-z0-9_\-\.\/]/", "", $_GET[$rAlias]);

The code above sanitizes the $_GET, $_POST, $_COOKIE, and $_REQUEST, arrays by removing any script tags, and any MODX tags, assuming that you have the allow_tags_in_post System Setting off — (and you definitely should).


When it Doesn’t Happen

If you have Friendly URLs on, which almost all of us do, the rules in the .htaccess file specify that if the page being requested isn’t found (which it generally won’t be, because the pages are in the database, not on the disk), index.php is loaded. The code above will execute, then MODX will look for the requested page in the database, prepare it, and send it off to the browser.

What if the file *is* found, though? If you have a .php or .html file on your site that is available via web browser, a request for that file will bypass MODX altogether. If the file presents a form and posts to itself, malicious code will not be sanitized unless you do it yourself in the code that processes the form.

Even if you sanitize the user input before processing it, you may still be vulnerable. If your form validates the user input and re-displays the form if there is an invalid entry (without sanitizing), malicious code in the form may still execute. This is generally only a problem with text input, not checkboxes or lists, but most forms have at least some text input.

The best way, by far, to make sure you are protected is to move the MODX core above the web root and put any executable .php files or .html files that contain PHP code under the core directory. Properly written extras put all executable PHP files under core/components/componentname. Moving the core is strongly recommended by MODX and you can see why. Once you move the core, no files in that directory, including all the MODX core files, can be executed from a browser.

An added protection is to use a host that has suPHP or suExec running and set the folder and file permissions to 755 and 644. This makes the files executable by you or by MODX, but leaves them as read-only for everyone else. If you look at your folders and files in PhpMyAdmin’s File Manager and see that their permissions are set to 755 and 644, the odds are good that suExec or suPHP is running.

Of course, that won’t help you with a web form that’s in a PHP file, or processed by a PHP file. Or a form processed with PHP that’s in an .html file. Usually, those situations are the result of importing code from outside of MODX. There are three possible solutions. One is to call $modx->sanitizeRequest() a the top of the processing code, but that only works if the $modx object has been instantiated in your code. The second is to copy the sanitizeRequest() function above to the top of your code, modify it so it works outside of MODX, and call it before doing any processing. The third, and probably best, method is to convert the code to a MODX snippet and let MODX handle the sanitizing. This can be a challenge if the code has mixed PHP and HTML, but it’s usually worth the effort.


Renaming the MODX Directories

Renaming the main MODX directories also helps protect your site. Remember that the MODX core code is public. Anyone can download it, study it, and test attack strategies against it. If a malicious person finds a vulnerability in some code in the MODX manager directory, renaming that directory (and others) will make it very difficult for them to attack your site. There are instructions for moving the core and renaming the directories, here

Renaming the Manager directory will also prevent people from launching brute-force attacks that attempt to log in over and over with generated usernames and passwords. If you have a strong username and password, they are unlikely to succeed, but they’re putting an unnecessary load on the server. If you rename the Manager directory, they’ll get a 404 page instead of the Manager login page. They’ll most likely go away after a single try rather than hammering away at the site.


Another Potential Vulnerability

A few of my extras were found to have a somewhat exotic vulnerabilty (now fixed) because they recorded URLs and information about the user’s visit (e.g., the user agent) which could be viewed later in a report. If you use xPDO to save your data, xPDO sanitizes it against MySQL injection attacks, but it doesn’t remove script tags, since MODX resources, templates, and chunks might contain legitimate script tags. The problem was compounded by the fact that the sanitizeRequest() code above doesn’t sanitize the URL or any other $_SERVER variables like $_SERVER['HTTP_USER_AGENT'].

Saving malicious code that was part of the URL or user agent string to the database caused no trouble. But when user’s view the report in their browsers, the malicious code could execute.

My mistake was in a) assuming that MODX’s sanitization of the request protected against this, and b) failing to think of this data as user input. It usually isn’t, because it’s set automatically by the browser and the server, but it can be.


Foreign Data

If you use a web service (e.g., Mandrill, MailChimp, a real estate database), or import data (e.g., importing WordPress users), the site you get your data from may have been compromised. In that case, the data could contain malicious code. Always sanitize it before saving or displaying it.


Using .htaccess to Protect Directories

If you have directories with sensitive files, you can keep them from being viewed or executed by putting an .htaccess file in the directory with code like this:

[code language=”html”]
IndexIgnore */*
<Files *.php>
Order Deny,Allow
Deny from all

<Files *.log>
Order Deny,Allow
Deny from all

The example above prevents visitors from viewing or executing the index file, PHP files, and any files ending in .log. Your PHP code and MODX will be able to read and execute the files, but they won’t be available for anyone visiting with a browser.


Final Notes

Here’s a quick checklist of things to do to make your site more secure:

  • Move the MODX core above the web root.
  • Rename the main MODX directories (core, manager, connectors, assets).
  • Don’t use anything like admin, root, manager, or any username that people could guess (e.g. BobRay) as your admin username.
  • Don’t use words that might be in the dictionary or common names for your username. Make up combination of non-words like PleenkFinbrun, or (better) use a random string of characters.
  • Use a strong, long password — again, no dictionary words or common names.
  • Use a different username and password for your Manager, cPanel, database, and FTP credentials.
  • Use a MODX-Friendly host that runs suPHP or suExec, and make sure all folder/file permissions are 755/644.
  • Never, ever, trust user input! This includes data from any source outside your site.


For more information on how to use MODX to create a web site, see my web site Bob’s Guides, or
better yet, buy my book: MODX: The Official Guide.

Looking for quality MODX Web Hosting? Look no further than <a
href=”http://bit.ly/YgFGHl”>Arvixe Web Hosting!

Tags: , , | Posted under MODX, MODX | RSS 2.0

Author Spotlight

Bob Ray

Bob Ray is the author of MODX: The Official Guide and over 30 MODX add-on components. He hosts Bob's Guides, a source of valuable information for MODX users, and has been very active in the MODX Forums with over 19,000 posts.

Leave a Reply

Your email address will not be published. Required fields are marked *