Why Moodle security hardening starts before the first course is built
Hardening a self-hosted Moodle site means controlling four things: what the web server exposes to the internet, who can administer the site, what code runs on it, and how quickly security releases are applied. Those four decisions shape almost every control that follows, so they belong in the plan before the first course is built, not after the site has gone live. A Moodle site typically holds learner records, grades, completion history and sometimes personal data such as dates of birth, contact details, or accommodation notes. Many of these sites are launched under a deadline for an academic term or a training program, and security settings are the first thing to slip when the schedule tightens. Moodle is harder to harden than it looks because its attack surface spreads across many components. The core ships with a large set of authentication, enrolment, and web service options, and Moodle documents more than 50 plugin types, including activity modules, blocks, themes, authentication, enrolment, local code, reports and admin tools. Each installed plugin adds code, and each is maintained by a different author on a different schedule. The administrator role also reaches almost everything: site configuration, plugin installation, user impersonation and, depending on how the site is set up, the ability to change how the web server and PHP behave. File uploads and the moodledata directory add a further path, because content authors and students can place files that the platform later serves or processes. Moodle's core is licensed under GPL-3.0, which means the software is free to use and modify, but the license does not transfer responsibility for how it is configured. Whoever operates the site owns the web server configuration, the PHP settings, the database access controls, the backup design, and the timing of updates. Moodle HQ and the plugin authors publish releases and documentation, but applying them correctly on your infrastructure is the operator's job. Ask your team to name the person accountable for each of those areas before any build work starts. Teams usually need this work at one of three points. The first is before go-live, when the site is new and the configuration is still easy to change. The second is after taking over an inherited site, where the previous team's plugins, admin accounts and server settings are unknown and need to be inventoried. The third is before a compliance assessment, when an external auditor will ask for evidence that controls exist and operate as described. DeployOpen plans and configures the hardening, and prepares the configuration records and evidence an assessor would examine. Independent auditors or certification bodies issue any assessment outcome, and DeployOpen does not issue audit reports, attestations or certifications. A practical first step is to write down the current state before changing anything: the Moodle version and its support status, the PHP and database versions, the web server document root, the list of installed plugins with their sources, the named administrator accounts, and the authentication methods enabled. That inventory turns a general concern into a list of specific checks, and it gives you a baseline against which later changes can be measured.
Which Moodle components and settings a hardening review covers
A Moodle hardening review looks at the places where a misconfiguration exposes code, data or accounts. The components below are linked: the web server decides what is publicly reachable, PHP and the database decide what an attacker can execute and read, and accounts, authentication and plugins decide who gets in and what they can change.
Web server document root and /public
Check that the web server document root points to the directory Moodle expects, not the main Moodle folder. From Moodle 5.1, the document root must point to the new /public directory, otherwise the site may show directory listings or errors. Confirm that code, configuration and other non-public files are not reachable through a URL, and test this from outside the network.
PHP runtime and settings
Confirm the PHP version is one the Moodle release supports, using the 64-bit build the release notes require. Review the php.ini settings that control file uploads, execution limits, dangerous functions, error display and session cookies. Errors shown to users reveal paths and code details, so display settings should be reviewed in production.
Database account and privileges
The Moodle database account should own only the Moodle database and hold the privileges the installer and upgrades need, without server-wide administrative rights. Check that the account is not shared with other applications, that the password is stored outside the web root, and that remote access is limited to the application servers. Confirm the database engine and version against the release requirements.
Moodledata directory outside the web root
The moodledata directory stores uploaded files, caches and session data, and it should never be reachable through a browser. Confirm it sits outside the web root with restricted file permissions for the web server user only. Check how it is backed up and encrypted at rest, since it holds course content and learner submissions.
Administrator and manager accounts
Review who holds site administrator and manager roles, and remove accounts that no longer need them. Confirm that administrator accounts are separate from day-to-day teaching accounts and that multi-factor authentication is enforced for them. Check that the default admin account and any shared or service logins have strong, unique credentials and a documented owner.
Authentication plugins
Moodle core ships several authentication methods: manual accounts, email self-registration, external database, LDAP, LTI, OAuth 2, Shibboleth and web services. Each enabled method is an entry point, so disable those the site does not use and review the settings of those it does. Self-registration needs email domain restrictions and confirmation, and external database or LDAP connections need least-privilege bind accounts and encrypted transport.
Enrolment and role configuration
Review which enrolment methods are active and who can change enrolments, roles and capabilities at category and course level. Custom roles often grant more than their name suggests, so check each capability against the job it supports. Confirm that web service tokens, cohort sync and self-enrolment keys are limited to the users and courses they need.
Installed plugins and themes
List every installed plugin and theme, including those that are disabled but still present on disk. Check each one for a release that matches the current Moodle version, an active maintainer and a known vulnerability history before keeping it. Remove unused components, since each one adds code that must be patched with the core.
Which hardening choices fit your site and what each one costs to run
This table compares five hardening decisions a Moodle team must make, with the situations where each option fits and the ongoing work it creates. Read each row against your current Moodle version, identity setup and integration list, then use the cost column to scope administrator and support time.
| Decision | Option and when it fits | Operational cost to run |
|---|---|---|
| Web document root | Serve from the /public directory on a supported Moodle version. This fits any site that can move to Moodle 5.1 or later, and it is the layout the 5.1 release notes require for those versions. | Web server configuration must be updated and tested during each upgrade. Sites that stay on a legacy layout need an extra review each time the web server or PHP changes. |
| Account creation | Disable email self-registration and provision accounts through an identity provider or a controlled import. This fits sites where staff and students already exist in a directory or student information system. | Requires an integration or import job, attribute mapping and a deprovisioning process. Without it, administrators handle account requests and removals by hand. |
| Admin sign-in and MFA | Rely on the identity provider for administrator sign-in and multi-factor checks, so Moodle accepts only federated sessions for admins. This fits organizations that already enforce MFA centrally. | Needs an SSO connection that is tested for admin accounts and a documented break-glass path. Confirm the protocol supported by your Moodle version before design. |
| Admin sign-in and MFA (Moodle-side) | Add a second factor inside Moodle through a plugin. This fits sites with local admin accounts and no central identity provider, or where policy requires a factor Moodle itself checks. | Each plugin must be vetted, tested on each Moodle upgrade and supported by its maintainer. Confirm its features and version compatibility against your Moodle release before choosing it. |
| Web services | Enable web services only for named integrations, each with a dedicated service, a restricted user and a limited function list. This fits sites with known integrations such as grade export or enrolment sync. | Each integration needs a token process, a review when functions change and monitoring. Keeping services closed by default means extra work when a new integration is requested. |
| Plugin sourcing | Use plugins from the Moodle plugins directory with maintainers and version listings where possible. Custom or vendor code fits when no listed plugin meets a requirement. | Directory plugins still need compatibility checks before each upgrade. Custom or vendor code adds code review, security testing and long-term maintenance owned by your team or a contractor. |
How to sequence a Moodle security hardening build
This sequence takes a Moodle site from a confirmed version and server layout to a verified hardened build. Each step closes with a check you can run in your own environment, so no control counts as done until its test passes.
Confirm versions and build the server layout
Confirm the Moodle version you will run, then read its release notes for the required 64-bit PHP version, supported database versions and upgrade prerequisites. For Moodle 5.1, the notes list PHP 8.2 or later and PostgreSQL 15, MySQL 8.4, MariaDB 10.11 or SQL Server 2017 or later. Build the server with the web server document root pointing to the /public directory and keep moodledata outside the web root. The platform owner should sign off the versions before installation. Done when a request to the site returns the login page only and a direct request for a moodledata path is refused.
Set PHP, database privileges and file permissions
Apply the PHP settings your security baseline calls for, including disabling functions the site does not use and setting error display for production. Create a dedicated database account with only the privileges Moodle needs for normal operation, and confirm with the platform owner whether upgrades will use a separate, more privileged account. Set code directories to be readable but not writable by the web server user, and allow write access only to moodledata and any path the platform owner approves. Done when a test write outside the approved paths fails and the site still loads.
Lock down admin accounts and enforce MFA
Limit the site administrator role to a small named group, remove default or shared accounts, and review every account that holds a manager or administrator role. Choose the route that enforces MFA, such as the identity provider behind SAML 2.0 single sign-on, OAuth 2 or LDAP, and confirm that the chosen plugin supports the second factor your policy requires. Confirm whether local password login remains available for administrators and, if it does, that it is protected by the same factor. Done when a test administrator cannot sign in without the second factor and the administrator list matches the approved names.
Define roles and capabilities with least privilege
Review Moodle's built-in roles and the capabilities each one grants, then remove any capability that the job function does not need. Create custom roles only where a documented duty requires them, and assign roles at the lowest level that works, such as category or course, keeping site-level assignments to the approved administrators. Record each role with its purpose, its capabilities and its owner. Done when a test account for each role can complete its own tasks, and the capability review shows no access that the design document does not list.
Vet and install only needed plugins
Build an inventory of every plugin, theme and authentication module, recording its source, version, license and maintainer. Install only the plugins that a documented requirement needs, and check that each one supports the Moodle version you run and is still maintained. Test each install in a non-production copy first, then review the code or the vendor's security notes for anything that handles authentication, file storage or web services. Done when the inventory matches the installed plugin list and the plugin overview shows no unexpected entries.
Configure upload and file handling controls
Set the allowed file types and maximum upload size to match your content policy, and restrict uploads for roles that do not need them. Confirm that web server and PHP upload limits agree with the Moodle settings, so that a limit in one place does not quietly override another. Review how files are served and which plugins store user files. If policy requires malware scanning of uploads, configure it with a scanner your security team has approved. Done when test uploads of a blocked file type and an oversized file are both refused and the refusals appear in the logs.
Disable unused authentication and web services
Turn off authentication methods the deployment does not use, such as email self-registration, manual accounts for staff, or any plugin the design document does not list. Disable web services unless a specific integration is documented. Where an integration needs one, create a dedicated service account, limit it to the functions the integration uses, and set token expiry according to your policy. Confirm that the enabled authentication list and the web services settings match the design document. Done when a login attempt through a disabled method is refused and no unused service endpoint responds.
Run the verification pass
Run a verification pass against the signed-off design, covering configuration, permissions, roles, plugins, uploads and authentication. Combine an automated scan of the platform with a manual review of the administration settings and a short test script that proves each control from the earlier steps behaves as designed. Record every result, fix each finding, and retest the changed items. Agree the assessment scope and the evidence format with your independent assessor before the pass begins. Done when every checklist item has a recorded result and each open finding has an owner.
Which Moodle versions still receive security fixes and how that shapes the plan
The first decision in any Moodle hardening plan is which release line the site will sit on, because a hardened configuration on an unsupported version loses its protection over time. Moodle ships major releases every six months, in April and October, and minor point releases every two months in February, April, June, August, October and December. Security fixes arrive through those point releases, so the site only stays protected if it stays on a version that still receives them.
Moodle 4.5 is a long-term support release with security support until 4 October 2027. Moodle 5.1 has general support until 5 October 2026 and security support until 19 April 2027, which means that after general support ends, only security fixes arrive until April 2027. Moodle 5.2 has security support until 4 October 2027. Moodle 5.3 is the next LTS release, with general support until 4 October 2027 and security support until 1 October 2029. Confirm these dates against the Moodle releases page before you write them into a policy or a contract, since support windows are the figures most likely to change.
Choosing between an LTS line and a six-monthly line is a security and operations decision, not only a feature decision. An LTS line gives the administrator fewer major upgrades and a longer security window, but it may lag behind features the faculty want. A six-monthly line brings new capability sooner, but it asks the platform team to complete a major upgrade roughly twice a year and to keep plugins compatible each time. Write down which line you chose, who approves the move to the next line, and how long you will run a version after its security support ends.
A patch plan must account for runtime requirements that change per release. Moodle 5.1 requires 64-bit PHP 8.2 or later, and Moodle 5.3 requires 64-bit PHP 8.3 or later. Database minimums also differ, with PostgreSQL, MySQL, MariaDB and SQL Server versions set for each release. Before scheduling a security update, check that the PHP runtime and database on the server meet the target release, because a point release that needs a newer PHP cannot be applied on the existing stack. Ask your hosting or platform team to record the PHP and database versions alongside the Moodle version in your change records.
Two related checks belong in the same plan. Upgrades to 5.1 require the site to be on Moodle 4.2.3 or later, and upgrades to 5.3 require Moodle 4.4 or later, so an older site may need an intermediate step. In addition, from Moodle 5.1 the web server document root must point to the /public directory. A patch window that skips this change can leave the site showing directory listings or errors. Confirm the upgrade path, the PHP and database requirements and the document root change with your administrator before you set the date for each security update.
How hardening changes for single-server, load-balanced and air-gapped Moodle
On one server, the web server, PHP and database usually share a host, so hardening centers on one web server configuration and one set of file permissions. The document root is the most important single setting. From Moodle 5.1, the web server document root must point to the new /public directory inside the Moodle code folder. Otherwise the site may show directory listings or errors. TLS usually terminates on the same web server, so certificate handling, protocol settings and HTTP to HTTPS redirects are maintained locally.
Key points for this model:
- TLS termination: terminate HTTPS on the web server, disable outdated protocol versions, and redirect all plain HTTP requests to HTTPS.
- Document root: set it to the /public directory on Moodle 5.1 and later, and confirm that the code folder above it is not served directly.
- moodledata: keep it outside the web root, owned by the PHP service account, with no read access for other local users and no URL path that reaches it.
- Sessions and caches: where sessions or caches use local disk, restrict permissions to the PHP service account and confirm the path sits outside the web root.
- Security releases: apply point releases to a staging copy first, then to production in a planned window, with a tested backup of code and database taken beforehand.
Verify the setup by requesting the code, configuration and moodledata paths from outside the server and confirming that each request is refused rather than returning content.
Behind a load balancer, TLS termination becomes a design decision with security consequences. If the balancer terminates TLS, traffic between it and the nodes must be encrypted or confined to a private network. If each node terminates TLS, certificates and cipher settings must match on every node. The document root and PHP configuration must also be identical across nodes, because a node that drifts can serve a different code version or configuration. Shared storage for moodledata and shared session or cache services need the same protection. This tab covers controls only. The high availability architecture is covered in its own topic.
Key points for this model:
- TLS termination: choose one termination model and document it. If the balancer terminates, protect the back-end hop and confirm the forwarded scheme so Moodle generates correct HTTPS links.
- Document root: apply the same /public document root on every node through configuration management, and check it after each build so no node keeps an older path.
- moodledata: place shared storage on a private network, restrict mounts to the PHP service account, and enable encryption at rest where the storage platform supports it.
- Sessions and caches: host session and cache services on private back-end addresses, enable authentication on them, and block any route from public networks.
- Security releases: rehearse each patch on a staging cluster, roll production nodes one at a time, and record the Moodle version on each node until all match.
Verify the setup by comparing PHP configuration, document root and Moodle version across every node, and by confirming that session and cache services refuse connections from outside the private network.
Without internet access, the site cannot fetch plugins, language packs, dependencies or security releases directly. Every artifact must enter through a controlled transfer process. Hardening shifts toward verifying what comes in: each package is checked, recorded and stored in an internal repository before it reaches production. Certificates often come from an internal certificate authority, and time sources, logging and update services need internal endpoints. Confirm with the vendor documentation for your Moodle version how update and plugin installation behave when outbound access is blocked.
Key points for this model:
- TLS termination: use certificates from an internal certificate authority, distribute its root certificate to clients, and place termination points to match the network zones.
- Document root: keep the /public document root on Moodle 5.1 and later, and record the web server path in the change record so each deployment can be checked against it.
- moodledata and sessions: keep moodledata on encrypted, access-controlled storage inside the enclave, and store backups in a separate zone with its own access controls.
- Security releases: download official packages on a transfer workstation, verify them against the publisher's published checksums, scan them, and move them through an approved transfer with a recorded sign-off.
- Plugins and dependencies: mirror required PHP packages, Composer dependencies and plugins into an internal repository, pin versions, and review each package's license and code before import.
Verify the procedure by rehearsing a full security release from transfer through to production, then confirming that the site runs with no outbound connection attempts in the firewall logs.
Controls that keep administrator, role and upload risk contained
Most Moodle compromises start with a privileged account, an over-permissive role or a file that the server should never have executed. The controls below limit what an attacker gets from each of those entry points, and each one needs an owner and a periodic check after go-live.
Administrator account count and naming
Every site administrator can change plugins, roles, authentication and server-facing settings, so the number of people holding that role is a direct measure of exposure. Keep the list short, name each account to a specific person, and record who approved it. Review the list on a fixed schedule and after staff changes, and confirm which accounts can reach the server through the site administration pages.
Separate administrator and daily accounts
Administrators who browse courses, grade work or answer forum posts with the same login they use for site changes expose their privileged session to phishing and to malicious course content. Give each administrator a second account for administration with no teaching role, and use it only for administrative tasks. Confirm the naming convention and where logs record which account made each change.
MFA at the identity provider or in Moodle
Multi-factor authentication stops password reuse and stolen credentials from becoming a login. Where Moodle sits behind an identity provider, enforce MFA there for every account, including administrators, and confirm that local fallback logins are restricted. Where MFA is needed inside Moodle, confirm the method and plugin supported by the exact version in use before planning, since support changes between releases.
Roles and capabilities reviewed for least privilege
Moodle roles are bundles of capabilities, and custom roles plus course-level overrides often grant more than the original design intended. Export the role definitions, compare them with the stated job functions, and list every course where a teacher role was given extra capabilities. Remove capabilities that no job needs, and retest the review after each new plugin, because plugins can add capabilities.
File upload types, size limits and delivery
Uploads from teachers and students are one of the most common routes for hostile content, so the allowed file types, maximum sizes and the way files are served all need deliberate settings. Restrict types to those the courses need, set size limits that match real use, and confirm that uploaded files are served as downloads rather than executed by the web server. Test the configuration with a file type that should be blocked.
Secrets stored outside the web root
Database credentials, mail passwords and API tokens in a configuration file inside the web-accessible tree can be read if the web server is misconfigured or a file is exposed. Store these values outside the document root, limit file permissions to the service account, and rotate them after staff departures or suspected exposure. Confirm how each integration in your build reads its credentials and where backups of the configuration are kept.
Plugin vetting before installation
Each plugin adds code, capabilities and sometimes new upload paths, so it is part of the attack surface. Before installing, check the source and publisher, the maintenance status, the license, the version compatibility with your Moodle release and the code for risky functions. Record the approval, and remove plugins that are unmaintained or no longer needed.
What drives the effort and cost of Moodle hardening, and how to reduce each driver
This table lists the factors that change how much work Moodle hardening takes, how each one raises effort, and what keeps it under control. Read it with your own environment in mind, then use the one-time and recurring split to shape the written scope and quote. The main takeaway is that a fixed, written baseline matters more than the size of the site.
| Driver | How it raises effort or cost | What keeps it down |
|---|---|---|
| Number of installed and planned plugins | Each plugin needs vetting for source, maintenance status, known vulnerabilities and compatibility with the target Moodle release. Plugins that add file upload, external calls or new capabilities need deeper review. | Agree a plugin allow list in writing before the baseline build. Remove unused plugins first and defer planned ones to a separate, later review. |
| Integrations that need web services or external authentication | Web service tokens, service accounts, OAuth 2 or SAML settings and LDAP bindings each need scoped permissions, secure transport and tested failure behavior. Every integration adds an attack surface to review. | Limit the number of integrations in phase one. Use a shared pattern for service accounts and token scope, and document each integration's allowed functions and owners. |
| Number of environments that must match (development, staging, production) | Hardening settings, web server rules, PHP configuration and plugin versions must be applied and verified in each environment. Drift between them creates untested gaps and repeated work. | Keep one configuration baseline as code or a documented template, applied to every environment. Verify production against staging with the same checks. |
| Custom plugins or themes needing review | Custom code is not covered by upstream security releases. Each one needs code review for input handling, capability checks, file handling and output escaping, plus retesting after each Moodle upgrade. | Reduce custom code to what the course design requires. Review each component against a fixed checklist and record the review result with its version. |
| State of the existing site (greenfield versus inherited with unknown changes) | An inherited site may have undocumented core edits, unknown administrators, old plugins, changed file permissions and an unclear web server layout. Discovery and cleanup take time before any hardening starts. | Ask for a written discovery step with a findings report before the hardening scope is fixed. Compare the live site against a clean install of the same release to find unexpected changes. |
| Compliance evidence requirements | Assessors often ask for configuration records, change history, access reviews and patch records. Producing and organizing this evidence adds effort, and the requirements vary by framework and by the auditor. DeployOpen prepares controls and evidence but does not issue audit reports or certifications. | Confirm the framework and the evidence list with your assessor before the scope is set. Agree in writing which evidence items are produced by the hardening work and which are the client's responsibility. |
| Number of administrators and custom roles | Each administrator account and each custom role needs MFA, least-privilege capability review and an owner. More roles mean more capability combinations to test, and more access reviews to repeat over time. | Keep the number of site administrators small and named. Use a short, documented set of custom roles. Schedule periodic role reviews with a named reviewer. |
How to test that Moodle hardening works and fails safely
A hardened Moodle site is only as good as the checks that prove each control is still in place after the next change. Run the verification pass below against staging first, record what you find, and repeat it after every upgrade, plugin change or configuration edit. The point is to show that controls hold under direct attack and that the site degrades to a safe state when something upstream breaks. Start at the edge. Confirm that the web server serves only the public directory, and that the Moodle code tree and moodledata are not reachable by direct URL. On 5.1 and later, the document root should point to /public. Request a handful of known paths directly, including files under the code tree, config-like files, and the moodledata location, and confirm each returns a refusal or a not-found response rather than a listing or file contents. Compare the web server configuration with your written baseline, not with memory.
Next, check PHP settings and file permissions against the same baseline. Read the effective values from the running PHP process, not only from the configuration file you edited, because pools and per-site overrides can differ. Confirm that the code tree is not writable by the web user where your baseline says it should be read-only, and that moodledata is writable only by the account that needs it. Record the exact directives and modes you checked so that a later reviewer can repeat the test without guessing.
Then test authentication. Sign in as an administrator and confirm that the second factor is required. Then run the failure case: fail or cancel the MFA step and confirm that access to administration pages is refused, not just hidden in the menu. Repeat with a non-administrator account that holds elevated roles. For roles, export the current role and capability assignments and compare them with your least privilege matrix. Look for users with site-level roles they do not need, and for roles that grant capabilities outside the matrix. Confirm which accounts are the emergency administrators and that they are documented.
Test the intake paths. Attempt uploads with disallowed file types and with files over the configured size limit, from a course, a profile and any plugin that accepts files. Confirm the rejection message appears and that nothing is stored in moodledata. Disable an authentication method in a test account and confirm sign-in through it fails. Send requests to web services that are switched off or restricted, and confirm they are rejected. Finally, compare the installed plugin inventory with your allow list and flag anything present but not approved.
Now test the failure modes, because hardening that only works when everything is healthy is not hardening. Make the identity provider unreachable in staging and confirm that the documented administrator recovery path still works, and that ordinary users are refused rather than given a fallback they should not have. Remove a non-core plugin in staging and confirm the site starts, the plugin's data is handled as your runbook says, and no page fails open. Finally, apply a security release to staging first, run this entire pass again on that copy, and only then schedule production. Ask your partner or internal team to write each expected result before the test runs, so a pass means something.
What to monitor, patch, back up and document after go-live
Hardening a Moodle site is not finished at go-live. The controls set during the rollout degrade as releases ship, administrators change roles, plugins age and logs fill up unread. The cards below cover the recurring work that keeps those controls true, and each one names the record or check that shows it is still in place.
Track security announcements and release dates
Subscribe to Moodle security announcements and plan around the minor release calendar, which falls in February, April, June, August, October and December. Assign one owner to read each advisory, decide whether it affects your version and plugins, and set a target window for applying the fix. Confirm the notification channels your team uses in your own environment.
Keep a dated patch record
Record each Moodle core and plugin update with its date, the version applied, the staging test result and the person who approved production deployment. Run every security release against a staging copy restored from a recent production backup before it reaches users. The record is the evidence auditors and internal reviewers will ask for first.
Review administrator and role assignments
Review who holds site administrator and sensitive role assignments on a fixed schedule, and remove access that no longer matches a current job. Check custom roles and capability overrides in the same review, since a role changed for one course can widen access elsewhere. Record each review with the reviewer, the date and the changes made, and confirm the review interval your policy requires.
Monitor logs and failed sign-ins
Watch web server and PHP error logs, along with Moodle's own logs for failed sign-in attempts and changes to administrator settings. Agree the alert thresholds and the people who respond before go-live, rather than setting them after the first incident. Confirm which log shipping and alerting tools your team operates, and how long logs are retained.
Maintain the plugin inventory
Keep a current list of every installed plugin, its source, its installed version, its maintainer and its compatibility with your Moodle version. Remove plugins that are unused, since each one adds code that must be patched. Check the inventory against the Moodle version in use before each minor release, because a plugin that is unsupported for the next release becomes a security gap.
Test backups with a restore
Back up the database and the moodledata directory together, on a schedule that matches how much course activity you can afford to lose. A backup that has never been restored is an assumption, so run a restore to a separate environment on a fixed schedule and time how long it takes. Record the result, and confirm the retention period and storage location your organization requires.
Maintain the hardening baseline document
Write one document that states the intended configuration: document root, PHP settings, authentication methods, MFA requirements, administrator accounts, role design and file upload limits. Update it whenever a change is approved, and note the date and reason for each change. Auditors and internal reviewers can then compare the live site against the stated baseline instead of reconstructing it from memory.
Moodle security hardening questions buyers ask before hiring help
What does Moodle security hardening cost and what drives the price?
Moodle hardening has no fixed public price. DeployOpen does not publish a price list, and a quote follows from a written scope. The cost is mostly skilled labor: assessing the current site, changing web server, PHP and database settings, configuring administrator accounts and MFA through your identity provider, reviewing roles and plugins, testing in a non-production copy, and writing runbooks. The main drivers are the number of plugins to vet, how many integrations need review (identity provider, LDAP, HR feeds), how many environments must be hardened (development, test, production), and how much compliance evidence you need. The hardening work itself is one-time. Security release testing and ongoing support recur and can be covered by a retainer. Ask each quote to list these items separately so you can compare them.
How long does Moodle security hardening take from kickoff to go-live?
Duration depends on the same drivers as cost, plus your change calendar and how quickly your team can respond. No duration is set here, because it varies with the size of the site and the availability of your people. In general terms, the work moves through phases: discovery, a staged build in a non-production copy, testing, then a change window for production. Delays usually come from slow access approvals, unclear plugin ownership, identity provider changes waiting on another team, and freeze periods such as exam seasons. A fixed-scope agreement sets the timeline in writing before work starts. Ask for the phase dates, the dependencies on your side, and the change windows you need to book.
What does our team need to provide for a hardening engagement?
Plan for a few named people from your side. The work needs administrator access to the Moodle site and its server, read access to logs, and a staging copy that matches production. Identity provider owners must confirm how accounts, MFA and attributes will be issued, and they need time for test logins. Provide the current Moodle version, PHP and database versions, a full list of installed plugins with their sources, and any custom code. Agree production change windows in advance, and name a decision-maker who can accept risk trade-offs. Share your current backup status and recent restore tests, because hardening changes must be reversible. Missing items usually appear as extra phases in the schedule.
Can an internal Moodle administrator harden the site without outside help?
Some of the work suits an experienced internal administrator, and some needs outside skills. Internal staff can usually handle role and capability reviews, removing unused plugins and accounts, enforcing strong passwords and MFA through the identity provider, and documenting decisions. Outside help is most useful at the server and PHP layer, for example placing the document root at the /public directory on Moodle 5.1 or later, reviewing PHP settings and file upload controls, vetting plugin code, and configuring SAML 2.0 or LDAP with correct attribute mapping. Independent testing is a separate activity and is often best run by people who did not make the configuration changes. Ask any partner to show which tasks they will do and which your team keeps.
Which compliance evidence does hardening produce for an external auditor?
Hardening produces controls and records that an assessor can review, such as configuration baselines, access reviews, change logs and test results. DeployOpen prepares systems, controls and evidence for compliance assessments. It does not issue audit reports, attestations or certifications, and independent auditors or certification bodies make any assessment outcome. Ask your auditor which evidence they expect for your framework before scoping, and map each hardening item to the control it supports. Some areas sit outside platform hardening, including staff training, incident response and vendor management, and these need their own evidence. Confirm framework names, versions and evidence expectations in writing with your assessor before work starts.
How does Moodle handle security releases after go-live?
Moodle publishes minor point releases every two months, in February, April, June, August, October and December, and major releases in April and October. Security fixes arrive through these releases, so plan a repeatable routine for each one. A typical path is to read the release notes, check plugin compatibility, apply the update to staging, run smoke tests and a backup restore, then schedule the production window. Agree in writing who approves changes, what target times apply to critical fixes, and what happens when a plugin lags behind core. Ongoing patching and testing can be covered by a DeployOpen retainer. Confirm release dates and upgrade paths on the Moodle releases page before you commit to a cadence.
Which Moodle versions get security support, and when does it end?
Moodle 4.5 is a long-term support release with security support until 4 October 2027. Moodle 5.1, released on 6 October 2025, has general support until 5 October 2026 and security support until 19 April 2027. Moodle 5.2, released on 20 April 2026, has security support until 4 October 2027. Moodle 5.3, released on 5 October 2026, is the next long-term support release, with general support until 4 October 2027 and security support until 1 October 2029. These dates come from the Moodle releases page. Choose a hardened baseline version that still has security support through your planned review period, and confirm the dates on the live releases page before you sign.
How DeployOpen scopes, hardens and hands over a Moodle site
DeployOpen plans, implements, hardens, documents and supports self-hosted open-source platforms inside your own infrastructure, including Moodle. For security hardening, we start from a written scope that covers the web server, PHP, accounts, plugins and patching, then deliver controls, configuration and documentation your team can run after handover.
How we scope
- Review the current Moodle version, PHP and database versions, and whether the document root already points to /public.
- Inventory administrator accounts, authentication methods, roles, installed plugins and file upload settings before changes.
- Agree in writing which hardening areas, environments and deliverables are included, using a fixed-scope agreement.
How we build
- Configure the web server and document root so only the intended public directory is served, with PHP settings reviewed against Moodle requirements.
- Restrict administrator access, enforce MFA where your identity setup supports it, and tighten roles and capabilities to least privilege.
- Vet plugins for source, maintenance status and compatibility, and set file upload controls and patching steps for security releases.
How we hand over
- Deliver a hardening runbook covering configuration baselines, account procedures, plugin review steps and change records.
- Test changes in a staging copy first, and document the results and any residual risks for your security and compliance reviewers.
- Walk your administrators through the security release process so they can apply patches and verify the outcome themselves.
How we support
- Ongoing support, upgrades and continuous testing are available as retainers after the fixed-scope work is complete.
- Retainers can cover applying Moodle security releases, rechecking configuration after upgrades and reviewing newly added plugins.
- Confirm with us during scoping which support level, response expectations and testing cadence fit your environment and governance needs.

