pwneglyph logo
web php path-traversal double-encoding fragment suffix-bypass

Use %2523 so a second decode produces a

Forced Suffix Bypass via Double-Encoded Fragment

Different decode stages disagree on when %23 becomes #. If the application appends .txt before the final decode or navigation semantics kick in, the fragment cuts off the forced suffix.

Why It Works

  • A single decode turns %23 into # too early; %2523 decodes to %23 first, then to # only after .txt is appended — cutting the suffix at the fragment.

Vulnerable Pattern

  • Read endpoints that append a fixed extension, then decode or redirect, or that pass the resulting path through a browser-relevant URL layer.

Exploit Flow

  1. Test whether one decode or two decodes occur between your input and the sink.
  2. If single-encoded %23 is too early or too late, try %2523 so the second decode creates the fragment only after .txt is added.

Variations

  • %23, %2523, mixed traversal plus fragment, or alternate separators if the sink is a non-browser URL parser.

Common Blockers

  • Server-side file reads that don't treat # specially, or path canonicalization before the fragment reaches a URL-aware layer.

PoC Sketch

?file=/tmp/sess_cnf%2523
# second decode turns it into a fragment cut-off before .txt

Good Situations To Use It

  • A read endpoint force-appends an extension you need to drop.
  • Two decode stages exist between input and sink.
  • The path eventually hits a URL-aware (fragment-honoring) layer.

Sources

  • fcsc2026/web/shellfish_say