@@ -11,6 +11,7 @@ import (
11
11
"net/http"
12
12
"os"
13
13
"path"
14
+ "reflect"
14
15
"strings"
15
16
"sync"
16
17
27
28
28
29
var defaultPlatform string
29
30
31
+ var defaultTrustedCIDRs = []* net.IPNet {{IP : net.IP {0x0 , 0x0 , 0x0 , 0x0 }, Mask : net.IPMask {0x0 , 0x0 , 0x0 , 0x0 }}} // 0.0.0.0/0
32
+
30
33
// HandlerFunc defines the handler used by gin middleware as return value.
31
34
type HandlerFunc func (* Context )
32
35
@@ -119,15 +122,9 @@ type Engine struct {
119
122
// List of headers used to obtain the client IP when
120
123
// `(*gin.Engine).ForwardedByClientIP` is `true` and
121
124
// `(*gin.Context).Request.RemoteAddr` is matched by at least one of the
122
- // network origins of `(*gin.Engine).TrustedProxies `.
125
+ // network origins of list defined by `(*gin.Engine).SetTrustedProxies() `.
123
126
RemoteIPHeaders []string
124
127
125
- // List of network origins (IPv4 addresses, IPv4 CIDRs, IPv6 addresses or
126
- // IPv6 CIDRs) from which to trust request's headers that contain
127
- // alternative client IP when `(*gin.Engine).ForwardedByClientIP` is
128
- // `true`.
129
- TrustedProxies []string
130
-
131
128
// If set to a constant of value gin.Platform*, trusts the headers set by
132
129
// that platform, for example to determine the client IP
133
130
TrustedPlatform string
@@ -147,6 +144,7 @@ type Engine struct {
147
144
pool sync.Pool
148
145
trees methodTrees
149
146
maxParams uint16
147
+ trustedProxies []string
150
148
trustedCIDRs []* net.IPNet
151
149
}
152
150
@@ -174,7 +172,6 @@ func New() *Engine {
174
172
HandleMethodNotAllowed : false ,
175
173
ForwardedByClientIP : true ,
176
174
RemoteIPHeaders : []string {"X-Forwarded-For" , "X-Real-IP" },
177
- TrustedProxies : []string {"0.0.0.0/0" },
178
175
TrustedPlatform : defaultPlatform ,
179
176
UseRawPath : false ,
180
177
RemoveExtraSlash : false ,
@@ -183,7 +180,8 @@ func New() *Engine {
183
180
trees : make (methodTrees , 0 , 9 ),
184
181
delims : render.Delims {Left : "{{" , Right : "}}" },
185
182
secureJSONPrefix : "while(1);" ,
186
- trustedCIDRs : []* net.IPNet {{IP : net.IP {0x0 , 0x0 , 0x0 , 0x0 }, Mask : net.IPMask {0x0 , 0x0 , 0x0 , 0x0 }}},
183
+ trustedProxies : []string {"0.0.0.0/0" },
184
+ trustedCIDRs : defaultTrustedCIDRs ,
187
185
}
188
186
engine .RouterGroup .engine = engine
189
187
engine .pool .New = func () interface {} {
@@ -342,9 +340,9 @@ func iterate(path, method string, routes RoutesInfo, root *node) RoutesInfo {
342
340
func (engine * Engine ) Run (addr ... string ) (err error ) {
343
341
defer func () { debugPrintError (err ) }()
344
342
345
- err = engine .parseTrustedProxies ()
346
- if err != nil {
347
- return err
343
+ if engine .isUnsafeTrustedProxies () {
344
+ debugPrint ( "[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value. \n " +
345
+ "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details." )
348
346
}
349
347
350
348
address := resolveAddress (addr )
@@ -354,12 +352,12 @@ func (engine *Engine) Run(addr ...string) (err error) {
354
352
}
355
353
356
354
func (engine * Engine ) prepareTrustedCIDRs () ([]* net.IPNet , error ) {
357
- if engine .TrustedProxies == nil {
355
+ if engine .trustedProxies == nil {
358
356
return nil , nil
359
357
}
360
358
361
- cidr := make ([]* net.IPNet , 0 , len (engine .TrustedProxies ))
362
- for _ , trustedProxy := range engine .TrustedProxies {
359
+ cidr := make ([]* net.IPNet , 0 , len (engine .trustedProxies ))
360
+ for _ , trustedProxy := range engine .trustedProxies {
363
361
if ! strings .Contains (trustedProxy , "/" ) {
364
362
ip := parseIP (trustedProxy )
365
363
if ip == nil {
@@ -382,13 +380,25 @@ func (engine *Engine) prepareTrustedCIDRs() ([]*net.IPNet, error) {
382
380
return cidr , nil
383
381
}
384
382
385
- // SetTrustedProxies set Engine.TrustedProxies
383
+ // SetTrustedProxies set a list of network origins (IPv4 addresses,
384
+ // IPv4 CIDRs, IPv6 addresses or IPv6 CIDRs) from which to trust
385
+ // request's headers that contain alternative client IP when
386
+ // `(*gin.Engine).ForwardedByClientIP` is `true`. `TrustedProxies`
387
+ // feature is enabled by default, and it also trusts all proxies
388
+ // by default. If you want to disable this feature, use
389
+ // Engine.SetTrustedProxies(nil), then Context.ClientIP() will
390
+ // return the remote address directly.
386
391
func (engine * Engine ) SetTrustedProxies (trustedProxies []string ) error {
387
- engine .TrustedProxies = trustedProxies
392
+ engine .trustedProxies = trustedProxies
388
393
return engine .parseTrustedProxies ()
389
394
}
390
395
391
- // parseTrustedProxies parse Engine.TrustedProxies to Engine.trustedCIDRs
396
+ // isUnsafeTrustedProxies compares Engine.trustedCIDRs and defaultTrustedCIDRs, it's not safe if equal (returns true)
397
+ func (engine * Engine ) isUnsafeTrustedProxies () bool {
398
+ return reflect .DeepEqual (engine .trustedCIDRs , defaultTrustedCIDRs )
399
+ }
400
+
401
+ // parseTrustedProxies parse Engine.trustedProxies to Engine.trustedCIDRs
392
402
func (engine * Engine ) parseTrustedProxies () error {
393
403
trustedCIDRs , err := engine .prepareTrustedCIDRs ()
394
404
engine .trustedCIDRs = trustedCIDRs
@@ -416,9 +426,9 @@ func (engine *Engine) RunTLS(addr, certFile, keyFile string) (err error) {
416
426
debugPrint ("Listening and serving HTTPS on %s\n " , addr )
417
427
defer func () { debugPrintError (err ) }()
418
428
419
- err = engine .parseTrustedProxies ()
420
- if err != nil {
421
- return err
429
+ if engine .isUnsafeTrustedProxies () {
430
+ debugPrint ( "[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value. \n " +
431
+ "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details." )
422
432
}
423
433
424
434
err = http .ListenAndServeTLS (addr , certFile , keyFile , engine )
@@ -432,9 +442,9 @@ func (engine *Engine) RunUnix(file string) (err error) {
432
442
debugPrint ("Listening and serving HTTP on unix:/%s" , file )
433
443
defer func () { debugPrintError (err ) }()
434
444
435
- err = engine .parseTrustedProxies ()
436
- if err != nil {
437
- return err
445
+ if engine .isUnsafeTrustedProxies () {
446
+ debugPrint ( "[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value. \n " +
447
+ "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details." )
438
448
}
439
449
440
450
listener , err := net .Listen ("unix" , file )
@@ -455,9 +465,9 @@ func (engine *Engine) RunFd(fd int) (err error) {
455
465
debugPrint ("Listening and serving HTTP on fd@%d" , fd )
456
466
defer func () { debugPrintError (err ) }()
457
467
458
- err = engine .parseTrustedProxies ()
459
- if err != nil {
460
- return err
468
+ if engine .isUnsafeTrustedProxies () {
469
+ debugPrint ( "[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value. \n " +
470
+ "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details." )
461
471
}
462
472
463
473
f := os .NewFile (uintptr (fd ), fmt .Sprintf ("fd@%d" , fd ))
@@ -476,9 +486,9 @@ func (engine *Engine) RunListener(listener net.Listener) (err error) {
476
486
debugPrint ("Listening and serving HTTP on listener what's bind with address@%s" , listener .Addr ())
477
487
defer func () { debugPrintError (err ) }()
478
488
479
- err = engine .parseTrustedProxies ()
480
- if err != nil {
481
- return err
489
+ if engine .isUnsafeTrustedProxies () {
490
+ debugPrint ( "[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value. \n " +
491
+ "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details." )
482
492
}
483
493
484
494
err = http .Serve (listener , engine )
0 commit comments