Q1: How do you prevent SQL Injection in Moodle?
Never use variables directly in SQL strings. Always use the placeholders (? or named parameters) provided by the DML API ($DB).
// BAD
$DB->get_record_sql("SELECT * FROM {user} WHERE id = $id");
// GOOD
$DB->get_record_sql("SELECT * FROM {user} WHERE id = ?", [$id]);
Q2: Explain the difference between `required_param` and `optional_param`.
These functions are used to retrieve data from $_GET or $_POST safely.
required_param($name, $type): Stops execution with an error if the parameter is missing. Use this for critical data (e.g., course ID).optional_param($name, $default, $type): Returns a default value if the parameter is missing.
Both require a PARAM_* constant (e.g., PARAM_INT, PARAM_TEXT) to sanitize the input immediately.
Q3: How do you check for permissions in a plugin?
Use the Capabilities API. First, define the context, then check the capability.
$context = context_course::instance($courseid);
// Throws an exception if user doesn't have permission (stops execution)
require_capability('mod/myplugin:view', $context);
// Returns boolean (good for conditional logic)
if (has_capability('mod/myplugin:edit', $context)) {
// Show edit button
}
Q4: What is 'sesskey' and why is it important?
A sesskey (Session Key) is a token used to prevent Cross-Site Request Forgery (CSRF). It is generated for each user session. Any script that performs an action (POST request) must check require_sesskey() to ensure the request originated from the user and not a malicious site.
Q5: How do you prevent Cross-Site Scripting (XSS)?
Moodle provides output cleaning functions. Always use s() for plain text attributes and format_string() or format_text() for content. When outputting HTML, use $OUTPUT renderers or Mustache templates which auto-escape variables by default.
Q6: What is 'PARAM_CLEANHTML'?
It is a parameter type used with optional_param or required_param. It uses HTML Purifier to remove malicious scripts (like <script> tags) while preserving safe HTML formatting. Use it for rich text editor content.
Q7: What is 'require_login()'?
It ensures that a user is logged in before accessing a page. If not, it redirects them to the login page. It also sets up the global $USER object. It should be called at the top of almost every script.
Q8: How do you securely handle file downloads?
Do not link directly to files in moodledata. Use pluginfile.php. In your plugin's lib.php, implement the _pluginfile() callback function to check permissions (e.g., has_capability) before serving the file content.
Q9: What is 'is_siteadmin()'?
A function that checks if the current user is a site administrator. Admins have all capabilities by default. Use this check sparingly; prefer capability checks (has_capability) to allow for role delegation.
Q10: What is 'PARAM_INT'?
A parameter type that casts the input to an integer. It is crucial for IDs. If the input is not an integer, it strips non-numeric characters or returns 0, preventing SQL injection via ID fields.
Q11: How do you secure a cron task?
Cron tasks run in the background, often as the admin user or without a specific user. Ensure your task logic does not rely on $USER or $PAGE context unless explicitly set. Use cron_setup_user() if you need to impersonate a user securely.
Q12: What is 'ignore_missing' in capability checks?
When defining capabilities in access.php, you can set archetypes. If you check a capability that doesn't exist, Moodle might throw an error. has_capability handles this gracefully, but require_capability is strict.
Q13: What is 'MOODLE_INTERNAL'?
A constant defined in the main Moodle entry points. Most include files check defined('MOODLE_INTERNAL') || die(); to prevent direct access to library files via the browser, which could expose paths or errors.
Q14: How do you sanitize a URL?
Use clean_param($url, PARAM_URL) or new moodle_url($url). This ensures the URL is valid and prevents javascript: protocol injection attacks.
Q15: What is 'PARAM_TEXT'?
A parameter type that strips all HTML tags. It is useful for plain text inputs like names or titles where no formatting is allowed.
Q16: How do you prevent 'Privilege Escalation'?
Always check capabilities in the correct context. Do not check CONTEXT_SYSTEM if the action is only for a specific course. Ensure that form submissions (POST) re-verify permissions, not just the page load (GET).
Q17: What is 'https_required()'?
A function (or $CFG->wwwroot setting) that ensures the site is accessed via HTTPS. Moodle now strongly recommends or enforces HTTPS to protect session cookies and data in transit.
Q18: How do you handle passwords?
Never store passwords in plain text. Moodle uses password_hash() (bcrypt) to hash passwords. Use hash_internal_user_password() to generate hashes and validate_internal_user_password() to check them.
Q19: What is 'security_key' in external services?
When using Web Services, a token is generated for the external app. This token acts as the password. It must be kept secret and can be restricted by IP address or expiration date.
Q20: What is 'riskbitmask'?
In access.php, capabilities have a riskbitmask (e.g., RISK_XSS, RISK_CONFIG). This warns admins that assigning this capability might allow the user to perform dangerous actions (like inserting XSS or changing site config).
Q21: How do you prevent 'Session Fixation'?
Moodle automatically regenerates the session ID upon login (session_regenerate_id). This prevents an attacker from tricking a user into using a known session ID.
Q22: What is 'login_https'?
An older setting to use HTTPS only for the login page. Modern practice is to use HTTPS for the entire site (Always-On SSL) to protect the session cookie at all times.
Q23: How do you validate a file upload type?
In the form definition, use the accepted_types option for the filemanager element (e.g., ['.pdf', '.docx']). Moodle validates the extension and MIME type.
Q24: What is 'user_not_fully_set_up()'?
A check to see if the user has completed their profile (e.g., agreed to site policy). Moodle restricts access until these steps are completed.
Q25: How do you prevent 'Brute Force' attacks?
Moodle has a built-in account lockout mechanism. If a user fails login multiple times (configurable threshold), their account is temporarily locked.
Q26: What is 'PARAM_NOTAGS'?
Similar to PARAM_TEXT, it strips HTML tags. It is strictly for data that should not contain any markup.
Q27: How do you secure a Web Service API?
Ensure the service function checks capabilities (validate_context). Do not rely solely on the token. The token authenticates the user, but the code must authorize the action.
Q28: What is 'clean_text()'?
A legacy function, now largely replaced by format_text(). It was used to clean dangerous HTML. format_text() does this automatically if the format requires it.
Q29: How do you handle 'Guest' access securely?
Guest access allows unauthenticated users to view content. Ensure your plugin checks isguestuser() if you need to restrict features (like posting to a forum) that guests should not do.
Q30: What is 'config_plugins' table?
It stores plugin configuration. While not a security feature per se, sensitive data (like API keys) stored here should be handled carefully. Moodle does not encrypt these values by default.