Note: This bug was identified and fixed by Claude Code (Opus 4.5) during a debugging session.
Bug Report: ModSecurity Parser Fails to Match Apache Error Logs
Summary
The crowdsecurity/modsecurity parser (v1.3) fails to parse valid Apache ModSecurity log entries due to a space handling bug in the grok patterns APACHEERRORPREFIX2 and MODSECPREFIX2.
Environment
- CrowdSec version: 1.6.x
- Parser version: crowdsecurity/modsecurity v1.3
- OS: Debian 13 (Trixie)
- Apache version: 2.4.x with mod_security2
- ModSecurity CRS: 3.3.7
Symptoms
- ModSecurity logs are read from
/var/log/apache2/error.log but never parsed
cscli explain --type modsecurity shows parser failure
cscli metrics show parsers shows 0 hits for crowdsecurity/modsecurity
- Attackers triggering ModSecurity rules are never banned
Root Cause Analysis
The bug is in the space handling between two patterns:
Pattern 1: APACHEERRORPREFIX2
\\[%{APACHEERRORTIME:timestamp}\\] \\[%{NOTSPACE:apacheseverity}\\] (\\[pid %{INT}(:tid %{INT})?\\] )?\\[(client|remote) %{IPORHOST:sourcehost}(:%{INT:source_port})?\\] (\\[client %{IPORHOST}\\])?
Note the ending: \\] (\\[client %{IPORHOST}\\])?
There is a space before the optional [client IP] group.
Pattern 2: MODSECPREFIX2
%{APACHEERRORPREFIX2} ModSecurity: ...
Note: There is a space after %{APACHEERRORPREFIX2}.
The Problem
For a log line like:
[Mon Dec 15 05:34:22 2025] [security2:error] [pid 123:tid 456] [client 192.168.1.1:12345] ModSecurity: Warning...
APACHEERRORPREFIX2 matches up to [client 192.168.1.1:12345]
- After the closing
], there's a space in the log
- The pattern
] (\\[client ...) consumes that space while trying to match the optional group
- The optional group
(\\[client %{IPORHOST}\\])? fails (next chars are ModSecurity, not [client)
- Since it's optional, the group is skipped, but the space was already consumed
MODSECPREFIX2 then expects another space before ModSecurity:
- But the space was already consumed, so the match fails
Fix
Move the space inside the optional group, so it's only consumed when the group actually matches:
Before (broken)
APACHEERRORPREFIX2: "...\\] (\\[client %{IPORHOST}\\])?"
MODSECPREFIX2: "%{APACHEERRORPREFIX2} ModSecurity: ..."
After (fixed)
APACHEERRORPREFIX2: "...\\] (\\[client %{IPORHOST}\\] )?"
MODSECPREFIX2: "%{APACHEERRORPREFIX2}ModSecurity: ..."
Changes:
- Add space inside optional group:
(\\[client %{IPORHOST}\\])? → (\\[client %{IPORHOST}\\] )?
- Remove space after prefix:
%{APACHEERRORPREFIX2} ModSecurity: → %{APACHEERRORPREFIX2}ModSecurity:
Verification
Before fix
$ echo '[Mon Dec 15 05:34:22 2025] [security2:error] [pid 123:tid 456] [client 192.168.1.1:12345] ModSecurity: Warning. test. [file "/test.conf"] [line "1"] [id "123"] [msg "test"] [severity "CRITICAL"] [hostname "test"] [uri "/"] [unique_id "abc"]' | cscli explain --type modsecurity -f -
├ s01-parse
| └ 🔴 crowdsecurity/modsecurity
└-------- parser failure 🔴
After fix
$ echo '[Mon Dec 15 05:34:22 2025] [security2:error] [pid 123:tid 456] [client 192.168.1.1:12345] ModSecurity: Warning. test. [file "/test.conf"] [line "1"] [id "123"] [msg "test"] [severity "CRITICAL"] [hostname "test"] [uri "/"] [unique_id "abc"]' | cscli explain --type modsecurity -f -
├ s01-parse
| └ 🟢 crowdsecurity/modsecurity (+36 ~2)
├-------- parser success 🟢
├ Scenarios
└ 🟢 crowdsecurity/modsecurity
Patch
Apply this patch to /etc/crowdsec/parsers/s01-parse/modsecurity.yaml:
# Fix 1: Move space inside optional [client IP] group
sed -i 's/(\\[client %{IPORHOST}\\])?/(\\[client %{IPORHOST}\\] )?/g' /etc/crowdsec/parsers/s01-parse/modsecurity.yaml
# Fix 2: Remove extra space between APACHEERRORPREFIX2 and ModSecurity
sed -i 's/%{APACHEERRORPREFIX2} ModSecurity:/%{APACHEERRORPREFIX2}ModSecurity:/g' /etc/crowdsec/parsers/s01-parse/modsecurity.yaml
# Reload CrowdSec
systemctl reload crowdsec
Additional Notes
Apache ErrorLogFormat
For CrowdSec compatibility, Apache's error log format should not include microseconds. The default Debian 13 format includes microseconds which the %{TIME} grok pattern cannot parse.
Recommended Apache configuration (/etc/apache2/conf-available/error-log-format.conf):
# CrowdSec compatibility: no microseconds
ErrorLogFormat "[%{%a %b %d %H:%M:%S %Y}t] [%-m:%l] [pid %P:tid %T] [client %{c}a] %M"
Enable with:
a2enconf error-log-format
systemctl reload apache2
Affected Versions
- crowdsecurity/modsecurity v1.3 (current as of December 2025)
References
Note: This bug was identified and fixed by Claude Code (Opus 4.5) during a debugging session.
Bug Report: ModSecurity Parser Fails to Match Apache Error Logs
Summary
The
crowdsecurity/modsecurityparser (v1.3) fails to parse valid Apache ModSecurity log entries due to a space handling bug in the grok patternsAPACHEERRORPREFIX2andMODSECPREFIX2.Environment
Symptoms
/var/log/apache2/error.logbut never parsedcscli explain --type modsecurityshows parser failurecscli metrics show parsersshows 0 hits forcrowdsecurity/modsecurityRoot Cause Analysis
The bug is in the space handling between two patterns:
Pattern 1:
APACHEERRORPREFIX2Note the ending:
\\] (\\[client %{IPORHOST}\\])?There is a space before the optional
[client IP]group.Pattern 2:
MODSECPREFIX2Note: There is a space after
%{APACHEERRORPREFIX2}.The Problem
For a log line like:
APACHEERRORPREFIX2matches up to[client 192.168.1.1:12345]], there's a space in the log] (\\[client ...)consumes that space while trying to match the optional group(\\[client %{IPORHOST}\\])?fails (next chars areModSecurity, not[client)MODSECPREFIX2then expects another space beforeModSecurity:Fix
Move the space inside the optional group, so it's only consumed when the group actually matches:
Before (broken)
After (fixed)
Changes:
(\\[client %{IPORHOST}\\])?→(\\[client %{IPORHOST}\\] )?%{APACHEERRORPREFIX2} ModSecurity:→%{APACHEERRORPREFIX2}ModSecurity:Verification
Before fix
After fix
Patch
Apply this patch to
/etc/crowdsec/parsers/s01-parse/modsecurity.yaml:Additional Notes
Apache ErrorLogFormat
For CrowdSec compatibility, Apache's error log format should not include microseconds. The default Debian 13 format includes microseconds which the
%{TIME}grok pattern cannot parse.Recommended Apache configuration (
/etc/apache2/conf-available/error-log-format.conf):Enable with:
Affected Versions
References