Skip to content

Commit 58c44d4

Browse files
Merge commit from fork
Stop using url.Parse for request-target paths. It interprets "//" as an RFC 3986 authority delimiter, so "//admin/people" silently drops "admin" from parsed_path, bypassing policies that check path segments. Signed-off-by: Ville Vesilehto <ville@vesilehto.fi> Co-authored-by: Ville Vesilehto <ville@vesilehto.fi>
1 parent dd0d204 commit 58c44d4

2 files changed

Lines changed: 23 additions & 3 deletions

File tree

envoyauth/request.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,19 @@ func RequestToInput(req any, logger logging.Logger, protoSet *protoregistry.File
112112
}
113113

114114
func getParsedPathAndQuery(path string) ([]string, map[string]any, error) {
115-
parsedURL, err := url.Parse(path)
115+
rawPath, rawQuery, _ := strings.Cut(path, "?")
116+
117+
decodedPath, err := url.PathUnescape(rawPath)
116118
if err != nil {
117119
return nil, nil, err
118120
}
119121

120-
parsedPath := strings.Split(strings.TrimLeft(parsedURL.Path, "/"), "/")
122+
parsedPath := strings.Split(strings.TrimLeft(decodedPath, "/"), "/")
121123

122-
query := parsedURL.Query()
124+
query, err := url.ParseQuery(rawQuery)
125+
if err != nil {
126+
return nil, nil, err
127+
}
123128
parsedQueryInterface := make(map[string]any, len(query))
124129
for paramKey, paramValues := range query {
125130
parsedQueryInterface[paramKey] = paramValues

envoyauth/request_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,21 @@ func TestParsedPathAndQuery(t *testing.T) {
651651
[]string{"my", "test", "path"},
652652
map[string]any{"a": []string{"1", "new\nline"}},
653653
},
654+
{
655+
createExtReqWithPath("//x/people"),
656+
[]string{"x", "people"},
657+
map[string]any{},
658+
},
659+
{
660+
createExtReqWithPath("//admin/dashboard"),
661+
[]string{"admin", "dashboard"},
662+
map[string]any{},
663+
},
664+
{
665+
createExtReqWithPath("//x/people?a=1"),
666+
[]string{"x", "people"},
667+
map[string]any{"a": []string{"1"}},
668+
},
654669
}
655670

656671
for _, tt := range tests {

0 commit comments

Comments
 (0)