Juan Pablo Tosso

Cybersecurity Research Engineer

Backend Developer

Penetration Tester

Open-Source Developer

Juan Pablo Tosso
Juan Pablo Tosso
Juan Pablo Tosso
Juan Pablo Tosso

Cybersecurity Research Engineer

Backend Developer

Penetration Tester

Open-Source Developer

Blog Post

WordPress with Coraza and Coreruleset

December 5, 2021 Coraza

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
    }    
}
tosso.io www.tosso.io {
    coraza_waf {
	directives `
		SecRule REQUEST_URI "^/wp-admin/admin-ajax.php" "id:150,phase:2,nolog,pass,ctl:ruleRemoveById=941180,\
		ctl:ruleRemoveById=941160"
	`
        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 www.tosso.io
        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$" \
"id:105,pass,nolog,ctl:ruleRemoveById=941180,ctl:ruleRemoveById=941160"

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 Comments
  • O-Zone 6:27 pm December 25, 2021 Reply

    Interesting! Just to know, why you didn’t choose to use Caddy to serve directly WordPress files?

    • jptosso 8:13 pm December 27, 2021 Reply

      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.

Write a comment