MODX Site Security Audit
MODX Revolution has good basic security — connectors are protected by tokens, control panel (/manager/) is closed to bots. Nevertheless, outdated Extra, incorrect file permissions, and custom code create vulnerabilities.
Scanning
# CMS-specific scanner
python3 -m drupwn --mode detect https://yourdomain.com # no MODX-specific, use general
# Nikto
nikto -h https://yourdomain.com
# Dirbusting (search for hidden files)
ffuf -w /usr/share/wordlists/dirb/common.txt -u https://yourdomain.com/FUZZ
Checklist
File Structure:
# Is core above web-root?
ls /var/www/yourdomain.com/core/ # Should NOT exist (if moved)
# Permissions on config.core.php
stat /var/www/yourdomain.com/config.core.php
# 644 or less
# Permissions on assets folder
find /var/www/yourdomain.com/assets/ -name "*.php" -type f
# PHP files in assets — sign of compromise
# Installer temporary files
ls /var/www/yourdomain.com/setup/ # should not exist after installation
Nginx protection for MODX:
# Close system directories
location ~ /(core|manager/includes)/ { deny all; }
location ~ /config\.core\.php$ { deny all; }
# Forbid PHP in assets (uploaded files)
location ~* /assets/.*\.(php|phtml|php3)$ { deny all; }
# Restrict access to manager
location /manager/ {
allow 1.2.3.4; # your IP
deny all;
}
MODX Version:
# Hide MODX version from HTML
# System → Settings → manager_login_startup_update = 0
# Check meta generator in HTML:
curl -s https://yourdomain.com/ | grep -i "modx\|meta.*generator"
System Security Settings:
session_cookie_secure: Yes (HTTPS only)
session_cookie_httponly: Yes
session_cookie_samesite: Strict
failed_login_attempts: 5 (login attempt limit)
blocked_minutes: 60 (block after limit exceeded)
Check Extra for Vulnerabilities: MODX vulnerability registry: no centralized, but check versions in Package Manager. Outdated Extra with known vulnerabilities: FormLister (outdated, use FormIt instead), some Ajaxform versions.
Custom Code — SQL Injection:
grep -r "\\\$_GET\|\\\$_POST" core/components/myextra/
grep -r "->query\|->exec" core/components/myextra/ | grep -v "prepare\|quote"
// Unsafe:
$db->query("SELECT * FROM table WHERE id = " . $_GET['id']);
// Correct:
$c = $modx->newQuery('MyObject');
$c->where(['id' => (int)$_GET['id']]);
CSRF Protection: MODX uses connector tokens to protect against CSRF in Connector requests. Ensure custom connectors don't bypass this check.
Security Headers
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'" always;
add_header Strict-Transport-Security "max-age=31536000" always;
Timeline
MODX site security audit with report — 1 day. Remediation of found issues — 4–8 hours.







