ModSecurity is an open-source web application firewall (WAF) module that provides security controls to protect web applications from various attacks. It can be configured and customized using a variety of directives in its configuration files.
Enable ModSecurity globally
When you enable ModSecurity globally, it means that the ModSecurity rules and settings will be applied to all websites, applications, or virtual hosts running on the server. This ensures a consistent level of security across the entire server, helping to protect against common web vulnerabilities such as SQL injection, cross-site scripting (XSS), and more.
Enabling ModSecurity globally typically involves configuring the ModSecurity module at the server level to apply security rules and settings across all virtual hosts or websites. Here are general steps for enabling ModSecurity globally on an Apache web server:
Install ModSecurity
Ensure that the ModSecurity module is installed on your server. You can install it using a package manager or compile it from the source.
- For Debian/Ubuntu Linux systems, use the following command to install ModSecurity
sudo apt-get install libapache2-mod-security2
- For CentOS/RHEL Linux systems, use the following command to install ModSecurity
sudo yum install mod_security
Enable ModSecurity Module
In your Apache configuration, load the ModSecurity module. This is usually done by adding the following line to your main Apache configuration file or an included configuration file:
LoadModule security2_module modules/mod_security2.so
Include ModSecurity Configuration
Include the ModSecurity configuration file in your main Apache configuration. This can be done using the Include
directive. For example:
Include "/etc/httpd/conf.d/modsecurity.conf"
Configure ModSecurity
Create or modify the ModSecurity configuration file (modsecurity.conf
). This file typically contains global settings, such as rule sets, exclusions, and other configurations.
# Example modsecurity.conf
<IfModule mod_security2.c>
SecRuleEngine On
# Other ModSecurity configurations...
</IfModule>
Enable ModSecurity for a Specific Virtual host
This involves configuring the ModSecurity module specifically for that virtual host within your web server settings.
First, you need to ensure that ModSecurity is installed on your server. You can install it using a package manager or compile it from the source.
If you’re using Apache configuration, load the ModSecurity module. This is usually done by adding the following line to your main Apache configuration file or an included configuration file:
LoadModule security2_module modules/mod_security2.so
Include ModSecurity Configuration
Include the ModSecurity configuration file in your virtual host configuration. This can be done using the Include
directive. For example:
Include "/etc/httpd/conf.d/modsecurity.conf"
Configure ModSecurity for the Virtual Host
Inside your virtual host configuration, use the SecRuleEngine
directive to enable or disable ModSecurity for that specific virtual host. Set it to On
enable:
<VirtualHost *:80>
ServerName yourdomain.com
DocumentRoot /path/to/your/document/root
# Enable ModSecurity for this virtual host
SecRuleEngine On
# Other virtual host configuration...
</VirtualHost>
Configure Nginx with ModSecurity
In your Nginx configuration, include the ModSecurity configuration and load the module. For example:
include modsecurity.conf;
modsecurity on;
Configure ModSecurity for the Virtual Host
Inside your virtual host configuration, use the modsecurity_rules_file
directive to specify the rules file for that virtual host:
server {
listen 80;
server_name yourdomain.com;
# ModSecurity configuration
modsecurity_rules_file /etc/nginx/conf.d/yourdomain-modsecurity.conf;
# Other virtual host configuration...
}
After making changes, restart Nginx to apply the new configuration:
sudo systemctl restart nginx
Basic ModSecurity Configuration
ModSecurity has a default configuration file that you can modify. For Apache, the configuration file is typically located at /etc/modsecurity/modsecurity.conf
. You can use a text editor to modify this file:
sudo nano /etc/modsecurity/modsecurity.conf
The above command will display the following:
# Example modsecurity.conf
<IfModule mod_security2.c>
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess On
SecResponseBodyMimeType text/plain text/html text/xml
SecRule ARGS|REQUEST_HEADERS|REQUEST_BODY "drop" \
"phase:1,rev:'2.2.9',ver:'OWASP_CRS/2.2.9',maturity:'9',accuracy:'8',t:none,block,msg:'Request Indicates a Security Scanner',id:'960015'"
# Other basic rules and configurations...
</IfModule>
Advanced ModSecurity Configuration
An advanced ModSecurity configuration involves fine-tuning the rules, incorporating additional security measures, and customizing settings to meet the specific needs of your web applications. Below are some advanced configurations and best practices for ModSecurity:
Block SQL injection attacks
You can use the SecRule
directive to define custom rules. For example, to block requests with specific SQL injection patterns:
SecRule ARGS "@rx (?i)(alter|select|insert|update|delete|drop)" "id:2,deny,status:403,msg:'SQL Injection'"
This ModSecurity rule (SecRule) is designed to detect potential SQL injection attempts in the request parameters (ARGS). The rule uses the regular expression “@rx (?i)(alter|select|insert|update|delete|drop)” to match case-insensitive occurrences of common SQL keywords (alter, select, insert, update, delete, drop) within the request parameters. If a match is found, the rule takes action by denying the request (deny), setting the HTTP status code to 403 (status:403), and logging a message indicating a potential SQL injection attempt (msg:’SQL Injection’). This rule helps protect web applications by blocking requests that contain suspicious SQL statements, mitigating the risk of SQL injection attacks.
Cross-Site Scripting (XSS) Protection:
To prevent Cross-Site Scripting attacks, include the following rule:
SecRule REQUEST_HEADERS:User-Agent "libwww-perl" "id:3,deny,status:403,msg:'Blocked - Libwww-perl User-Agent'"
This ModSecurity rule (SecRule) is designed to identify and block requests where the User-Agent header contains the string “libwww-perl,” which is often associated with automated scripts or bots. The rule is triggered when the User-Agent header matches the specified condition.
Upon detection, the rule takes action by denying the request (deny), setting the HTTP status code to 403 (status:403), and logging a message indicating that the request was blocked due to the presence of the “libwww-perl” User-Agent (msg:’Blocked – Libwww-perl User-Agent’). This helps protect web applications from potential scraping or automated attacks associated with the libwww-perl User-Agent, enhancing security by preventing requests from this specific client identifier.
File Inclusion Protection
This rule protects against path traversal attacks:
SecRule ARGS "@rx \.\./" "id:4,deny,status:403,msg:'Blocked - Path Traversal'"
This ModSecurity rule (SecRule) is designed to detect and prevent path traversal attacks in the request parameters (ARGS). It uses the regular expression “@rx ../” to look for occurrences of the sequence “../” within the request parameters, which is indicative of attempts to navigate up the directory structure and potentially access sensitive files or directories.
When a match is found, the rule takes action by denying the request (deny), setting the HTTP status code to 403 (status:403), and logging a message indicating that the request has been blocked due to a potential path traversal attempt (msg:’Blocked – Path Traversal’). This rule serves as a protective measure against malicious attempts to exploit directory traversal vulnerabilities, enhancing the security of web applications.
Common Web Application Attacks
This ModSecurity rule (SecRule) aims to restrict the allowed HTTP methods for incoming requests, denying any requests with methods other than GET, POST, or HEAD. The rule utilizes the regular expression “!^(GET|POST|HEAD)$” to negate the specified HTTP methods, effectively capturing requests with methods not explicitly listed.
SecRule REQUEST_METHOD "!^(GET|POST|HEAD)$" "id:5,deny,status:405,msg:'Method Not Allowed'"
Upon detection of such unauthorized methods, the rule takes action by denying the request (deny), setting the HTTP status code to 405 Method Not Allowed (status:405), and logging a message indicating the denial due to an unsupported HTTP method (msg:’Method Not Allowed’). By enforcing a strict policy on allowed HTTP methods, this rule helps mitigate potential security risks associated with non-standard or unauthorized request methods, contributing to improved web application security.
Block requests from a specific IP address
This ModSecurity rule (SecRule) is designed to block requests originating from a specific IP address, 192.168.1.100, identified by the REMOTE_ADDR variable
SecRule REMOTE_ADDR "@ipMatch 192.168.1.100" "id:6,deny,status:403,msg:'Blocked - IP Blacklist'"
The rule utilizes the operator “@ipMatch” to compare the source IP address of incoming requests with the specified IP address. When a match is found, indicating that the request originates from the blacklisted IP address, the rule takes action by denying the request (deny), setting the HTTP status code to 403 (status:403), and logging a message indicating the block due to an IP blacklist entry (msg:’Blocked – IP Blacklist’). This rule provides a mechanism to restrict access from a particular IP address, potentially used for blocking malicious or unwanted traffic, enhancing the security of the web application by preventing access from the specified blacklisted IP.
Rate Limiting
Limit the number of requests from a specific IP address within a given time frame:
SecRule IP:REQUESTS "@gt 30" "id:7,phase:1,deny,status:429,msg:'Rate Limit Exceeded'"
This ModSecurity rule (SecRule) is designed to enforce rate limiting on incoming requests based on the IP address. The rule utilizes the IP collection variable “IP:REQUESTS” to track the number of requests from a specific IP address, and the operator “@gt 30” checks if the count is greater than 30. If the condition is met, indicating that the specified IP address has exceeded the defined threshold of 30 requests, the rule takes action by denying the request in the first phase of processing (phase:1), setting the HTTP status code to 429 Too Many Requests (status:429), and logging a message indicating the rate limit exceeded (msg:’Rate Limit Exceeded’).
This rule helps protect against abuse or potential DDoS attacks by limiting the number of requests from a single IP address within a specified timeframe, enhancing the security and availability of the web application.
Block requests from a specific User-Agent
SecRule REQUEST_HEADERS:User-Agent "malicious-bot" "id:8,deny,status:403,msg:'Blocked - Malicious User-Agent'"
Deny requests with a User-Agent header containing “malicious-bot”.
File Upload Restrictions
Restrict file uploads to certain file types:
SecRule FILES_TMPNAMES "@rx \.php$" "id:9,deny,status:403,msg:'Blocked - PHP File Upload'"
Deny file uploads with a file name ending in “.php”.
Customizing Error Pages
Customize the error page shown when a rule is triggered:
SecRule REQUEST_URI "@contains /restricted/" "id:10,deny,status:403,msg:'Blocked - Restricted Path'"
SecDefaultAction "phase:2,log,auditlog,status:403,pass"
Deny requests to the “/restricted/” path and customize the default actions.
Blocking Based on Request Size
Limit the size of incoming requests to prevent potential denial-of-service attacks:
SecRule REQUEST_BODY_SIZE "@gt 100000" "id:11,deny,status:413,msg:'Request Entity Too Large'"
This rule denies requests with a body size greater than 100,000 bytes, returning a 413 status code.
Blocking Based on Response Status Code
Block requests if the server responds with a specific status code:
SecRule RESPONSE_STATUS "^5\d\d$" "id:12,deny,status:503,msg:'Server Error'"
This rule denies requests when the server responds with a 5xx status code.
Session Fixation Protection
Protect against session fixation attacks by monitoring session-related parameters:
SecRule REQUEST_COOKIES:/^PHPSESSID/ "id:13,deny,status:403,msg:'Blocked - Session Fixation'"
This rule denies requests with a PHP session ID cookie in the request.
Blocking Based on Referrer Header
Block requests if the referrer is a known malicious site:
SecRule REQUEST_HEADERS:Referer "@contains evil.com" "id:14,deny,status:403,msg:'Blocked - Malicious Referrer'"
Deny requests when the referrer header contains “evil.com”.
Custom Response Page
Customize the response page for denied requests
SecRule REQUEST_URI "@contains /blocked/" "id:15,deny,status:403,msg:'Blocked - Custom Response'"
ErrorDocument 403 /custom-error-page.html
Deny requests to “/blocked/” and display a custom error page.
Blocking Based on Country
Block requests originating from a specific country using GeoIP:
SecRule GEO:COUNTRY_CODE "@streq CN" "id:16,deny,status:403,msg:'Blocked - China'"
This rule denies requests from China based on the country code.
Enable/Disable Rules
You can enable or disable specific ModSecurity rules by modifying the configuration files or using commands. To disable a rule, you can use:
sudo nano /etc/modsecurity/whitelist.conf
Add a rule ID preceded by SecRuleRemoveById
to disable a rule:
SecRuleRemoveById 123456
Rule Exclusions
You may need to exclude specific rules for certain paths or parameters. This can be achieved using location-based directives. For example:
<Location "/path/to/exclude">
SecRuleEngine Off
</Location>
This disables ModSecurity for the specified location.
Audit Log Configuration
ModSecurity can log events to help you analyze and troubleshoot. To configure the audit log, edit the configuration file:
sudo nano /etc/modsecurity/modsecurity.conf
Configure the audit log settings:
SecAuditEngine On
SecAuditLog /var/log/modsecurity/audit.log
Ensure the log directory exists and has the right permissions:
sudo mkdir -p /var/log/modsecurity/
sudo chown www-data: /var/log/modsecurity/
Restart Apache after making changes.