Drupal is a robust and secure CMS, but like any web application, it is susceptible to security vulnerabilities. Below are some common Drupal security vulnerabilities and best practices to mitigate them.
1. SQL Injection
Issue:
- Attackers can manipulate database queries via unsanitized input fields, leading to data leaks or database corruption.
Mitigation:
✅ Use Drupal’s Database API (db_query, db_select, etc.)
Drupal provides parameterized queries to prevent SQL injection.
❌ Bad (Vulnerable Code)
✅ Secure (Using Drupal Database API)
2. Cross-Site Scripting (XSS)
Issue:
- Attackers inject malicious JavaScript code into input fields, affecting users who view the page.
- Can lead to cookie theft, session hijacking, and defacing of content.
Mitigation:
✅ Use Twig auto-escaping in templates
✅ Sanitize output using Drupal’s Xss::filter()
and Html::escape()
functions
✅ Validate and restrict HTML inputs
❌ Bad (Vulnerable Code)
✅ Secure
In Twig templates, auto-escaping is enabled by default:
3. Cross-Site Request Forgery (CSRF)
Issue:
- Attackers trick authenticated users into submitting malicious requests without their knowledge.
Mitigation:
✅ Use Drupal’s built-in CSRF tokens (Form API
and Url::fromRoute()
with CSRF protection).
✅ Verify tokens before executing critical actions.
❌ Bad (Vulnerable Code)
- If a user visits a malicious site while logged in, the site could trigger this action.
✅ Secure (Using Drupal CSRF Token)
- This ensures only authenticated users with a valid session can perform the action.
4. Remote Code Execution (RCE)
Issue:
- Attackers exploit poorly validated file uploads or unserialized data to execute malicious PHP code.
Mitigation:
✅ Disable PHP execution in public file directories (sites/default/files
).
✅ Use file_validate_extensions()
to restrict uploaded file types.
✅ Avoid using eval()
, system()
, or exec()
.
✅ Secure File Upload in a Form
✅ Secure File Access
5. Access Control Issues
Issue:
- Improper role or permission management can allow unauthorized users to view, edit, or delete sensitive data.
Mitigation:
✅ Define permissions in my_module.permissions.yml
✅ Use user_access()
to check permissions before executing actions.
✅ Secure Access Check
6. Security Misconfigurations
Issue:
- Leaving development configurations enabled on a live site can expose debugging information, logs, and database errors.
Mitigation:
✅ Disable error reporting in production (settings.php
)
✅ Use .htaccess
to restrict access to sensitive directories (sites/default/files/private
).
✅ Always apply security updates (drush updb
and composer update
).
✅ Secure settings.php
✅ Restrict Access to Sensitive Files
7. Insecure Third-Party Modules
Issue:
- Using unverified or outdated contributed modules can introduce security vulnerabilities.
Mitigation:
✅ Only install trusted modules from Drupal.org
✅ Enable security updates (drush pm:security
)
✅ Review module permissions and configurations
✅ Check for security updates
8. Session Hijacking
Issue:
- If session cookies are exposed, attackers can impersonate users.
Mitigation:
✅ Use HTTPS ($settings['https'] = TRUE;
)
✅ Regenerate session IDs after login (session_regenerate_id(TRUE)
)
✅ Set SameSite
cookies to prevent CSRF attacks (cookie_samesite: 'Strict'
)
✅ Secure Session Configuration
Final Takeaways
Vulnerability | Mitigation |
---|---|
SQL Injection | Use Drupal’s Database API (->condition() ) |
XSS | Escape output (Html::escape() ), use Twig auto-escaping |
CSRF | Use form tokens and Url::fromRoute() |
RCE | Restrict file uploads (file_validate_extensions() ) and disable PHP execution in /files/ |
Access Control | Use user_access() and properly configure permissions |
Security Misconfigurations | Disable error reporting and secure settings.php |
Third-Party Modules | Install only trusted modules and run drush pm:security |
Session Hijacking | Use HTTPS and secure cookies |
Cross-Site Request Forgery (CSRF) & Cross-Site Scripting (XSS) in PHP Applications
Both CSRF and XSS are common web security vulnerabilities, but they work differently and require different mitigation strategies.
1. Cross-Site Request Forgery (CSRF)
How CSRF Works
A CSRF attack tricks an authenticated user into making unintended requests to a web application on which they are logged in. This can lead to unauthorized actions, such as changing account settings, transferring funds, or deleting content.
CSRF Attack Example
- A user logs into a banking website and stays logged in (
session
is active). The attacker sends a malicious email or embeds a hidden request in a page:
- When the user loads the email or visits the attacker’s page, their browser automatically sends the request with session cookies, transferring money to the attacker.
Mitigation Strategies
✅ Use CSRF Tokens: Generate and verify tokens for critical actions.
✅ Use SameSite
Cookies: Prevent cookies from being sent with cross-site requests.
✅ Verify Referrer Headers: Ensure requests originate from the same domain.
✅ Require Re-authentication: For sensitive actions like changing passwords or transferring money.
CSRF Prevention in PHP
✅ Step 1: Generate a CSRF Token
✅ Step 2: Include CSRF Token in Forms
✅ Step 3: Validate CSRF Token in PHP
✅ Step 4: Use SameSite
Cookies in php.ini
2. Cross-Site Scripting (XSS)
How XSS Works
XSS allows attackers to inject malicious JavaScript into web pages, which can steal cookies, hijack sessions, or deface websites.
Types of XSS Attacks
Type | Description | Example |
---|---|---|
Stored XSS | Malicious script is saved in the database and executed for all users. | A comment section where users inject <script>alert("Hacked!");</script> . |
Reflected XSS | Malicious script is injected into URLs and executed when a user clicks the link. | https://example.com/search?q=<script>alert('Hacked!')</script> |
DOM-based XSS | Malicious JavaScript is executed by modifying the page’s DOM without server interaction. | document.write(location.search) used insecurely. |
Mitigation Strategies
✅ Escape User Input: Prevent scripts from executing by encoding special characters.
✅ Use Html::escape()
(Drupal) or htmlspecialchars()
(PHP): Convert <script>
to <script>
.
✅ Enable HTTP Content Security Policy (CSP): Restrict the execution of scripts to trusted sources.
✅ Use X-XSS-Protection
Header: Modern browsers block reflected XSS.
✅ Validate and Sanitize Inputs: Remove unexpected input before saving to the database.
XSS Prevention in PHP
❌ Bad (Vulnerable Code)
✅ Secure Code
✅ Secure Form Processing
✅ Secure Output in JavaScript Context
✅ Use a Content Security Policy (CSP) In .htaccess
or nginx.conf
:
Key Differences Between CSRF and XSS
Feature | CSRF | XSS |
---|---|---|
Attack Type | Forces user to perform unintended actions | Injects malicious scripts into a web page |
Goal | Abuse authenticated session | Steal cookies, execute unauthorized JS |
Common Exploit | Hidden form submissions, AJAX requests | Injecting <script> tags into inputs |
Mitigation | CSRF tokens, SameSite cookies, referrer checks | Escaping output, CSP, input validation |
Final Thoughts
- CSRF attacks trick authenticated users into performing unintended actions.
- Use CSRF tokens,
SameSite
cookies, and re-authentication for critical actions.
- Use CSRF tokens,
- XSS attacks inject malicious scripts to steal data or deface websites.
- Escape all user input before outputting to the page (
htmlspecialchars()
,Html::escape()
).
- Escape all user input before outputting to the page (
- Both vulnerabilities can be prevented with proper security measures such as CSP headers, input validation, and proper authentication mechanisms.