A security vulnerability has been discovered in how the input.parsed_path field is constructed. HTTP request paths are treated as full URIs when parsed; interpreting leading path segments prefixed with double slashes (//) as authority components, and therefore dropping them from the parsed path. This creates a path interpretation mismatch between authorization policies and backend servers, enabling attackers to bypass access controls by crafting requests where the authorization filter evaluates a different path than the one ultimately served.
Attack example
HTTP request:
GET //admin/users HTTP/1.1
Host: example.com
Policy sees:
The leading //admin path segment is interpreted as an authority component, and dropped from input.parsed_path field:
{
"parsed_path": ["users"]
}
Backend receives:
//admin/users path, normalized to /admin/users.
Affected Request Pattern Examples
| Request path |
input.parsed_path |
input.attributes.request.http.path |
Discrepancy |
| / |
[""] |
/ |
✅ None |
| //foo |
[""] |
//foo |
❌ Mismatch |
| /admin |
["admin"] |
/admin |
✅ None |
| /admin/users |
["admin", "users"] |
/admin/users |
✅ None |
| //admin/users |
["users"] |
//admin/users |
❌ Mismatch |
Impact
Users are impacted if all the following conditions apply:
- Protected resources are path-hierarchical (e.g.,
/admin/users vs /users)
- Authorization policies use
input.parsed_path for path-based decisions
- Backend servers apply lenient path normalization
Patches
Go: v1.13.2-envoy-2
Docker: 1.13.2-envoy-2, 1.13.2-envoy-2-static
Workarounds
Users who cannot immediately upgrade opa-envoy-plugin are recommended to apply one, or more, of the workarrounds described below.
1. Enable the merge_slashes Envoy configuration option
As per Envoy best practices, enabling the merge_slashes configuration option in Envoy will remove redundant slashes from the request path before filtering is applied, effectively mitigating the input.parsed_path issue described in this advisory.
2. Use input.attributes.request.http.path instead of input.parsed_path in policies
The input.attributes.request.http.path field contains the unprocessed, raw request path. Users are recommended to update any policy using input.parsed_path to instead use the input.attributes.request.http.path field.
Example
package example
# Use instead of input.parsed_path
parsed_path := split( # tokenize into array
trim_left( # drop leading slashes
urlquery.decode(input.attributes.request.http.path), # url-decode the path
"/",
),
"/",
)
References
A security vulnerability has been discovered in how the
input.parsed_pathfield is constructed. HTTP request paths are treated as full URIs when parsed; interpreting leading path segments prefixed with double slashes (//) as authority components, and therefore dropping them from the parsed path. This creates a path interpretation mismatch between authorization policies and backend servers, enabling attackers to bypass access controls by crafting requests where the authorization filter evaluates a different path than the one ultimately served.Attack example
HTTP request:
Policy sees:
The leading
//adminpath segment is interpreted as an authority component, and dropped frominput.parsed_pathfield:{ "parsed_path": ["users"] }Backend receives:
//admin/userspath, normalized to/admin/users.Affected Request Pattern Examples
input.parsed_pathinput.attributes.request.http.pathImpact
Users are impacted if all the following conditions apply:
/admin/usersvs/users)input.parsed_pathfor path-based decisionsPatches
Go:
v1.13.2-envoy-2Docker:
1.13.2-envoy-2,1.13.2-envoy-2-staticWorkarounds
Users who cannot immediately upgrade opa-envoy-plugin are recommended to apply one, or more, of the workarrounds described below.
1. Enable the
merge_slashesEnvoy configuration optionAs per Envoy best practices, enabling the merge_slashes configuration option in Envoy will remove redundant slashes from the request path before filtering is applied, effectively mitigating the
input.parsed_pathissue described in this advisory.2. Use
input.attributes.request.http.pathinstead ofinput.parsed_pathin policiesThe
input.attributes.request.http.pathfield contains the unprocessed, raw request path. Users are recommended to update any policy usinginput.parsed_pathto instead use theinput.attributes.request.http.pathfield.Example
References