mirror of
https://github.com/element-hq/matrix-authentication-service.git
synced 2026-08-28 14:04:05 +00:00
Handle null values in the policy format_requester helper
A requester with a banned IP but no `User-Agent` header crashed the policy evaluation: the field is serialized as JSON `null` (not omitted), which passes a bare truthiness check and then aborts `sprintf` in the WASM build.
This commit is contained in:
+16
-10
@@ -1,3 +1,4 @@
|
||||
# Copyright 2025, 2026 Element Creations Ltd.
|
||||
# Copyright 2025 New Vector Ltd.
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
@@ -68,22 +69,27 @@ requester_banned(requester, policy) if ip_in_list(requester.ip_address, policy.b
|
||||
|
||||
requester_banned(requester, policy) if matches_string_constraints(requester.user_agent, policy.banned_user_agents)
|
||||
|
||||
# The fields are `null` (not absent) when unknown: a bare `requester.user_agent`
|
||||
# check lets `null` through to `sprintf`, which aborts the WASM evaluation. The
|
||||
# helper rule is undefined for both null and absent values, which `not` handles.
|
||||
requester_has(requester, key) if is_string(requester[key])
|
||||
|
||||
format_requester(requester) := "unknown" if {
|
||||
not requester.ip_address
|
||||
not requester.user_agent
|
||||
not requester_has(requester, "ip_address")
|
||||
not requester_has(requester, "user_agent")
|
||||
}
|
||||
|
||||
format_requester(requester) := sprintf("%s / %s", [requester.ip_address, requester.user_agent]) if {
|
||||
requester.ip_address
|
||||
requester.user_agent
|
||||
requester_has(requester, "ip_address")
|
||||
requester_has(requester, "user_agent")
|
||||
}
|
||||
|
||||
format_requester(requester) := sprintf("%s", [requester.ip_address]) if {
|
||||
requester.ip_address
|
||||
not requester.user_agent
|
||||
format_requester(requester) := requester.ip_address if {
|
||||
requester_has(requester, "ip_address")
|
||||
not requester_has(requester, "user_agent")
|
||||
}
|
||||
|
||||
format_requester(requester) := sprintf("%s", [requester.user_agent]) if {
|
||||
not requester.ip_address
|
||||
requester.user_agent
|
||||
format_requester(requester) := requester.user_agent if {
|
||||
not requester_has(requester, "ip_address")
|
||||
requester_has(requester, "user_agent")
|
||||
}
|
||||
|
||||
@@ -46,4 +46,18 @@ test_requester_banned if {
|
||||
{"ip_address": "192.168.1.1", "user_agent": "Mozilla/5.0"},
|
||||
{"banned_ips": ["192.168.1.1"]},
|
||||
)
|
||||
|
||||
# A missing user agent is serialized as null, not omitted
|
||||
common.requester_banned(
|
||||
{"ip_address": "192.168.1.1", "user_agent": null},
|
||||
{"banned_ips": ["192.168.1.1"]},
|
||||
)
|
||||
}
|
||||
|
||||
test_format_requester if {
|
||||
common.format_requester({"ip_address": "192.168.1.1", "user_agent": "Mozilla/5.0"}) == "192.168.1.1 / Mozilla/5.0"
|
||||
common.format_requester({"ip_address": "192.168.1.1", "user_agent": null}) == "192.168.1.1"
|
||||
common.format_requester({"ip_address": null, "user_agent": "Mozilla/5.0"}) == "Mozilla/5.0"
|
||||
common.format_requester({"ip_address": null, "user_agent": null}) == "unknown"
|
||||
common.format_requester({}) == "unknown"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user