Skip to content

Fix Open Redirect (L5/6/7/9/10), IDOR (L1-4), JWT (L1) - #218

Closed
beanbeah wants to merge 1 commit into
OWASP-CTF:dc34-ctffrom
beanbeah:ctf/r2-batch-05
Closed

beanbeah wants to merge 1 commit into
OWASP-CTF:dc34-ctffrom
beanbeah:ctf/r2-batch-05

Conversation

@beanbeah

@beanbeah beanbeah commented Aug 9, 2026

Copy link
Copy Markdown

Fixes 10 challenges:

  • Challenge-41/42/43/44/45: Open Redirect LEVEL_5/6/7/9/10 (Http3xxStatusCodeBasedInjection)
    • LEVEL_5/9/10: apply the same-origin allow-list, hardened against control-character and backslash normalization bypasses of the blacklist.
    • LEVEL_6/7: stop fusing the untrusted value directly onto the trusted authority (the old pattern let .evil.com become https://trusted.com.evil.com, an actual evil.com subdomain); the value is now normalized into a same-origin path with exactly one leading slash.
  • Challenge-46/47/48/49: IDOR LEVEL_1-4 (IDORVulnerability)
    • LEVEL_1: requested id is now checked against the id embedded in the caller's signed token instead of trusting any id.
    • LEVEL_2: profile lookup always uses the id from the signed token, ignoring the separate attacker-controllable userId_level2 cookie.
    • LEVEL_3/4: authorization role always comes from the signed token's role claim, ignoring the separate (plaintext/base64) role cookie.
  • Challenge-50: JWT LEVEL_1 (JWTVulnerability)
    • Token to validate is now read from the Authorization header instead of a JWT URL query parameter (credential no longer leaks into logs/history/Referer). Front-end updated to match.

Local verification (WSL, Java 17, Gradle wrapper)

  • compileJava / compileTestJava: BUILD SUCCESSFUL
  • Targeted unit tests (IDORVulnerabilityTest, JWTVulnerabilityTest, Http3xxStatusCodeBasedInjectionTest): BUILD SUCCESSFUL, no failures
  • Booted the app locally (bootRun) and exercised every fixed level over real HTTP requests:
    • IDOR L1-4: cross-user/role-escalation payloads now return "Access Denied", same-user legitimate access still returns the correct profile.
    • JWT L1: old ?JWT= query vector is now ignored; Authorization header path validates correctly and rejects invalid tokens (401).
    • Open Redirect L5/6/7/9/10: backslash/control-char bypasses and domain-suffix-confusion payloads (.evil.com) and bare external domains are all rejected/kept same-origin; legitimate same-origin/relative redirects still 302 correctly.
    • Sanity-checked adjacent unaffected levels (Open Redirect L1-4/8/11, JWT L2) for regressions — none found.

🤖 Generated with Claude Code

…L_1) vulnerabilities

Open Redirect (Http3xxStatusCodeBasedInjection):
- LEVEL_5: harden the blacklist check against bypasses that rely on
  browsers normalizing the URL before navigation - embedded control/
  whitespace characters hiding a leading "//", and backslashes standing
  in for forward slashes.
- LEVEL_6/7: stop concatenating the untrusted value directly onto the
  trusted authority. The old 'authority + value' pattern let a value
  like '.evil.com' produce 'https://trusted.com.evil.com', which is an
  actual subdomain of evil.com, not a path under trusted.com. The value
  is now normalized into a same-origin path with exactly one leading
  slash and '@'/control characters stripped.
- LEVEL_9/10: apply the same same-origin allow-list used for LEVEL_5
  instead of unconditionally trusting the redirect target.

IDOR (IDORVulnerability):
- LEVEL_1: the requested id is now compared against the id embedded in
  the caller's signed token; a mismatch is rejected instead of
  returning any profile requested.
- LEVEL_2: the profile lookup now always uses the id from the signed
  token, ignoring the separate attacker-controllable userId cookie.
- LEVEL_3/4: the authorization role now always comes from the signed
  token's own role claim, ignoring the separate (plaintext / base64)
  role cookie that was previously trusted outright.

JWT (JWTVulnerability):
- LEVEL_1: the token to validate is now read from the Authorization
  header instead of a 'JWT' URL query parameter, so the credential no
  longer leaks into server access logs, browser history, or the
  Referer header of subsequent requests. Updated the LEVEL_1 front-end
  to match.

Verified locally (WSL, Java 17, Gradle wrapper):
- ./gradlew compileJava compileTestJava -> BUILD SUCCESSFUL
- Targeted unit tests (IDORVulnerabilityTest, JWTVulnerabilityTest,
  Http3xxStatusCodeBasedInjectionTest) -> BUILD SUCCESSFUL, no failures
- Booted the app locally and exercised each fixed level over HTTP:
  every original exploit payload is now rejected/ignored while the
  legitimate (same-user / same-origin / header-based) flow still
  returns the expected data, with no regressions on adjacent
  unaffected levels (Open Redirect LEVEL_1-4/8/11, JWT LEVEL_2).
@github-actions

github-actions Bot commented Aug 9, 2026 •

Copy link
Copy Markdown

🏆 VulnerableApp — CTF Patch Score

█░░░░░░░░░░░░░░░░░░░  13 / 187 pts  (7%)

7 / 110 challenges patched

Per-challenge detail is withheld — it would reveal the rubric.

Commit: 90d6547 · scoring run

🎉 Your result is on the leaderboard — see where you rank! 🏆

@beanbeah

beanbeah commented Aug 9, 2026

Copy link
Copy Markdown
Author

Closing as part of a full stand-down of this CTF push.

@beanbeah beanbeah closed this Aug 9, 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.

1 participant