The Percent That Escaped — Java Bug Hunt

Inspired by the "%2520 in every URL" class of bugs that has hit search engines and CDNs alike — percent signs that aren't themselves encoded turn "50% off"…

  • Language: Java
  • Layer: Backend
  • Difficulty: Medium
  • Concepts: Encoding, URLs
  • Modelled on: URL encoding
  • Visible tests: percent signs are encoded; spaces, ampersands and equals encode; plain text passes through
  • Reward: 50 XP for a complete fix

Briefing

Inspired by the "%2520 in every URL" class of bugs that has hit search engines and CDNs alike — percent signs that aren't themselves encoded turn "50% off" links into broken requests, while everything else was handled.

ParamEncoder.java encodes a query-string value. It forgot the most important character.

Bug report

BUG-2520 · Reported by: SEO (broken deep links in the wild)

encode(raw) — minimal table for our URLs:

  • " " -> %20, "&" -> %26, "=" -> %3D, and "%" itself -> %25 (FIRST!)
  • all other characters pass through

Observed: "50% off" encodes to "50%%20off" — the bare % corrupts the request.

Logs

[crawler] GET /deals?q=50%%20off -> 400 Bad Request

The code as shipped

ParamEncoder.java (editable)

class ParamEncoder {
    static String encode(String raw) {
        return raw
            .replace(" ", "%20")
            .replace("&", "%26")
            .replace("=", "%3D");
    }
}

Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More Java bug hunts.