Hi Andrea,

We have recently reconfigured our Tomcat installations to use https only, so 
that any request via the proxy is redirected to 
https://<internal_server>:port/geoserver<https://%3cinternal_server%3e:port/geoserver>


This would be another configuration option

Regards,

Graham Humphries | System Analyst
Department of State Growth
4 Salamanca Place, Hobart TAS 7000 | GPO Box 536, Hobart TAS 7001
P: (03) 6166 3155
www.stategrowth.tas.gov.au<https://www.stategrowth.tas.gov.au/>
Courage to make a difference through
TEAMWORK | INTEGRITY | RESPECT | EXCELLENCE

In recognition of the deep history and culture of this island, I acknowledge 
and pay my respects to all Tasmanian Aboriginal people; the past, and present 
custodians of the Land.

From: Andrea Aime <andrea.a...@geosolutionsgroup.com>
Sent: Tuesday, 4 February 2025 1:03 AM
To: GeoServer <geoserver-devel@lists.sourceforge.net>
Subject: [Geoserver-devel] CSP with a proxy, how to deal with it

Hi all,
I've spent some time trying to figure out how to attack the issue of CSP + 
Proxy with SSL termination, this mail contains my findings (warning, long and 
technical).

First of all, what's going on?
GeoServer code, Spring security, and Wicket internals, all tend to use 
HTTPServletReponse.redirect("${relativePath}"), where relativePath is often 
"web".

>From Servlet API 
>javadoc<https://javaee.github.io/javaee-spec/javadocs/javax/servlet/http/HttpServletResponse.html#sendRedirect-java.lang.String->
> (thanks Steve) we learn the method should be implemented by the container by 
>turning the relative path into an absolute URL.
That is done by taking the HTTP Host header, which is part of the spec and 
guaranteed to be there, the context path (e.g., "geoserver") and the relative 
path provided as an argument.

The protocol is an issue: there is not true standard HTTP header indicating the 
protocol (there are non-standard headers though, more on this later), so the 
servlet container will use whatever protocol it received the request onto.

Now, it's pretty common practice that SSL is handled by proxy in front of 
GeoServer, with nginx and apache being common choices. So the request goes to, 
say 
"https://gs-main.geosolutionsgroup.com/geoserver/web/<http://gs-main.geosolutionsgroup.com/geoserver/web/>",
 the proxy handles SSL and forwards the request as 
"http://<internal-gs-host>:8080/geoserver/web/<http://%3cinternal-gs-host%3e:8080/geoserver/web/>"
 and when doing a redirect the servlet container returns a HTTP 302 with a 
Location header stating 
"http://gs-main.geosolutionsgroup.com/geoserver/myChosenPath<http://gs-main.geosolutionsgroup.com/geoserver/myChosenPath>".
 Whoops!

So far everything worked anyways, because most sites have transitioned in 
recent years from HTTP to HTTPS and have a built-in configuration redirecting 
any HTTP request to HTTPS.
So it works by doing this:

  1.  GeoServer sends a redirect with Location header set to 
http://gs-main.geosolutionsgroup.com/geoserver/myChosenPath<http://gs-main.geosolutionsgroup.com/geoserver/myChosenPath>
  2.  The browser receives exactly that, and opens that new URL
  3.  The proxy in turns performs another redirect, this time to 
https://gs-main.geosolutionsgroup.com/geoserver/myChosenPath<http://gs-main.geosolutionsgroup.com/geoserver/myChosenPath>
  4.  The browser follows the new path and we're back in business
This happens on a set of very common actions in the GeoServer UI: login, 
logout, switch tab in the tabbed layer pages, click save in a number of pages 
where save is implemented as an Ajax button.

Introduce CSP, and the browser gets instructed not to reach out to pages 
outside of the origin server and protocol, and our little set of actions above 
stops at point 2., with errors only visible if you open the developer tools.

How to get out of it? I found and considered a few approaches.

-------------------------------------------------------------------------------------

First one: have GeoServer redirect to a full URL every time. That's allowed by 
the servlet API and we could build the full redirect URL by using the proxy 
base URL configuration. Redirects are done also in code outside of GeoServer, 
but this could be performed in a servlet wrapper.
However, I know for a fact it's going to break secure deploys that don't expose 
the GUI on the web... the typical situation there is that they access GeoServer 
directly within the DMZ, on the actual GeoServer IP, and the GUI needs to keep 
on working in that case.
We'd need some way to tell apart the local direct access from the "through 
proxy" access.
Which would mean, fiddling with the proxy configuration anyways. Meh!

Second one: tell the web container which protocol to use. The non standard, yet 
common, "X-Forwarded-Proto" header can be set to "https" as a way to tell the 
container which protocol it should use for redirects. However, containers will, 
out of the box, ignore it, because the header is not guarnteed to be there and 
it may be manipulated by clients to mount some sort of attack.
Futhermore, each container has a different way to configure using the header. 
For example, in Tomcat it would be declaring a Valve in server.xml:

<Valve className="org.apache.catalina.valves.RemoteIpValve"
       protocolHeader="X-Forwarded-Proto"
       remoteIpHeader="X-Forwarded-For"
       internalProxies=".*" />

But in Jetty, it would be something completely different in start.ini:

--module=forwarded

(mind, untested) and so on for each different servlet container.

Third one: tell the proxy to switch the protocol

The proxy can be configured to switch the proxy in redirect calls. Again, we're 
facing a case by case scenario.

For nginx (the case that I've actually tried, and can confirm it works):

proxy_redirect http://$host/ https://$host/;

For apache (mind, untested):

Header edit Location ^http://(.*)$ https://$1

and so on, a different way to do this in each proxy software.

-------------------------------------------------------------------------------------

Which one to choose? I've made a few questions around and asked people about 
this, as well as a few AIs, the summary is:

  *   SSL termination is normally in the hands of system admins, which may or 
may not dealing with the GeoServer setup
  *   Those same people are familiar with their proxy of choice, but very 
often, only lightly familiar with Tomcat configuration. Asking around about the 
Valve, I could not find anyone that knew what it was, while the nginx setting 
was known, although not normally used
  *   Asking AIs confirmed that web container setup is well known only in Java 
heavy shops, but a number of GeoServer deploys are in environments where GS is 
the only Java app around.
So I'd suggest to go an document how to configure proxies. I can offer an 
example of Nginx.
Can anyone else test the Apache approach? And then we can ask users to 
contribute approaches for other proxies, once the admins know what to do, they 
should be able to figure out the specific setting quickly.


Regards,

Andrea Aime



==

GeoServer Professional Services from the experts!

Visit http://bit.ly/gs-services-us for more information.

==

Ing. Andrea Aime
@geowolf
Technical Lead

GeoSolutions Group
phone: +39 0584 962313

fax:     +39 0584 1660272

mob:   +39  339 8844549


https://www.geosolutionsgroup.com/

http://twitter.com/geosolutions_it

-------------------------------------------------------

Con riferimento alla normativa sul trattamento dei dati personali (Reg. UE 
2016/679 - Regolamento generale sulla protezione dei dati "GDPR"), si precisa 
che ogni circostanza inerente alla presente email (il suo contenuto, gli 
eventuali allegati, etc.) è un dato la cui conoscenza è riservata al/i solo/i 
destinatario/i indicati dallo scrivente. Se il messaggio Le è giunto per 
errore, è tenuta/o a cancellarlo, ogni altra operazione è illecita. Le sarei 
comunque grato se potesse darmene notizia.

This email is intended only for the person or entity to which it is addressed 
and may contain information that is privileged, confidential or otherwise 
protected from disclosure. We remind that - as provided by European Regulation 
2016/679 "GDPR" - copying, dissemination or use of this e-mail or the 
information herein by anyone other than the intended recipient is prohibited. 
If you have received this email by mistake, please notify us immediately by 
telephone or e-mail

________________________________

CONFIDENTIALITY NOTICE AND DISCLAIMER
The information in this transmission may be confidential and/or protected by 
legal professional privilege, and is intended only for the person or persons to 
whom it is addressed. If you are not such a person, you are warned that any 
disclosure, copying or dissemination of the information is unauthorised. If you 
have received the transmission in error, please immediately contact this office 
by telephone, fax or email, to inform us of the error and to enable 
arrangements to be made for the destruction of the transmission, or its return 
at our cost. No liability is accepted for any unauthorised use of the 
information contained in this transmission.
_______________________________________________
Geoserver-devel mailing list
Geoserver-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geoserver-devel

Reply via email to