Skip to content

RBAC bypass in nginx Lua layer via percent-encoding, slash-doubling, and case variance #1055

Description

@mmguero

Malcolm's nginx Lua RBAC check (check_rbac in nginx_auth_helpers.lua) matches role-restricted path patterns (/htadmin, /auth, /admin_login, /arkime/api/esadmin, /netbox, /upload, etc.) against the raw, undecoded ngx.var.request_uri. nginx's own location dispatch, however, percent-decodes and normalizes the URI before matching, and the htadmin/admin_login location uses a case-insensitive regex (~*).

Because the RBAC layer's view of the path and nginx's view of the path can disagree, an authenticated low-privilege user can reach a role-restricted location by:

  • percent-encoding a character in the restricted path (e.g. /%68tadmin.php)
  • varying case (e.g. /HTADMIN.php)
  • slash-doubling, if merge_slashes isn't guaranteed on for the relevant location

nginx routes the request to the restricted backend location in all three cases; check_rbac's pattern match fails to recognize the path as restricted and grants access (path_role_envs is fail-open on non-match — line 437).

Verified end-to-end: authenticated as a low-privilege Keycloak user, /htadmin.php correctly returns 403; /%68tadmin.php with the identical session returns 200 with real htadmin backend content, confirmed via the backend's own access log.

Every entry in path_role_envs is affected, not just htadmin — same bypass applies to all role-restricted prefixes.

Fix: normalize_uri_for_rbac() updated to percent-decode, collapse repeated slashes, collapse traversal sequences, and lowercase — in that order — before matching, so the RBAC layer's normalization agrees with nginx's own decode/case-fold behavior. Verified against malformed escapes, encoded traversal, double-encoding, and overlong-UTF-8 edge cases in a live OpenResty shell; no regressions or new fail-open paths introduced.

See GHSA-jr6p-63pg-hr6g

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingnginxRelating to Malcolm's use of nginxsecurityRelated to issues with bearing on the security of Malcolm itself

Type

Fields

Frequency

None yet

Projects

Status
Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions