security: sanitize path and uri

This commit is contained in:
yusing
2025-03-22 23:53:33 +08:00
parent 4a5e0b8d81
commit f3840d56af
5 changed files with 106 additions and 11 deletions

View File

@@ -19,6 +19,7 @@ import (
gphttp "github.com/yusing/go-proxy/internal/net/gphttp"
"github.com/yusing/go-proxy/internal/route/routes"
route "github.com/yusing/go-proxy/internal/route/types"
"github.com/yusing/go-proxy/internal/utils/strutils"
)
type fetchResult struct {
@@ -207,10 +208,7 @@ func findIconSlow(r route.HTTPRoute, req *http.Request, uri string) *fetchResult
defer cancel()
newReq := req.WithContext(ctx)
newReq.Header.Set("Accept-Encoding", "identity") // disable compression
if !strings.HasPrefix(uri, "/") {
uri = "/" + uri
}
u, err := url.ParseRequestURI(uri)
u, err := url.ParseRequestURI(strutils.SanitizeURI(uri))
if err != nil {
logging.Error().Err(err).
Str("route", r.TargetName()).
@@ -231,11 +229,8 @@ func findIconSlow(r route.HTTPRoute, req *http.Request, uri string) *fetchResult
return &fetchResult{statusCode: http.StatusBadGateway, errMsg: "connection error"}
default:
if loc := c.Header().Get("Location"); loc != "" {
loc = path.Clean(loc)
if !strings.HasPrefix(loc, "/") {
loc = "/" + loc
}
if loc == newReq.URL.Path {
loc = strutils.SanitizeURI(loc)
if loc == "/" || loc == newReq.URL.Path {
return &fetchResult{statusCode: http.StatusBadGateway, errMsg: "circular redirect"}
}
return findIconSlow(r, req, loc)

View File

@@ -126,11 +126,17 @@ func VerifyNewAgent(w http.ResponseWriter, r *http.Request) {
return
}
if err := os.WriteFile(certs.AgentCertsFilename(data.Host), zip, 0600); err != nil {
filename := certs.AgentCertsFilename(data.Host)
if !strutils.IsValidFilename(filename) {
gphttp.ClientError(w, gphttp.ErrInvalidKey("host"))
return
}
if err := os.WriteFile(filename, zip, 0600); err != nil {
gphttp.ServerError(w, r, err)
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte(fmt.Sprintf("Added %d routes", nRoutesAdded)))
w.Write(fmt.Appendf(nil, "Added %d routes", nRoutesAdded))
}