Skip to content

fix(unanchored_regex): flag any unanchored location regex, not just file extensions#65

Merged
MegaManSec merged 2 commits into
masterfrom
fix/unanchored_regex-generalize
Jun 9, 2026
Merged

fix(unanchored_regex): flag any unanchored location regex, not just file extensions#65
MegaManSec merged 2 commits into
masterfrom
fix/unanchored_regex-generalize

Conversation

@MegaManSec

Copy link
Copy Markdown
Owner

needs_tail_anchor() only fired when the regex source literally ended with an escaped file extension (.php style), so plain unanchored patterns like 'location ~ /v1/' — the doc's own bad example — and half-anchored alternations like '^/foo|/bar' were never reported.

Replace it with needs_anchor(): walk the parsed regex tree and require every top-level alternative to be pinned at the start (^ / \A) or the end ($ / \Z). Groups, nested branches, and min>=1 repeats are traversed; PCRE's \z (unknown to the vendored parser) is recognized on the source. Severity stays LOW.

…ile extensions

needs_tail_anchor() only fired when the regex source literally ended
with an escaped file extension (\.php style), so plain unanchored
patterns like 'location ~ /v1/' — the doc's own bad example — and
half-anchored alternations like '^/foo|/bar' were never reported.

Replace it with needs_anchor(): walk the parsed regex tree and require
every top-level alternative to be pinned at the start (^ / \A) or the
end ($ / \Z). Groups, nested branches, and min>=1 repeats are
traversed; PCRE's \z (unknown to the vendored parser) is recognized on
the source. Severity stays LOW.
…d leading assertions; move helpers up

- Normalize unescaped \z to \Z before parsing instead of only honoring a
  trailing \z on the raw source, so '/x|/y\z' no longer hides the
  unanchored first alternative.
- Unwrap a group spanning the whole pattern in _is_anchored so
  '(^a|b$)' is accepted like its unwrapped equivalent.
- Skip zero-width lookarounds when probing the pattern edges so
  '(?!/admin)^/v1' counts as anchored (and 'foo$(?!bar)' too).
- Move the anchor-walk helpers next to the file's other module-level
  helpers instead of trailing the Regexp class.
@MegaManSec
MegaManSec merged commit da5a9fa into master Jun 9, 2026
24 checks passed
@MegaManSec
MegaManSec deleted the fix/unanchored_regex-generalize branch June 9, 2026 23:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant