corazawaf / coraza-caddy

OWASP Coraza middleware for Caddy. It provides Web Application Firewall capabilities
https://www.coraza.io/
Apache License 2.0
290 stars 35 forks source link

Missing hostname in WAF logs #75

Open TheForcer opened 1 year ago

TheForcer commented 1 year ago

Hi everyone,

I am currently trying to implement Coraza into my Caddy setup, but for some reason the hostname of blocked requests does not get logged. As you can see in the log samples below, the hostname is recorded as [hostname ""]

2023/06/15 11:08:02.985 WARN    http.handlers.waf       [client "192.168.178.11"] Coraza: Access denied (phase 1). POST without Content-Length or Transfer-Encoding headers [file "@owasp_crs/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "1543"] [id "920180"] [rev ""] [msg "POST without Content-Length or Transfer-Encoding headers"] [data "0"] [severity "warning"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/210/272"] [hostname ""] [uri "/api/add"] [unique_id "iicqKuOYWuBJfVcM"]

2023/06/15 11:08:02.985 ERROR   http.handlers.waf       [client "192.168.178.11"] Coraza: Access denied (phase 2). XSS Attack Detected via libinjection [file "@owasp_crs/REQUEST-941-APPLICATION-ATTACK-XSS.conf"] [line "4432"] [id "941100"] [rev ""] [msg "XSS Attack Detected via libinjection"] [data "Matched Data: XSS data found within ARGS:url: <script>"] [severity "critical"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-xss"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/152/242"] [hostname ""] [uri "/api/add"] [unique_id "iicqKuOYWuBJfVcM"]

2023/06/15 11:08:02.985 ERROR   http.handlers.waf       [client "192.168.178.11"] Coraza: Access denied (phase 2). XSS Filter - Category 1: Script Tag Vector [file "@owasp_crs/REQUEST-941-APPLICATION-ATTACK-XSS.conf"] [line "4451"] [id "941110"] [rev ""] [msg "XSS Filter - Category 1: Script Tag Vector"] [data "Matched Data: <script> found within ARGS:url: <script>"] [severity "critical"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-xss"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/152/242"] [hostname ""] [uri "/api/add"] [unique_id "iicqKuOYWuBJfVcM"]

According to #35 this should be fixed, so I am not sure if there is a possible misconfiguration at play also.

I've compiled Caddy 2.6.4 with xcaddy in several ways, with the most recent command seen as below. AFAIK these versions should contain the servername fixes.

xcaddy build --with github.com/corazawaf/coraza-caddy/@v2.0.0-rc.2 --with github.com/corazawaf/coraza/@v3.0.0

My current Caddyfile looks like this. I am using the current rule files from coraza-coreruleset, haven't made any changes except additionaly allowing HTTP/3 & HTTP/3.0 versions in crs-setup.conf.

{
        debug
        http_port 1180
        https_port 11443
        admin off
        auto_https off
        order coraza_waf first
        servers {
                metrics
        }
}

(tls) {
        tls ./{args.0}_ecc/fullchain.cer ./{args.0}_ecc/{args.0}.key
        header {
                Strict-Transport-Security max-age=63072000;includeSubDomains;preload
                X-Content-Type-Options nosniff
                X-Frame-Options SAMEORIGIN
                X-Robots-Tag none
        }
}

(waf) {
        coraza_waf {
          #load_owasp_crs
          directives `
           Include @coraza.conf-recommended
           Include @crs-setup.conf.example
           Include @owasp_crs/*.conf
           SecRuleEngine On
          `
 }
}

memes.example.com {
        import tls example.com
        import waf
        reverse_proxy 10.0.0.109:5001
}

Would be happy about some hints. Thank you 😀

jcchavezs commented 1 year ago

Am I right to assume that hostname will come from this line https://github.com/corazawaf/coraza-caddy/blob/main/http.go#L44 @M4tteoP ?

M4tteoP commented 1 year ago

I think that around the hostname, and server name, we have to clarify a bit the logic and maybe do still some work around them:

Hostname The hostname field of the error logs has been aligned with https://github.com/corazawaf/coraza/pull/517/ to the ModSecurity behavior. It means that we expect that the field is populated with the server IP. The latter is provided by the connector via ProcessConnection (func (tx *Transaction) ProcessConnection(client string, cPort int, server string, sPort int). Currently, in the Caddy connector we are missing this last step, resulting in a hostname always empty.

Server name https://github.com/corazawaf/coraza/pull/572 is meant to fix the SERVER_NAME variable that was never been populated and therefore was never matching. For that purpose, we are providing SetServerName to the connectors, and we expect that it is populated with the Host header. It is the header provided as-is by the client and the SERVER_NAME variable itself is indeed meant to be used to perform checks on it.

The discussion/actions we should take are: 1) fix the ProcessConnection in the Caddy connector providing the server string. It could be the IP, or via some config providing a way to propagate the hostname that the coraza module is intercepting. 2) Evolve the conversation that we had in https://github.com/corazawaf/coraza/pull/517, and take into account the idea of performing a name resolution to provide more meaningful values for the hostname field.

Thanks @TheForcer for raising it!

jcchavezs commented 1 year ago

Any hint on how to obtain the right server name @mholt?

mholt commented 1 year ago

Are you talking about the user-given name of the server in the JSON config as keys here? https://caddyserver.com/docs/json/apps/http/servers/

jptosso commented 1 year ago

Sometimes users might bind ip address or just a port. We will have to cover all flanks

M4tteoP commented 1 year ago

FYI, related conversation ModSecurity side: https://github.com/SpiderLabs/ModSecurity/pull/2906

jptosso commented 1 year ago

Any idea on how to continue? The problem is we are not filling ProcessConnection and that is the variable we are using to display the logs.

ErazerBrecht commented 3 months ago

I don't want to be this dude but are there any plans? Afaik it's this line: https://github.com/corazawaf/coraza/blob/dc778126cf458b6a832ced0cffce077f1653147c/internal/corazarules/rule_match.go#L198

And I could create a PR with it being the host header if available. But it looks like it's being blocked at a 'higher level'.

For me specifically it would be nice to have the hostname because we have a single WAF for multiple domains. (And is also what we used to have with Apache)

jcchavezs commented 3 months ago

Please give it a stab @ErazerBrecht