How to Create Custom ModSecurity Rules in Imunify360 for API Protection
Custom ModSecurity rules for Imunify360 let you block malicious JSON, restrict API methods, limit upload sizes, and fine‑tune protection for your API endpoints.
6 min read
Running a web application that exposes an API makes you a frequent target for automated attacks. Even with a firewall and a Web Application Firewall such as Imunify360, sophisticated exploits can slip through if the default rule set does not cover the specific payloads you see in your logs. Custom ModSecurity rules let you tailor protection to the exact API endpoints and request patterns that matter to your business.
Why Create Custom ModSecurity Rules for API Endpoints?
Imunify360 ships with the OWASP ModSecurity Core Rule Set (CRS). While CRS is great for generic web traffic, it is often too broad for API traffic. Typical API characteristics include:
Strict JSON or XML schemas.
Specific HTTP methods on defined paths.
Versioned URLs such as /api/v1/users that need separate handling.
When an attacker sends a malformed JSON body, a SQL injection string, or a path-traversal payload that matches an endpoint, the generic rules may miss it or, worse, generate false positives that block legitimate clients. Custom rules let you:
Detect and block known exploit patterns that target your API.
Enforce strict content-type and size limits.
Log detailed information for forensic analysis.
Preparing the Server for Custom Rules
Imunify360 stores custom ModSecurity rules in /etc/imunify360/custom-modsecurity.d/. Before editing, confirm the directory exists and that the Imunify360 service is running.
Debian / Ubuntu (apt)
# Verify Imunify360 is installed
dpkg -l | grep imunify360
# Ensure the custom rules directory exists
sudo mkdir -p /etc/imunify360/custom-modsecurity.d
# Restart Imunify360 to apply any changes later
sudo systemctl restart imunify360
The commands above confirm the package, create the directory with proper permissions, and restart the Imunify360 daemon so it will reload custom rules on the next reload.
AlmaLinux / Rocky Linux / RHEL (dnf)
# Verify Imunify360 installation
rpm -qa | grep imunify360
# Create the custom rules directory if missing
sudo mkdir -p /etc/imunify360/custom-modsecurity.d
# Restart the service
sudo systemctl restart imunify360
Both sets of commands perform the same actions: verify the product, ensure a place for custom rules, and restart the service to pick up new configuration.
Writing a Rule to Block Malicious JSON Payloads
Many API exploits start with a JSON body that contains SQL syntax, JavaScript, or shell commands. The following rule checks the request body for characters that are unlikely in legitimate JSON (e.g., unescaped single quotes, semicolons, or "--").
SecRule REQUEST_HEADERS:Content-Type "application/json" – applies only to requests that claim to send JSON.
phase:2 – runs after the request body has been parsed.
block – terminates the request with a 403 response.
@rx ('|\"|;|--|/\*|\*/|xp_cmdshell|union\s+select) – a regular expression that matches characters or strings commonly used in SQLi or command injection.
logdata records the exact snippet that triggered the rule, which is useful for debugging.
Restricting HTTP Methods on Sensitive Endpoints
Some APIs expose administrative functions under /api/v1/admin/*. If those endpoints should only accept POST and PUT, you can block everything else.
Rule file: 02_restrict_admin_methods.conf
# Allow only POST and PUT on admin routes
SecRule REQUEST_URI "^/api/v1/admin/" \
"id:100002, \
phase:1, \
chain, \
t:none, \
block, \
msg:'Disallowed HTTP method on admin API'"
SecRule REQUEST_METHOD "!@within POST PUT" \
"t:none"
Explanation:
The first SecRule matches any request whose URI starts with /api/v1/admin/.
It chains to a second rule that checks the HTTP method.
@within POST PUT passes only if the method is POST or PUT; otherwise the request is blocked.
Limiting Request Body Size for File-Upload Endpoints
Large payloads can be used for denial-of-service or to embed malicious files. Imunify360 already limits body size globally, but you may want a stricter limit for a specific endpoint, such as /api/v1/upload.
Rule file: 03_body_size_limit.conf
# Set a 2 MB limit on the upload endpoint
SecRule REQUEST_URI "^/api/v1/upload$" \
"id:100003, \
phase:2, \
block, \
t:none, \
msg:'Upload payload exceeds 2 MB limit', \
ctl:requestBodyProcessor=URLENCODED, \
ctl:requestBodyLimit=2097152"
Explanation:
ctl:requestBodyLimit=2097152 tells ModSecurity to reject bodies larger than 2 MB for this request.
The rule runs in phase:2 after the body is read, ensuring the limit is enforced before any application processing.
Deploying and Testing the Custom Rules
After creating the rule files, place them in the custom directory and reload Imunify360. Use curl or a REST client to verify that the rules behave as expected.
Debian / Ubuntu
# Copy rule files (example assumes you are in /tmp)
sudo cp /tmp/01_block_malicious_json.conf /etc/imunify360/custom-modsecurity.d/
sudo cp /tmp/02_restrict_admin_methods.conf /etc/imunify360/custom-modsecurity.d/
sudo cp /tmp/03_body_size_limit.conf /etc/imunify360/custom-modsecurity.d/
# Reload Imunify360 (no full restart needed)
sudo systemctl reload imunify360
JSON rule:curl -X POST -H "Content-Type: application/json" -d '{"user":"admin","pass":"\' OR 1=1 --"}' https://example.com/api/v1/login – should return 403.
Method restriction:curl -X GET https://example.com/api/v1/admin/users – should be blocked.
Body size limit: Use a tool to send a 3 MB file to /api/v1/upload – Imunify360 will reject it.
Check the Imunify360 audit log (/var/log/imunify360/audit.log) for entries containing the msg you defined. This confirms the rule fired and shows the captured data.
Maintaining and Updating Custom Rules
Custom rules are living assets. As your API evolves, you’ll need to adjust patterns, add new endpoints, or retire old ones. Follow these best practices:
Version control: Store each .conf file in a Git repository. Tag releases when you push a new set of rules.
Commenting: Include a header comment with the rule ID, purpose, creation date, and author. Example:
# Rule ID: 100001
# Purpose: Block SQL-like payloads in JSON bodies
# Created: 2024-10-04
# Author: AtoZNode Security Team
Testing pipeline: Use a staging server with identical Imunify360 configuration. Run automated curl tests before promoting changes to production.
Log review: Periodically scan the audit log for false positives. If a legitimate request is blocked, refine the regular expression or add an exception using SecRuleRemoveById in a separate "whitelist" file.
Conclusion
Imunify360 provides a solid baseline WAF, but API-driven applications often need more granular protection. By creating custom ModSecurity rules you can:
Detect and block malicious JSON payloads.
Enforce strict HTTP methods on sensitive routes.
Apply endpoint-specific size limits.
Maintain a clear, auditable rule set that grows with your API.
Implement the steps above on your Debian/Ubuntu or AlmaLinux-based server, test thoroughly, and integrate rule management into your deployment workflow. With tailored rules in place, your API will be better shielded against the targeted exploits that most generic WAF configurations miss.
custom modsecurity rulesimunify360api securitylinux server hardeningrequest body inspectionhttp method restrictionrequest size limitaudit log monitoring
Try it on your own server
Follow along on a Cloud VPS with full root access, or read the step-by-step knowledge base guides.