Skip to content

fix: whitelist safe characters in trailing-slash rewrite to prevent open redirect#2362

Closed
B4nan wants to merge 2 commits intomasterfrom
fix/trailing-slash-backslash-redirect
Closed

fix: whitelist safe characters in trailing-slash rewrite to prevent open redirect#2362
B4nan wants to merge 2 commits intomasterfrom
fix/trailing-slash-backslash-redirect

Conversation

@B4nan
Copy link
Member

@B4nan B4nan commented Mar 23, 2026

Summary

  • Every previous approach to match/detect backslashes failed in production (hex escapes, character classes, map+if, separate location blocks) despite passing CI
  • This takes the opposite approach: whitelist safe URL characters instead of blacklisting backslashes
  • Changes the trailing-slash location regex from ^(.+)/$ to ^(/[a-zA-Z0-9][a-zA-Z0-9_./-]*)/$
  • Only letters, digits, dots, hyphens, underscores, and forward slashes can trigger the redirect
  • Uses only basic regex character ranges — no hex escapes, no backslash escaping, zero ambiguity

Fixes apify/apify-core#26551

🤖 Generated with Claude Code

B4nan and others added 2 commits March 23, 2026 18:32
The [^\\\\] character class in the location regex didn't work in
production due to nginx config backslash escaping differences across
environments.

Use a map directive with \x5c (PCRE hex escape for backslash byte 0x5C)
which is completely unambiguous. The map sets $uri_has_backslash, and
an if+return inside the trailing-slash location block returns 404 when
a backslash is detected - preventing the redirect that would put \ in
the Location header.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previous approaches tried to detect/match the backslash character using
\x5c hex escapes, [^\\\\] character classes, map directives, and if
blocks - all worked in CI but failed in production.

This takes the opposite approach: instead of blacklisting backslashes,
whitelist the safe characters that should appear in documentation URLs.
The trailing-slash location regex changes from ^(.+)/$ to
^(/[a-zA-Z0-9][a-zA-Z0-9_./-]*)/$ so it only matches URIs composed of
letters, digits, dots, hyphens, underscores, and forward slashes.

Uses only basic regex features (character ranges and literals) that work
identically across all PCRE/POSIX ERE versions with zero escaping
ambiguity.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@B4nan
Copy link
Member Author

B4nan commented Mar 24, 2026

Not needed - the \x5c location approach works, previous test failures were due to CloudFront cache.

@B4nan B4nan closed this Mar 24, 2026
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.

2 participants