Skip to content

WordPress with Coraza and Coreruleset

So this site is a standard WordPress running on Apache 2 with a Caddy reverse proxy serving OWASP CRS rules. The settings are:

include /coraza/modsecurity.conf
include /coraza/owasp-crs/crs-setup.conf
include /coraza/setup-vars.conf
include /coraza/owasp-crs/rules/*.conf

Specific rules to allow wordpress exclusions, it allows login and admin features that would normally create false positives:

SecAction "id:100014,phase:1,nolog,pass,setvar:tx.crs_exclusions_wordpress=1"

Fix some issue with Coraza and empty JSON payloads, it won’t be patched because this is supposed to work that way:

SecRule REQUEST_URI "^/wp-json/" "id:100015,phase:1,nolog,msg:'testing',ctl:ruleRemoveById=200002,pass"

Don’t try to attack this site, because it doesn’t have too many resources please 🙁

You can also check my Caddyfile running for the Docker image jptosso/coraza-caddy:latest

    order coraza_waf first
    log {
        output stdout
} {
    coraza_waf {
	directives `
		SecRule REQUEST_URI "^/wp-admin/admin-ajax.php" "id:150,phase:2,nolog,pass,ctl:ruleRemoveById=941180,\
        include /coraza/modsecurity.conf
        include /coraza/owasp-crs/crs-setup.conf
        include /coraza/crs-custom-settings.conf
        include /coraza/owasp-crs/rules/*.conf
    reverse_proxy wordpress {
        header_up Host
        header_up X-Real-IP {remote}
        header_up X-Unique-ID {http.transaction_id}
        header_up X-Forwarded-Proto https

I will be posting about performance and some issues I might be finding on the way.

Update 1: Issues with big file uploads and template customization.

I noticed 502 errors when trying to upload long files, so I checked Caddy logs and I found that the io.Reader for the request body was closed before sending it to the upstream server.
The solution was to remove defer reader.Close() from the multipart body processor but a second error came, request body wasn’t being send to the upstream server for multipart requests, so I did a quick fix and I hardcoded the new reader into Caddy:

	re, err := tx.RequestBodyBuffer.Reader()
	if err != nil {
		return err
	r.Body = io.NopCloser(re)
	rec := NewStreamRecorder(w, tx)

The next issue was a customization request for the template, I wanted to added some widget but two rules were triggered, 941180 and 941160. It was a quick fix with ctl:

SecRule REQUEST_URI "^/wp-admin/admin-ajax.php$" \

I could have used ruleRemoveTargetById but there were so many events being triggered for both rules.

Update 2: New plugin and xmlrpc

Everything is still running smooth, logs has been updated to “console” format and two exceptions were added, one of them is for the google plugin and the other one was for xmlrpc:

SecRule REQUEST_URI "^/wp-json/google-" "id:160,phase:1,nolog,pass,ctl:ruleRemoveById=930120"
SecRule REQUEST_URI "^/xmlrpc.php$" "id:170,phase:1,nolog,pass,ctl:ruleRemoveById=941100"

2 Replies to “WordPress with Coraza and Coreruleset”

    1. I haven’t tested Caddy PHP-FPM connector, it should be transparent for Coraza because it works in a different layer but I will definitely add some info.

Leave a Reply

Your email address will not be published. Required fields are marked *