@@ -236,8 +236,61 @@ func TestReverseProxyStripHeadersPresentInConnection(t *testing.T) {
236
236
}
237
237
}
238
238
239
+ func TestDontTrustForwardedHeaders (t * testing.T ) {
240
+ const prevForwardedFor = "client ip"
241
+ const prevForwardedProto = "https"
242
+ const prevForwardedHost = "example.com"
243
+ const backendResponse = "I am the backend"
244
+ const backendStatus = 404
245
+ backend := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
246
+ if r .Header .Get ("X-Forwarded-For" ) == "" {
247
+ t .Errorf ("didn't get X-Forwarded-For header" )
248
+ }
249
+ if strings .Contains (r .Header .Get ("X-Forwarded-For" ), prevForwardedFor ) {
250
+ t .Errorf ("X-Forwarded-For contains prior data" )
251
+ }
252
+ if strings .Contains (r .Header .Get ("X-Forwarded-Proto" ), prevForwardedProto ) {
253
+ t .Errorf ("X-Forwarded-Proto contains prior data" )
254
+ }
255
+ if strings .Contains (r .Header .Get ("X-Forwarded-Host" ), prevForwardedHost ) {
256
+ t .Errorf ("X-Forwarded-Host contains prior data" )
257
+ }
258
+ w .WriteHeader (backendStatus )
259
+ w .Write ([]byte (backendResponse ))
260
+ }))
261
+ defer backend .Close ()
262
+ backendURL , err := url .Parse (backend .URL )
263
+ if err != nil {
264
+ t .Fatal (err )
265
+ }
266
+ proxyHandler := NewSingleHostReverseProxy (backendURL )
267
+ frontend := httptest .NewServer (proxyHandler )
268
+ defer frontend .Close ()
269
+
270
+ getReq , _ := http .NewRequest ("GET" , frontend .URL , nil )
271
+ getReq .Host = "some-name"
272
+ getReq .Header .Set ("Connection" , "close" )
273
+ getReq .Header .Set ("X-Forwarded-For" , prevForwardedFor )
274
+ getReq .Header .Set ("X-Forwarded-Proto" , prevForwardedProto )
275
+ getReq .Header .Set ("X-Forwarded-Host" , prevForwardedHost )
276
+ getReq .Close = true
277
+ res , err := frontend .Client ().Do (getReq )
278
+ if err != nil {
279
+ t .Fatalf ("Get: %v" , err )
280
+ }
281
+ if g , e := res .StatusCode , backendStatus ; g != e {
282
+ t .Errorf ("got res.StatusCode %d; expected %d" , g , e )
283
+ }
284
+ bodyBytes , _ := ioutil .ReadAll (res .Body )
285
+ if g , e := string (bodyBytes ), backendResponse ; g != e {
286
+ t .Errorf ("got body %q; expected %q" , g , e )
287
+ }
288
+ }
289
+
239
290
func TestXForwardedFor (t * testing.T ) {
240
291
const prevForwardedFor = "client ip"
292
+ const prevForwardedProto = "https"
293
+ const prevForwardedHost = "example.com"
241
294
const backendResponse = "I am the backend"
242
295
const backendStatus = 404
243
296
backend := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
@@ -247,6 +300,12 @@ func TestXForwardedFor(t *testing.T) {
247
300
if ! strings .Contains (r .Header .Get ("X-Forwarded-For" ), prevForwardedFor ) {
248
301
t .Errorf ("X-Forwarded-For didn't contain prior data" )
249
302
}
303
+ if ! strings .Contains (r .Header .Get ("X-Forwarded-Proto" ), prevForwardedProto ) {
304
+ t .Errorf ("X-Forwarded-Proto didn't contain prior data" )
305
+ }
306
+ if ! strings .Contains (r .Header .Get ("X-Forwarded-Host" ), prevForwardedHost ) {
307
+ t .Errorf ("X-Forwarded-Host didn't contain prior data" )
308
+ }
250
309
w .WriteHeader (backendStatus )
251
310
w .Write ([]byte (backendResponse ))
252
311
}))
@@ -256,13 +315,16 @@ func TestXForwardedFor(t *testing.T) {
256
315
t .Fatal (err )
257
316
}
258
317
proxyHandler := NewSingleHostReverseProxy (backendURL )
318
+ proxyHandler .TrustForwardedHeaders = true
259
319
frontend := httptest .NewServer (proxyHandler )
260
320
defer frontend .Close ()
261
321
262
322
getReq , _ := http .NewRequest ("GET" , frontend .URL , nil )
263
323
getReq .Host = "some-name"
264
324
getReq .Header .Set ("Connection" , "close" )
265
325
getReq .Header .Set ("X-Forwarded-For" , prevForwardedFor )
326
+ getReq .Header .Set ("X-Forwarded-Proto" , prevForwardedProto )
327
+ getReq .Header .Set ("X-Forwarded-Host" , prevForwardedHost )
266
328
getReq .Close = true
267
329
res , err := frontend .Client ().Do (getReq )
268
330
if err != nil {
0 commit comments