Fix unescaped regex metacharacters in PATH rule matching causing request failures#3251
Open
kshitijshresth wants to merge 1 commit into
Open
Fix unescaped regex metacharacters in PATH rule matching causing request failures#3251kshitijshresth wants to merge 1 commit into
kshitijshresth wants to merge 1 commit into
Conversation
isValidUrlGlobPattern accepts characters like ( ) [ ] { } | . + ^ $ in PATH rule values, but isPathAllowed converted wildcard segments to regex without escaping them. A rule value such as /(api* produced an invalid regex and threw on every request to the resource, surfacing as a 500 from verifySession. Literal characters like . and + also changed matching semantics. isPathAllowed is extracted to server/lib/pathMatch.ts as a pure module, metacharacters are escaped before wildcard substitution, compiled segment regexes are cached, and the test suite now imports the real implementation instead of a stale copy, with added coverage for special characters.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
By creating this pull request, I grant the project maintainers an unlimited,
perpetual license to use, modify, and redistribute these contributions under any terms they
choose, including both the AGPLv3 and the Fossorial Commercial license terms. I
represent that I have the right to grant this license for all contributed content.
Summary
isPathAllowed(used bycheckRulesinverifySession.tsto evaluate PATH resource rules) converts wildcard pattern segments to regular expressions without escaping regex metacharacters.isValidUrlGlobPatterninvalidators.tsexplicitly permits- . _ ~ ! $ & ' ( ) * + , ; # = @ :in rule values, so rules that pass API validation can produce invalid or semantically wrong regexes at request time.Impact
Unhandled exception on every request. A PATH rule value like
/(api*is accepted by validation, but the matcher buildsnew RegExp("^(api.*$"), which throwsSyntaxError: Invalid regular expression: missing ).checkRuleshas no exception handling, so the error propagates to the catch-all inverifyResourceSessionand every request to that resource fails with500 Failed to verify sessionuntil the rule is deleted.Incorrect matching for literal characters. Since PATH rules commonly gate auth bypass (ACCEPT) or denial (DROP), both directions matter:
*.pngmatchedimageXpng(.acted as regex any-char)a+b*matchedaaabcand failed to matcha+bc(+acted as a quantifier)$ref*could never match anything ($acted as an anchor)Changes
isPathAllowedfromverifySession.tsintopathMatch.tsas a pure module (no logger/config/db imports) so it can be unit tested in isolation;verifySession.tsimports and re-exports it, keeping its public surface unchanged.*→.*and?→.substitutions. The escape set deliberately excludes*and?so wildcard semantics are unchanged.Map. Keys are admin-defined rule pattern segments (a bounded set), not request paths, so the cache cannot grow with traffic. This avoids recompiling regexes on every proxied request, which sits on the hot path.logger.debugcalls (~10 string interpolations per segment comparison, evaluated eagerly on every request regardless of log level) were removed.Tests
verifySession.test.tspreviously tested a stale inline duplicate ofisPathAllowedrather than the real implementation, so regressions in the production code could never fail the suite. It now imports the real function frompathMatch.ts.( ) [ ] { } | \ . + ^ $ |as literals, a no-throw guarantee for all characters accepted byisValidUrlGlobPattern, preserved?single-character wildcard behavior, and a deep-path sanity check.Verified against the unfixed logic first: the new tests fail with
Invalid regular expression: /^(api.*$/: Unterminated group, and pass after the fix.Reproduction (before this fix)
/(api*(accepted by validation).Invalid regular expression: /^(api.*$/: Unterminated groupin logs).