Skip to content

Commit 391dd7f

Browse files
authored
Merge pull request from GHSA-vjh7-5r6x-xh6g
* fix:Incorrect identification of source IP addresses * feat: support reverse proxy * stash * stash * fix: the bug * fix: the bug * fix: the bug * fix: the bug * delete unused comment * refacotr the proccess * add comment to notice user to config correct proxy setting * fix:some problems * refactor the ip * Update gateway_route.go
1 parent f76b6bc commit 391dd7f

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

route/gateway_route.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package route
22

33
import (
44
"net/http"
5+
"strings"
56

67
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
78
"github.com/IceWhaleTech/CasaOS-Gateway/service"
@@ -18,6 +19,38 @@ func NewGatewayRoute(management *service.Management) *GatewayRoute {
1819
}
1920
}
2021

22+
// the function is to ensure the request source IP is correct.
23+
func rewriteRequestSourceIP(r *http.Request) {
24+
// we may receive two kinds of requests. a request from reverse proxy. a request from client.
25+
26+
// in reverse proxy, X-Forwarded-For will like
27+
// `X-Forwarded-For:[192.168.6.102]`(normal)
28+
// `X-Forwarded-For:[::1, 192.168.6.102]`(hacked) Note: the ::1 is inject by attacker.
29+
// `X-Forwarded-For:[::1]`(normal or hacked) local request. But it from browser have JWT. So we can and need to verify it
30+
// `X-Forwarded-For:[::1,::1]`(normal or hacked) attacker can build the request to bypass the verification.
31+
// But in the case. the remoteAddress should be the real ip. So we can use remoteAddress to verify it.
32+
33+
ipList := strings.Split(r.Header.Get("X-Forwarded-For"), ",")
34+
35+
r.Header.Del("X-Forwarded-For")
36+
r.Header.Del("X-Real-IP")
37+
38+
// Note: the X-Forwarded-For depend the correct config from reverse proxy.
39+
// otherwise the X-Forwarded-For may be empty.
40+
remoteIP := r.RemoteAddr[:strings.LastIndex(r.RemoteAddr, ":")]
41+
if len(ipList) > 0 && (remoteIP == "127.0.0.1" || remoteIP == "::1") {
42+
// to process the request from reverse proxy
43+
44+
// in reverse proxy, X-Forwarded-For will container multiple IPs.
45+
// if the request is from reverse proxy, the r.RemoteAddr will be 127.0.0.1.
46+
// So we need get ip from X-Forwarded-For
47+
r.Header.Add("X-Forwarded-For", ipList[len(ipList)-1])
48+
}
49+
// to process the request from client.
50+
// the gateway will add the X-Forwarded-For to request header.
51+
// So we didn't need to add it.
52+
}
53+
2154
func (g *GatewayRoute) GetRoute() *http.ServeMux {
2255
gatewayMux := http.NewServeMux()
2356
gatewayMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
@@ -36,6 +69,10 @@ func (g *GatewayRoute) GetRoute() *http.ServeMux {
3669
return
3770
}
3871

72+
// to fix https://github.com/IceWhaleTech/CasaOS/security/advisories/GHSA-32h8-rgcj-2g3c#event-102885
73+
// API V1 and V2 both read ip from request header. So the fix is effective for v1 and v2.
74+
rewriteRequestSourceIP(r)
75+
3976
proxy.ServeHTTP(w, r)
4077
})
4178

0 commit comments

Comments
 (0)