# Fix Apache mod_security False Positive Blocking Legitimate POST Requests
Your users report that submitting forms on your website suddenly fails with a 403 Forbidden error. The Apache error log shows:
[Thu Apr 08 14:22:07.654321 2026] [:error] [pid 4567] [client 203.0.113.55:45678] [client 203.0.113.55] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against `TX:ANOMALY_SCORE'" [file "/etc/modsecurity/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf"] [line "456"] [id "941100"] [msg "XSS Filter - Category 1: Script Tag Vector"] [data "Matched Data: <script found within ARGS_POST:content: <script>alert('xss')</script>"] [severity "CRITICAL"] [tag "application-multi"] [hostname "example.com"] [uri "/api/posts/create"] [unique_id "Zabc123def456"]ModSecurity (mod_security) has flagged a legitimate request as malicious and blocked it with a 403. This is a false positive, and it is one of the most common issues with WAF deployments.
Understanding the Error
The error message contains critical information:
- Rule ID: [id "941100"] -- the specific ModSecurity rule that triggered
- Phase: phase 2 -- the rule fired during request body inspection
- Data: Matched Data: <script found within ARGS_POST:content -- the POST parameter content that matched
- File: The rule file where the rule is defined
Step 1: Identify the Triggering Rule
Search for the rule definition:
grep -r "941100" /etc/modsecurity/rules/This shows the rule logic so you can understand what it is detecting and why it may be a false positive.
Step 2: Check the Audit Log
ModSecurity maintains detailed audit logs:
tail -100 /var/log/modsec_audit.logEach entry contains the full request, response, and all rules that evaluated. This is more useful than the Apache error log for understanding why a rule triggered.
Step 3: Create a Rule Exception
There are three approaches to handling false positives, from least to most specific:
Approach 1: Disable the Rule for a Specific URL
<Location "/api/posts/create">
SecRuleRemoveById 941100
</Location>This disables rule 941100 only for the /api/posts/create endpoint. Other endpoints are still protected.
Approach 2: Disable the Rule for a Specific Parameter
SecRule REQUEST_FILENAME "@streq /api/posts/create" \
"id:10001,\
phase:2,\
pass,\
nolog,\
ctl:ruleRemoveTargetById=941100;ARGS_POST:content"This disables rule 941100 only for the content POST parameter on the /api/posts/create endpoint. The rule still fires for other parameters on the same endpoint.
Approach 3: Adjust the Anomaly Score Threshold
If many rules are generating false positives, the anomaly score threshold may be too low:
# In /etc/modsecurity/modsecurity.conf
SecAction \
"id:900110,\
phase:1,\
pass,\
t:none,\
nolog,\
setvar:'tx.inbound_anomaly_score_threshold=10'"The default threshold is 5. Increasing it to 10 means more individual rule matches are required before a request is blocked. This is a blunt instrument -- prefer targeted rule exceptions.
Step 4: Test in Detection Mode
Before deploying rule changes, run mod_security in detection-only mode:
SecRuleEngine DetectionOnlyIn this mode, ModSecurity logs all matches but does not block any requests. Review the logs for a week to identify false positives, then switch back to SecRuleEngine On with your exceptions in place.
Common False Positive Scenarios
HTML Content in Form Fields
Rule 941100 (XSS detection) triggers when users submit HTML content in text areas. Common for blog posts, CMS content, and rich text editors.
SQL Keywords in Search Queries
Rule 942100 (SQL injection detection) triggers on search queries containing SQL-like syntax:
SELECT * FROM users WHERE name = 'John'Base64 Encoded Data
Rule 941170 (XSS via base64) triggers on base64-encoded API payloads, which are common in mobile app APIs.
File Uploads with Binary Content
Binary file uploads can trigger various rules because the raw bytes happen to match SQL or XSS patterns. Exclude the upload endpoint:
<Location "/api/uploads">
SecRuleRemoveById 941100 942100 942200
SecRequestBodyAccess Off
</SecRuleEngine>The SecRequestBodyAccess Off disables request body inspection entirely for uploads, which is appropriate since binary data cannot contain SQL injection or XSS attacks.