Moodle Security Hardening Guide for 2026: Protect Your LMS
Education remains a high-value target because LMS platforms combine identities, grades, submissions, messaging, integrations, and privileged administrator workflows. Moodle publishes security advisories and supported-release updates regularly, which means patching and configuration need to be treated as operational controls, not occasional cleanup.
Most Moodle incidents don't start with zero-day exploits. They start with delayed patching, misconfigured servers, and default settings left unchanged. This guide gives you the complete hardening checklist -- from file permissions and PHP settings to authentication, patching, and supported-release planning -- so you can stop wondering whether you're protected and start knowing.
Use this as technical hardening guidance. Validate the final control set against your institution's risk model, hosting architecture, and incident-response policy.
1. File System Permissions
Incorrect permissions are one of the most common Moodle installation mistakes and among the easiest to exploit.
Application directory (/var/www/moodle/): Set ownership to root:root. Directories should be 755, files 644. This prevents the web server process from modifying application code, which stops code injection attacks cold.
config.php: After installation, set it to 444 (read-only for all). Never leave it writable by the web server. An attacker who can write to config.php owns your entire Moodle instance -- database credentials, session secrets, everything.
Moodledata directory (/var/moodledata/): This must be writable by the web server, so set ownership to www-data:www-data. Directories 700, files 600. Critically, moodledata must live outside your web document root. If it's browser-accessible, attackers can download student submissions and session files directly.
Run Moodle's built-in check at Site Administration > Reports > Security Checks -- it flags permission issues automatically.
# Set application directory permissions
chown -R root:root /var/www/moodle
find /var/www/moodle -type d -exec chmod 755 {} \;
find /var/www/moodle -type f -exec chmod 644 {} \;
chmod 444 /var/www/moodle/config.php
# Set moodledata permissions
chown -R www-data:www-data /var/moodledata
find /var/moodledata -type d -exec chmod 700 {} \;
find /var/moodledata -type f -exec chmod 600 {} \;2. PHP Hardening
PHP's default configuration is built for development convenience, not production security.
- Disable dangerous functions that allow PHP to execute OS commands:
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,parse_ini_file,show_sourceNote: Some Moodle features and plugins use exec. Test your plugins before applying this in production.
- Lock down error display -- stack traces in production tell attackers your file paths and database structure:
display_errors = Off
log_errors = On
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
expose_php = Off- Harden sessions to block the most common hijacking techniques:
session.cookie_httponly = 1
session.cookie_secure = 1
session.use_strict_mode = 1
session.cookie_samesite = Lax- Restrict file system access to contain any file-inclusion vulnerability:
open_basedir = /var/www/moodle:/var/moodledata:/tmp
allow_url_include = Off3. Database Security
Your Moodle database contains every grade, every student record, and every audit log. Treat it accordingly.
- Dedicated database user: Create a MySQL/MariaDB user with only the privileges Moodle needs (SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP, INDEX) on the Moodle database only. Never use the root database account.
- Bind to localhost: If Moodle and the database are on the same server, bind MySQL to 127.0.0.1. Exposing port 3306 to the internet invites brute force within minutes.
- Enable TLS for remote connections: If your database is on a separate server, encrypt the connection. In cloud environments, traffic between instances traverses shared infrastructure.
- Encrypt at rest: Consider MySQL/MariaDB Transparent Data Encryption (TDE) to protect data files on disk against physical theft or backup exposure.
4. config.php Security Settings
// Force HTTPS
$CFG->wwwroot = 'https://yourmoodle.example.com';
// Secure cookies
$CFG->cookiesecure = true;
$CFG->cookiehttponly = true;
// Reduce session timeout from 8 hours (default) to 2 hours
$CFG->sessiontimeout = 7200;
// If behind a load balancer or reverse proxy
$CFG->sslproxy = true;
// Disable debug output
$CFG->debug = 0;
$CFG->debugdisplay = 0;
// Keep moodledata outside web root
$CFG->dataroot = '/var/moodledata';
// Disable Gravatar (prevents external data leakage)
$CFG->enablegravatar = false;The default 8-hour session timeout is too generous. If a student leaves a library computer without logging out, that's 8 hours of open access. Two hours is a reasonable balance for most institutions.
5. SSL/TLS and Security Headers
HTTPS is non-negotiable, but the certificate is just the starting point.
TLS configuration: Disable TLS 1.0 and 1.1 -- both have known vulnerabilities. Require TLS 1.2 as a minimum and prefer TLS 1.3. Use Let's Encrypt with certbot for free, auto-renewing certificates. This eliminates both the cost barrier and the "forgot to renew" failure mode.
Essential security headers:
| Header | Value | Purpose |
|---|---|---|
| Strict-Transport-Security | max-age=31536000; includeSubDomains | Forces HTTPS, eliminates SSL stripping |
| X-Frame-Options | SAMEORIGIN | Blocks clickjacking via iframes |
| X-Content-Type-Options | nosniff | Prevents browsers treating uploads as executable |
| Referrer-Policy | strict-origin-when-cross-origin | Stops Moodle's sesskey tokens leaking in referrers |
The referrer policy is Moodle-specific: the sesskey is part of Moodle's CSRF protection, and leaking it via referrer headers weakens that defense.
Content Security Policy (CSP): Use the Catalyst local_csp plugin for GUI-based CSP management. Start in reporting mode to identify what your site loads, build exception rules, then switch to enforcement. Moodle's inline scripts and dynamic content mean a fully restrictive CSP will break features -- test thoroughly before enforcing.
6. Moodle's Built-In Security Checks
Before reaching for any external tool, Moodle has a powerful self-audit report built right in. Navigate to Site Administration > Reports > Security Checks and run it monthly -- not just at setup. Configuration drift from plugin updates or OS changes can silently flip green checks to red without any deliberate action on your part.
The report automatically validates your configuration across 10+ checks, covering everything from whether PHP errors are visible to users, whether your moodledata directory is browser-accessible, whether config.php is writable, and whether your password policy is active. Each failed check links directly to the setting that needs fixing.
Green across the board is your security baseline. Any flag is a remediation task, not a suggestion. For the full list of checks and what each one means, see the official Moodle Security Checks documentation.
7. OWASP Top 10: Where Moodle Stands
Moodle's development team explicitly references OWASP standards. Here's the reality of the OWASP Top 10 2025 categories -- what Moodle handles and what you must configure yourself.
| OWASP Category | Moodle's Built-in Defense | Your Responsibility |
|---|---|---|
| A01: Broken Access Control | Capability system (has_capability), role-based permissions | Audit role assignments, enforce least privilege |
| A02: Security Misconfiguration | Security Overview Report, hardening documentation | Apply this hardening guide, run security checks regularly |
| A03: Software Supply Chain Failures | Plugin review process, signed releases, security advisories | Remove unused plugins, track versions, patch promptly |
| A04: Cryptographic Failures | HTTPS enforcement, bcrypt password hashing, secure cookies | Configure TLS properly, enable database encryption |
| A05: Injection | Parameterized queries ($DB API), HTML Purifier, sesskey tokens | Keep Moodle updated, audit third-party plugins |
| A06: Insecure Design | Security-first development policy, code review process | Review custom code and plugin selections |
| A07: Authentication Failures | MFA (tool_mfa), password policies, account lockout | Enable MFA for all admins, configure strong password rules |
| A08: Software/Data Integrity | Signed releases, update verification | Verify checksums, use trusted plugin sources only |
| A09: Security Logging and Alerting Failures | Event logging, admin audit trail | Review logs regularly, set up alerting |
| A10: Mishandling of Exceptional Conditions | Error display controls, exception handling patterns | Keep debug output disabled in production and test failure paths |
The key gap: third-party plugins don't undergo the same security review as Moodle core. This is where most post-breach forensics point.
8. Authentication Hardening
Authentication is your primary defense against unauthorized access. Most installations don't use Moodle's tools fully.
Multi-Factor Authentication (MFA): Moodle 4.0+ includes tool_mfa supporting TOTP (Google Authenticator, Authy), FIDO2/WebAuthn hardware keys, and email verification. Enable MFA for all administrator accounts at minimum -- ideally for all users. The MFA plugin uses a weight system, giving you flexibility: trusted IP ranges can count as a partial factor, reducing friction for on-campus users.
Password policy (Site Administration > Security > Site Policies):
- Minimum 12 characters (the 8-character default is inadequate by 2026 standards)
- Require uppercase, lowercase, digits, and special characters
- Account lockout after 5 failed attempts
- Consider the Catalyst Password Validator plugin to check against the Have I Been Pwned breach database
Brute force protection: The auth_antihammer plugin blocks users and IPs that repeatedly hammer authentication. Combined with fail2ban on your server monitoring web server logs, you create layered protection against credential stuffing and password-spraying attacks.
9. Logging and Patch Management
What to actively monitor:
- Failed login spikes: Indicate brute force; integrate with fail2ban for automated response
- Admin account activity: Unexpected admin actions outside business hours are a red flag
- Plugin installations and updates: Unauthorized plugin installation is a common attack vector
- Role escalations: Monitor when users receive elevated permissions
- Security Checks report: Run Site Administration > Reports > Security Checks monthly; it validates 15+ settings automatically
Patch management: Moodle publishes regular minor releases and security announcements for supported branches. Subscribe to the Moodle Security Announcements forum and register your site at moodle.org to receive private advisories before public disclosure -- this gives you a head start before vulnerabilities are widely known. Registration takes 5 minutes. For CVSS 9.0+, patch within 48 hours. For high-severity issues, patch within your regular maintenance window. Always test on staging before production.
10. Moodle 5.x Security Improvements
If you're still on Moodle 4.x, the 5.x series brings meaningful security enhancements.
Moodle 5.0 (April 2025): Improved MFA admin setup with clearer factor explanations. New clean_string() function for better template rendering security. Self-hosted AI model support via Ollama, eliminating the need to send student data to third-party AI providers.
Moodle 5.1 (October 2025): The most significant architectural change in recent Moodle history -- core directories (admin, lib, config.php) have been moved outside the publicly accessible /public/ directory. Your web server document root now points to /public/ only, preventing direct browser access to sensitive application files.
Important: Upgrading to 5.1 requires web server reconfiguration -- your document root must be updated to point to /public/. Plugin code remains in Moodle's normal plugin directories under the main codebase; do not move plugin trees into /public. Always test on staging first and read the official upgrade notes before upgrading production.
The current LTS version is Moodle 4.5, which receives security updates until October 2027. Moodle 5.2 is the current stable release as of May 2026 and also receives security support until October 2027. If your priority is LTS stability, use 4.5. If you want the newer architectural security improvements (like the /public/ restructure), plan a supported 5.x upgrade after plugin testing.
Hardening Checklist
- File permissions set:
root:rooton application,www-data:www-dataon moodledata config.phpset to444(read-only)- moodledata located outside web document root
- PHP hardened:
display_errors Off, expose_php Off, open_basedirset - Session cookies:
httponly, secure, samesiteall enabled - Dedicated database user with minimum required privileges only
- Database bound to localhost or restricted by IP
- TLS 1.2+ enforced, TLS 1.0/1.1 disabled
- Security headers configured (HSTS, X-Frame-Options, CSP)
- MFA enabled for all administrator accounts
- Password policy updated (minimum 12 characters, lockout after 5 attempts)
- Registered at moodle.org for private security advisories
- Security Checks report reviewed this month
- Patch process documented with <48hr SLA for critical CVEs
How MooDIY Cloud Handles This For You
Implementing a complete security hardening checklist can take 40-80 hours, but ongoing maintenance -- monthly patching, security-header review, audit log checks, and keeping PHP and system dependencies current -- is where most teams face the real challenge.
MooDIY Cloud addresses this by managing security end-to-end:
Pre-hardened from day one -- Every Moodle instance is delivered with secure configurations already in place, including file permissions, PHP settings, security headers, and a locked-down config.php. You don't configure security from scratch -- you inherit a hardened baseline. Ready to run Moodle on a secure, pre-hardened platform? Explore MooDIY hosting plans
Research References
- Moodle Security Recommendations -- Official Moodle hardening documentation covering file permissions, password policies, and general best practices
- Moodle Security Checks -- Full explanation of every check in the built-in Security Checks report and how to resolve failures
- Moodle Site Security Settings -- All configurable security settings available under Site Administration > Security
- Moodle Multi-Factor Authentication -- Complete guide to enabling and configuring tool_mfa, factor weights, and deployment strategies
- Moodle Security Announcements -- Official CVE disclosures and patch notices; subscribe to receive private advisories before public release
- Moodle Security FAQ -- Answers to common security questions including hacked site recovery and XSS handling
- OWASP ModSecurity Core Rule Set -- The official CRS project site with installation guides and documentation
- OWASP Top 10 (2025) -- The authoritative reference for the ten most critical web application security risks
