'Cannot resolve Request Header Issue in ModSecurity and its affects on WordPress
CURRENT: I have the familiar issue with an internal 403 coming up... however, after exploring for the issue through all error logs, I have found that the Forbidden error is emerging from a Modsecurity issue regarding Request Headers
and flagging up rulesets within, modsecurity_crs_21_protocal / OWASP_CRS.
ORIGINAL: I could not access my site at all. While I can now log in to my domain.co.uk, and navigate around - after modifying the wp-config.php
from many suggestions, replacing and modifying again my .htaccess
, as well as resolving a missing:
[http/2.0]
within, modsecurity_crs_10_config,
PROGRESS: The internal WordPress issue persists and shows itself when trying to configure/change the dynamics of the site, particularly, time and date settings, permalinks, editing pages by any means, and generally when I try to save any changes.
NOTES: VPS, CentOS, not - cPanel. Fresh install of WordPress, as my own is held on a shared drive.
All directories are set to [755] and files to [644].
I have also normalised the SQL database to be
UTF8mb4_unicode.ci
-- in the event this could help, it has sped things up but nothing else.
EXPLORING: When exploring modsecurity.d I have browsed far and wide and found a few mods for modsecurity_crs_10_config that was proposed to work, by excluding
- error log
[id='******']
,
along with coding in
[SecRule REQUEST_FILENAME "/wp-admin/load-scripts.php]
but nothing seems to be resolving the issue!!
====
`# (CRS new ruleset)
Rule to allow server-status requests with missing mandatory headers.
SecRule REMOTE_ADDR "@ipMatch ***.***.*.**"
"msg:'Matched 1***.***.*.** and matched server-status. Disabling rules *****1 and *****2',
phase:1,
id:1*****,
t:none,
pass,
log,
chain"
SecRule REQUEST_FILENAME "server-status$"
"t:none,
ctl:ruleRemoveById=*****1,
ctl:ruleRemoveById=*****2"
Rule to allow load-scripts.php requests without triggering rules.
SecRule REQUEST_FILENAME "/wp-admin/load-scripts.php$"
"msg:'Disabled rules *****1 and *****2 for load-scripts.php$',
phase:1,
nolog,
pass,
ctl:ruleRemoveById=*****1,
ctl:ruleRemoveById=*****2,
id:'2*****'"`
====
While remembering that there seem to be variations between server directory/file paths: Do the above look ok, or do I need to be doing something else? Am I in the right place (file) to be applying these rules?
Thanks in advance and I will try to answer any questions you have in as much detail as you need.
KR, John
Have tried: I have tried updating file permissions 755 & 644, config.php,.htaccess, normalised sql database, modsec engine is on, apache status - no issues, and modified rulesets to modsecurity_crs_10_config.
Expecting: Check if I have got the right coding/syntax in the right place/order and more importantly in the right file, or if I need to be doing something different.
===================== [[ UPDATE ]] =====================
This may seem a little long-winded, however... less id specific details, as per request, here are the results of updating:
CentOS: 7.9
Iworx: 7
Apache: 2.4.52
ModSecurity: 2.2.9
OWSAP: 3.3.2
PHP: 7.4
APR, PCRE, LIBXML: Installed
Error Logs (All commented out IP addresses don't belong to me either!).
==================== [[ START ERROR LOGS ]] ====================
Audit.log: Last three entries
--d0a9ea60-C--
action=health-check-site-status-result&_wpnonce=015c390f17&counts%5Bgood%5D=18&counts%5Brecommended%5D=1&counts%5Bcritical%5D=0
--d0a9ea60-F--
HTTP/1.1 403 Forbidden
Content-Length: 199
Connection: close
Content-Type: text/html; charset=iso-8859-1
Date: Mon, 28 Mar 2022 17:03:35 GMT
Server: Apache/2.4.52 (CentOS) OpenSSL/1.0.2k-fips mod_watch/4.3 mod_fastcgi/2.4.6
--d0a9ea60-H--
Message: Access denied with code 403 (phase 2). [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_41_sql_injection_attacks.conf"] [line "159"]
[id "981173"] [rev "2"] [msg "Restricted SQL Character Anomaly Detection Alert - Total # of special characters exceeded"]
[data "Matched Data: - found within ARGS:action: health-check-site-status-result"] [ver "OWASP_CRS/2.2.9"] [maturity "9"] [accuracy "8"] [tag "OWASP_CRS/WEB_ATTACK/SQL_INJECTION"]
Action: Intercepted (phase 2)
Apache-Handler: proxy:fcgi://names123-remi-php74-proxy
Stopwatch: 1648487015800212 8861 (- - -)
Stopwatch2: 1648487015800212 8861; combined=6733, p1=899, p2=5347, p3=0, p4=0, p5=348, sr=139, sw=139, l=0, gc=0
Producer: ModSecurity for Apache/2.9.3 (http://www.modsecurity.org/); OWASP_CRS/2.2.9; OWASP_CRS/3.3.2.
Server: Apache/2.4.52 (CentOS) OpenSSL/1.0.2k-fips
Engine-Mode: "ENABLED"
Modsecurity.d/activated_rules/ CRS_41 (159):
SecRule ARGS_NAMES|ARGS|XML:/* "([\~\!\@\#\$\%\^\&\*\(\)\-\+\=\{\}\[\]\|\:\;\"\'\´\’\‘\`\<\>].*?){4,}" "phase:2,t:none,t:urlDecodeUni,block,id:'981173',rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'9',accuracy:'8',msg:'Restricted SQL Character Anomaly Detection Alert - Total # of special characters exceeded',capture,logdata:'Matched Data: %{TX.1} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',tag:'OWASP_CRS/WEB_ATTACK/SQL_INJECTION',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.sql_injection_score=+1,setvar:'tx.msg=%{rule.msg}',setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/RESTRICTED_SQLI_CHARS-%{matched_var_name}=%{tx.0}"
NOTES: d0a9ea60-H
appears to be a result of d0a9ea60-C
which may explain why WordPress will intially complete a health check and comes back healthy - but will not conduct any other tests (Theme and Plugin, etc)?
Web Server Error Log: Last two entries
[Mon Mar 28 18:55:13 2022] [-:error] [pid 27563:tid 140237342709504] [client **.***.***.*:40074] [client **.***.***.*] ModSecurity: Warning. Operator GE matched 0 at
TX:outbound_anomaly_score. [file "/etc/httpd/modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf"] [line "102"] [id "980140"]
[msg "Outbound Anomaly Score Exceeded (score 0): individual paranoia level scores: , , , "]
[ver "OWASP_CRS/3.3.2"] [tag "Host: domain.na.me"] [tag "event-correlation"] [hostname "domain.na.me"] [uri "/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php"]
[unique_id "YkIEkcSvwnZVNnEcbqtwCgAAAHA"]
[Mon Mar 28 18:55:13 2022] [-:error] [pid 27563:tid 140237342709504] [client **.***.***.*:40074] [client **.***.***.*] ModSecurity: Warning. Operator GE matched 0 at
TX:inbound_anomaly_score. [file "/etc/httpd/modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf"] [line "91"] [id "980130"]
[msg "Inbound Anomaly Score Exceeded (Total Inbound Score: 0 - SQLI=0,XSS=0,RFI=,LFI=,RCE=,PHPI=,HTTP=,SESS=): individual paranoia level scores: , , , "]
[ver "OWASP_CRS/3.3.2"] [tag "Host: domain.na.me"] [tag "event-correlation"] [hostname "domain.na.me"] [uri "/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php"]
[unique_id "YkIEkcSvwnZVNnEcbqtwCgAAAHA"]
modsecurity-crs/rules/ RESPONSE_980_CORRELATION (91, 102):
82. SecRule TX:INBOUND_ANOMALY_SCORE "@ge %{tx.inbound_anomaly_score_threshold}" \
83. "id:980130,\
84. phase:5,\
85. pass,\
86. t:none,\
87. log,\
88. noauditlog,\
89. msg:'Inbound Anomaly Score Exceeded (Total Inbound Score: %{TX.INBOUND_ANOMALY_SCORE} - SQLI=%{tx.sql_injection_score},XSS=%{tx.xss_score},RFI=%{tx.rfi_score},LFI=%{tx.lfi_score},RCE=%{tx.rce_score},PHPI=%{tx.php_injection_score},HTTP=%{tx.http_violation_score},SESS=%{tx.session_fixation_score}): individual paranoia level scores: %{TX.ANOMALY_SCORE_PL1}, %{TX.ANOMALY_SCORE_PL2}, %{TX.ANOMALY_SCORE_PL3}, %{TX.ANOMALY_SCORE_PL4}',\
90. tag:'event-correlation',\
91.>> ver:'OWASP_CRS/3.3.2'"
93. SecRule TX:OUTBOUND_ANOMALY_SCORE "@ge %{tx.outbound_anomaly_score_threshold}" \
94. "id:980140,\
95. phase:5,\
96. pass,\
97. t:none,\
98. log,\
99. noauditlog,\
100. msg:'Outbound Anomaly Score Exceeded (score %{TX.OUTBOUND_ANOMALY_SCORE}): individual paranoia level scores: %{TX.OUTBOUND_ANOMALY_SCORE_PL1}, %{TX.OUTBOUND_ANOMALY_SCORE_PL2}, %{TX.OUTBOUND_ANOMALY_SCORE_PL3}, %{TX.OUTBOUND_ANOMALY_SCORE_PL4}',\
101. tag:'event-correlation',\
102.>> ver:'OWASP_CRS/3.3.2'"
NOTES: There could well be a version issue, or conflict, while I cannot see earlier installed versions of OWASP, it is becoming possible that the files are embedded elsewhere, or not named properly, in the system and are causing a conflict?
/etc/httpd/logs/error_log: Main block entry
[Mon Mar 28 17:39:02 2022] [suexec:notice] [pid 27330:tid 140238080026752] AH01232: suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
[Mon Mar 28 17:39:02 2022] [-:notice] [pid 27330:tid 140238080026752] ModSecurity for Apache/2.9.3 (http://www.modsecurity.org/) configured.
[Mon Mar 28 17:39:02.447352 2022] [:notice] [pid 27330:tid 140238080026752] ModSecurity: APR compiled version="1.5.2"; loaded version="1.5.2"
[Mon Mar 28 17:39:02.447358 2022] [:notice] [pid 27330:tid 140238080026752] ModSecurity: PCRE compiled version="8.32 "; loaded version="8.32 2012-11-30"
[Mon Mar 28 17:39:02.447363 2022] [:notice] [pid 27330:tid 140238080026752] ModSecurity: LIBXML compiled version="2.9.1"
[Mon Mar 28 17:39:02.447413 2022] [:notice] [pid 27330:tid 140238080026752] ModSecurity: StatusEngine call: "2.9.3,Apache/2.4.52 (CentOS) Op,1.5.2/1.5.2,8.32/8.32 2012-11-30,(null),2.9.1,d052a9a3f6f1e10728f8450a585dba54e25cb3b4"
[Mon Mar 28 17:39:04.510608 2022] [:notice] [pid 27330:tid 140238080026752] ModSecurity: StatusEngine call failed. Query: GIXDSLRTFRAXAYLDNBSS6MROGQXDKMRA.FBBWK3TUJ5JSSICPOAWDCLRVFYZC6MJO.GUXDELBYFYZTELZYFYZTEIBSGAYTELJR.GEWTGMBMFBXHK3DMFEWDELRZFYYSYZBQ.GUZGCOLBGNTDMZRRMUYTANZSHBTDQNBV.GBQTKOBVMRRGCNJUMUZDKY3CGNRDI.1648489142.status.modsecurity.org
[Mon Mar 28 17:39:04.552056 2022] [so:warn] [pid 27330:tid 140238080026752] AH01574: module security2_module is already loaded, skipping
[Mon Mar 28 17:39:04.552090 2022] [so:warn] [pid 27330:tid 140238080026752] AH01574: module unique_id_module is already loaded, skipping
[Mon Mar 28 17:39:04 2022] [lbmethod_heartbeat:notice] [pid 27330:tid 140238080026752] AH02282: No slotmem from mod_heartmonitor
[Mon Mar 28 17:39:04 2022] [-:notice] [pid 27368:tid 140238080026752] FastCGI: process manager initialized (pid 27368)
[Mon Mar 28 17:39:04 2022] [mpm_event:notice] [pid 27330:tid 140238080026752] AH00489: Apache/2.4.52 (CentOS) OpenSSL/1.0.2k-fips mod_watch/4.3 mod_fastcgi/2.4.6 configured -- resuming normal operations
==================== [[ END ERROR LOGS ]] ====================
A) Ensured everything was clear and updated
B) As you can see, I have installed the necessary modules/software, as both ModSecurity - and the new Modsecurity-CRS is being called on. [Mon Mar 28 17:39:04.510608 2022] StatusEngine failed
, was due to a syntax error, which I corrected.
C) I have taken out the earlier coding from modsecurity.d/modsecurity_crs_10
, and placed it in modsecurity-crs/rules/REQUEST-900-EXCLUSION
as per the install instructions. The code has been modified slightly to accept a range as opposed to a list.
SecRule REQUEST_URI "@beginsWith /wp-admin/" \
"msg:'Matched REQUEST URI and matched server-status. Disabling rules 960008 - 960017',\
phase:1,\
id:1881,\
t:none,\
pass,\
log,\
chain"
SecRule REQUEST_URI "server-status$" \
"t:none,\
ctl:ruleRemoveById=960008-960017"
D) Uncommented lines 350-361 (crs_exclusions_wordpress=1
) within modsecurity-crs/crs-setup
E) Have also, as per instructions, implemented the following into, httpd/conf/httpd.conf
:
<IfModule security2_module>
Include modsecurity-crs/crs-setup.conf
Include modsecurity-crs/rules/*.conf
</IfModule>
LoadModule security2_module modules/mod_security2.so
LoadModule unique_id_module modules/mod_unique_id.so
-- [[ RUN ]] --
$ sudo systemctl restart httpd.service -- successfull
$ sudo systemctl status -l httpd.service -- Active (running)
Unfortunately, I still have the same issues.
There is a distinct chance I may not have linked something somewhere or may have not uncommented something, it could well be that I have uncommented too many with a high setting!
Hope this helps?
Appreciated
Solution 1:[1]
CRS Dev-On-Duty here. It seems like you are facing an OWASP ModSecurity Core Rule Set false positive that could possibly be covered by the Wordpress rule exclusion package. To activate this rule exclusion package, enable the rule 900130 in the crs-setup.conf and enable the appropriate package.
To get more information about the Core Rule Set installation and to understand Core Rule Set tuning process in general, please have a look at these linked, excellent Core Rule Set tutorials.
If the problem persists, then I need more information to help you:
Please provide the following if possible:
- Full alert message (ideally send us the full audit log of the request)
- Web server and version or the platform you are using
- ModSecurity version
- CRS version
ATTENTION: When submitting logs, please remove all personal information like IP addresses, hostnames, passwords, etc.
We'll be happy to have a look afterwards.
UPDATE:
Sorry it took so long to respond. I didn't notice that you updated your issue. I've only seen it now as I'm OWASP ModSecurity Core Rule Set (CRS) dev-on-duty again.
First of all I think you now have a conflict with two different CRS versions.
When I see modsecurity_crs_21_protocal
and modsecurity_crs_10_config
I see that you have loaded OWASP CRS version 2.
Here is what the CRS version 2 rules look like: https://github.com/coreruleset/coreruleset/tree/v2.2/master/base_rules
Current version is OWASP CRS 3: https://github.com/coreruleset/coreruleset/tree/v3.3/master/rules
As you see the rule files have different names and numbering.
I see these CRS 3 rules in your "Web Server Error Log" and when I see modsecurity-crs/rules/RESPONSE_980_CORRELATION
.
I also suspect this conflict when I see the following log line / log section H
:
Producer: ModSecurity for Apache/2.9.3 (http://www.modsecurity.org/); OWASP_CRS/2.2.9; OWASP_CRS/3.3.2.
So I think the first step is to remove the old CRS version 2.
I see that you are loading the OWASP ModSecurity CRS rules here:
<IfModule security2_module>
Include modsecurity-crs/crs-setup.conf
Include modsecurity-crs/rules/*.conf
</IfModule>
Are there only CRS 3 rules in this directory modsecurity-crs/rules/? I think so.
So questions are: how do you install the OWASP CRS rules? And where are the CRS version 2 rules loaded and can you remove the loading of these rules?
Then, we'll take the next step and have a look at the log files again when the old rules are gone.
This time I'll follow the changes on this issue!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |