@@ -124,6 +124,16 @@ def get_workspace_repository(
124124 ]
125125)
126126
127+ # Do not forward spoofed reverse-proxy informational headers:
128+ STRIP_REQUEST_HEADERS = HOP_BY_HOP_HEADERS | {
129+ "host" ,
130+ "x-forwarded-for" ,
131+ "x-forwarded-host" ,
132+ "x-forwarded-proto" ,
133+ "x-real-ip" ,
134+ "forwarded" ,
135+ }
136+
127137# Define paths that do not require X-Workspace header
128138AUTH_WHITELIST_PATTERNS = [
129139 re .compile (p )
@@ -135,11 +145,24 @@ def get_workspace_repository(
135145
136146
137147@app .get ("/api/capabilities.json" )
138- async def capabilities ():
148+ async def capabilities (request : Request ):
139149 """Proxy OSM capabilities manifest without requiring authentication."""
140150
151+ client_host = request .client .host if request .client else "unknown"
152+ req_headers = [
153+ (k .encode (), v .encode ())
154+ for k , v in request .headers .items ()
155+ if k .lower () not in STRIP_REQUEST_HEADERS
156+ ] + [
157+ (b"Host" , _osm_client .base_url .host .encode ()),
158+ (b"X-Real-IP" , client_host .encode ()),
159+ (b"X-Forwarded-For" , client_host .encode ()),
160+ (b"X-Forwarded-Host" , (request .url .hostname or "" ).encode ()),
161+ (b"X-Forwarded-Proto" , request .url .scheme .encode ()),
162+ ]
163+
141164 url = httpx .URL (path = "/api/capabilities.json" )
142- rp_req = _osm_client .build_request ("GET" , url )
165+ rp_req = _osm_client .build_request ("GET" , url , headers = req_headers )
143166
144167 try :
145168 rp_resp = await _osm_client .send (rp_req , stream = True )
@@ -208,16 +231,21 @@ async def catch_all(
208231 )
209232
210233 client = _osm_client
211-
212- # Forward all request headers except the hop-by-hops:
213- new_headers = [
234+ client_host = request .client .host if request .client else "unknown"
235+ req_headers = [
214236 (k .encode (), v .encode ())
215237 for k , v in request .headers .items ()
216- if k .lower () not in HOP_BY_HOP_HEADERS
238+ if k .lower () not in STRIP_REQUEST_HEADERS
239+ ] + [
240+ (b"Host" , client .base_url .host .encode ()),
241+ (b"X-Real-IP" , client_host .encode ()),
242+ (b"X-Forwarded-For" , client_host .encode ()),
243+ (b"X-Forwarded-Host" , (request .url .hostname or "" ).encode ()),
244+ (b"X-Forwarded-Proto" , request .url .scheme .encode ()),
217245 ]
218246
219247 rp_req = client .build_request (
220- request .method , url , headers = new_headers , content = request .stream ()
248+ request .method , url , headers = req_headers , content = request .stream ()
221249 )
222250 try :
223251 rp_resp = await client .send (rp_req , stream = True )
0 commit comments