Lion Cipher Lab

Break and fix path-based authorization with parser differentials

Why it matters

Almost every production web system enforces authorization at least partly on the URL path: an ingress rule that says /admin/* requires a role, a WAF signature that blocks /internal, an API gateway route that demands a scope for /v1/billing, an nginx 'location' block with a deny. It is the cheapest control in the building and it is deployed everywhere, which is exactly why it is worth understanding that it rests on an assumption almost nobody checks: that the component making the decision and the component serving the response agree on what the path IS. They usually do not. A URL path is not a…

What you'll learn

Steps in this lab

  1. The bug in one sentence: two parsers, one path
  2. Set up: one folder, two files, nothing to install
  3. Create pathauthz.py -- four normalizers, one gateway, one origin app
  4. Create harness.py -- the rig that starts both processes and counts
  5. Run it once and read the headline
  6. Section [N]: four normalizers, and none of them agree
  7. Section [D]: the decode-ORDER axis -- same resolver, different answer
  8. Section [1]: what each half thinks the path is, before a single packet moves
  9. Section [1b]: the third parser you did not know you had
  10. Section [2]: live, through two processes -- 15 of 19 get in
  11. Section [3]: the half nobody counts -- false blocks and locked-out users
  12. Failure mode (a): allowlist-by-prefix versus the canonical form
  13. Failure mode (b): the check reads the RAW target, the router reads the DECODED path
  14. Failure mode (c): the proxy strips a prefix, so the halves disagree about what the path IS
  15. Failure mode (d): a denylist regex for '..' that one re-encoding defeats
  16. Fix 1: canonicalize exactly once at the edge, and REJECT rather than repair
  17. Fix 2: do not authorize on the path -- authorize on the resolved route, after routing
  18. Judgment: why this fix and not that one, and when not to bother
  19. Find it in your own systems, and what a reviewer looks for

Open the full interactive lab →