Program enrolment
enrol_muprog
A minimal enrolment plugin for Moodle that provides program-based enrolments managed entirely by the companion `tool_muprog` plugin. The plugin prevents all manual enrolment management (adding, deleting, hiding instances, unenrolling users) and delegates control to the program management system. It auto-enables itself on installation and implements a null privacy provider since it stores no personal data beyond what core enrolment tracking handles.
This is a very clean, minimal enrolment plugin with no security vulnerabilities. The plugin contains only four PHP files, does not define any custom database tables, exposes no web-accessible pages, handles no user input, and performs no file or HTTP operations.
Security posture:
- All database access uses
$DB->get_record()with parameterized queries - Output is properly sanitized with
format_string() - No forms, no state-changing endpoints, no user-facing pages — so CSRF, auth, and capability checks are not applicable
- No file operations, no HTTP requests, no code execution
Code quality:
- The only finding is a missing
defined('MOODLE_INTERNAL') || die();guard indb/install.php, which is a low-severity coding standard issue with no security impact (the file only defines a function) - The privacy provider correctly implements
null_providersince the plugin stores no personal data - No third-party libraries are bundled
- All Moodle APIs used are current and non-deprecated in Moodle 5.1
The single low finding does not warrant downgrading below A.
Plugin Overview
enrol_muprog is a program enrolment plugin that serves as the enrolment mechanism for the MuTMS (Multi-Tenant Management Suite) program management system (tool_muprog). It is designed to be entirely programmatically managed — all instance creation, deletion, and user enrolment is controlled by the parent tool_muprog plugin.
Architecture
The plugin consists of four PHP files:
lib.php— Definesenrol_muprog_pluginextendingenrol_plugin, which overrides methods to prevent manual management (can_add_instance(),can_delete_instance(),can_hide_show_instance(),allow_unenrol()all returnfalse). Theget_instance_name()method fetches the associated program name fromtool_muprog_programtable for display purposes.db/install.php— Auto-enables the enrol plugin during installation by adding'muprog'to$CFG->enrol_plugins_enabled.classes/privacy/provider.php— Implementsnull_provider(no personal data stored).lang/en/enrol_muprog.php— English language strings.
Security Assessment
The plugin has an excellent security posture due to its minimal attack surface:
- No web-accessible pages or endpoints
- No user input processing
- No custom database tables
- No file operations or HTTP requests
- Properly uses Moodle's
$DBAPI andformat_string()for output
Key Finding
The only issue identified is a missing defined('MOODLE_INTERNAL') || die(); guard in db/install.php, which is a coding standard violation with no practical security impact.
Findings
The db/install.php file is missing the standard defined('MOODLE_INTERNAL') || die(); guard that Moodle coding standards require for internal PHP files.
Core enrol plugins such as enrol_manual and enrol_meta include this check in their db/install.php files. While the file only defines a function (so direct web access would not execute any code), the check is a defense-in-depth convention expected by the Moodle plugin review process.
No risk. This is a coding convention issue, not a security vulnerability. The file only defines a function, so direct access via a web browser would define the function but never call it, producing a blank page. No data is exposed and no state is changed.
In Moodle, db/install.php files are included by the plugin installer during the upgrade/installation process. The MOODLE_INTERNAL constant is set early in config.php and serves as a guard to prevent direct web access to internal files. Since this file only defines the function xmldb_enrol_muprog_install() without calling it, direct access would not execute any logic — the guard is purely a coding standard requirement.
/**
* Enable muprog enrolments.
*/
function xmldb_enrol_muprog_install() {
Add the defined('MOODLE_INTERNAL') || die(); guard after the license header and before the function definition:
defined('MOODLE_INTERNAL') || die();
/**
* Enable muprog enrolments.
*/
function xmldb_enrol_muprog_install() {
The plugin is part of the MuTMS (Multi-Tenant Management Suite) ecosystem and depends on tool_muprog for its core functionality. The get_instance_name() method gracefully handles the case where tool_muprog is not installed by checking class_exists(\tool_muprog\local\program::class) before attempting to use it.
The db/install.php auto-enables the plugin by directly modifying $CFG->enrol_plugins_enabled. This is a common pattern for third-party enrolment plugins. Moodle core's uninstall_cleanup() method in core\plugininfo\enrol automatically removes the plugin from this config value during uninstallation, so no db/uninstall.php is needed for this purpose.
The plugin declares support for Moodle 5.0 through 5.2 via $plugin->supported = [500, 502] in version.php. All Moodle APIs used by the plugin ($DB->get_record(), format_string(), set_config(), core_plugin_manager::reset_caches()) are current and non-deprecated in these versions.