danweh
danweh

Reputation: 41

Apache reverse proxy and Wicket CsrfPreventionRequestCycleListener

Since integrating CsrfPreventionRequestCycleListener into our Apache Wicket (7.6.0) application, we have a problem operating the application behind an Apache reverse proxy.

Our configuration terminates SSL at Apache, and the reverse proxy passes the requests via http to our Wildfly 10 application server. This allows us to offload TLS/SSL among other things.

But since adding the CsrfPreventionRequestCycleListener, we are seeing the following in the server.log file and connections are aborted:

[org.apache.wicket.protocol.http.CsrfPreventionRequestCycleListener] 
(default task-12) Possible CSRF attack, request URL: 
 http://example.com/example/portal/wicket/page, 
 Origin: https://example.com, action: aborted with error 
 400 Origin does not correspond to request

The problematic Apache config:

<VirtualHost example.com:443>
ServerName example.com
LogLevel debug
SSLEngine On
SSLCertificateFile             /var/example/example.com/signed.crt
SSLCertificateKeyFile          /var/example/example.com/domain.key
SSLCACertificateFile           /var/example/example.com/intermediate.pem

SSLProtocol +TLSv1.2 +TLSv1.1 +TLSv1
SSLOpenSSLConfCmd DHParameters "/usr/local/apache2/1024dhparams.pem"

SSLProxyEngine on
ProxyPass        / http://localhost:8390/ timeout=600
ProxyPassReverse / http://localhost:8390/ timeout=600
ProxyPreserveHost On

Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Credentials "true"
Header edit Location ^http(\:\/\/.*)$ https$1

We found a solution using http2 but would prefer one without http2 (for reasons, see in https://http2.pro/doc/Apache).

The working Apache configuration using http2

<VirtualHost example.com:443>
ServerName example.com
LogLevel debug
SSLEngine On
SSLCertificateFile             /var/example/example.com/signed.crt
SSLCertificateKeyFile          /var/example/example.com/domain.key
SSLCACertificateFile           /var/example/example.com/intermediate.pem
SSLProtocol +TLSv1.2 +TLSv1.1 +TLSv1
SSLOpenSSLConfCmd DHParameters "/usr/local/apache2/1024dhparams.pem"

SSLProxyEngine On
ProxyPreserveHost On

# Settings for http2 communication
Protocols h2 http/1.1
ProxyPass   / https://localhost:8754/ timeout=600
ProxyPassReverse    / https://localhost:8754/ timeout=600
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off 

Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Credentials "true"
# Header edit Location ^http(\:\/\/.*)$ https$1
</VirtualHost>

Can anyone help us create a valid apache reverse proxy configuration that works with the CsrfPreventionRequestCycleListener without the http2 module?

Upvotes: 4

Views: 2804

Answers (1)

Christian Wolf
Christian Wolf

Reputation: 1237

I think I had a similar issue here and solved it just now. I think you might have solved your issue by now but maybe anyone else is falling over this topic.

You might want to look into a network dump to verify the problem. For me, apache sent requests to the locally running service (your case to http://localhost:8754) while some request headers were still referring the public name https://example.com. This was detected as a security risk and the connection refused by the underlying service.

I made sure, that mod_headers was enabled in apache and added the line

RequestHeader edit Referer "https://example.com" "http://localhost:8754"

After that no more references to anything related to example.com was in my tcp dumps and the connection was opened successfully.

You might need to adopt according to your setup (maybe you need multiple headers corrected or something similar). I cannot try it out at the moment.

Upvotes: 2

Related Questions