Skip to content

Fix Challenge-33: enforce admin role check on UrlAccess2Admin (Failure to Restrict URL Access 2) - #343

Closed
beanbeah wants to merge 2 commits into
OWASP-CTF:dc34-ctffrom
beanbeah:ctf/r2-challenge-challenge-33-url-access-2
Closed

beanbeah wants to merge 2 commits into
OWASP-CTF:dc34-ctffrom
beanbeah:ctf/r2-challenge-challenge-33-url-access-2

Conversation

@beanbeah

@beanbeah beanbeah commented Aug 9, 2026

Copy link
Copy Markdown

Vulnerability

UrlAccess2Admin.doPost() (the admin-only function for the "Failure to Restrict URL Access 2" challenge) only called Validate.validateSession(ses), which accepts any authenticated session regardless of role (player or admin). The level's JSP page hides the admin endpoint URL and required parameter inside obfuscated client-side JavaScript, but any logged-in player who reverse engineers that JS can POST directly to the admin servlet and receive the privileged result key without ever holding an admin session.

Fix

Added a Validate.validateAdminSession(ses) gate at the top of doPost(), returning 403 Forbidden before any challenge logic executes when the session's role is not admin. This mirrors the same pattern already applied and CI-verified for the sibling URL Access 1 challenge (UrlAccess1Admin, PR #330).

UrlAccess2.java (the guest-view red herring servlet) needed no change — confirmed against the parity notes for the reference 40/40 PR, which likewise only touches the *Admin.java files for these two challenges.

Testing

Added src/it/java/servlets/module/challenge/UrlAccess2AdminIT.java, a new integration test following the existing repo convention (NoSqlInjection1IT, XxeChallenge1IT) that exercises the real servlet end-to-end against a live MariaDB-backed instance:

  • A regular player session posting the correct hidden adminData parameter to the admin endpoint now gets 403.
  • A real admin session still receives the correct result key (legitimate function unaffected).

Ran via mvn failsafe:integration-test/verify against a disposable local MariaDB container: 2/2 tests passed. (Full docker compose Tomcat/Mongo bring-up was infeasible in this session due to heavy shared-sandbox resource contention from many concurrent sibling build agents, so this lighter-weight path — still real application code, no mocks of the class under test — was used to get genuine local verification before opening this PR.)

🤖 Generated with Claude Code

Failure to Restrict URL Access 2's admin function (UrlAccess2Admin)
only called Validate.validateSession(ses), which accepts any logged
in user (player or admin). Any authenticated player who read the
level's obfuscated client-side JS could discover the hidden admin
endpoint and POST directly to it, receiving the privileged result key
with no admin session required.

Fix: add Validate.validateAdminSession(ses) as a gate at the top of
doPost, returning 403 Forbidden before any challenge logic runs when
the caller's session role is not 'admin'. Mirrors the same fix already
applied and CI-verified for the sibling URL Access 1 challenge
(UrlAccess1Admin, PR #330). UrlAccess2.java (the guest-view red herring
servlet) needs no change, consistent with the working-list's parity
note that the reference 40/40 PR only touches the *Admin.java files
for these two challenges.

Added src/it/java/servlets/module/challenge/UrlAccess2AdminIT.java, a
new integration test (same pattern as the existing NoSqlInjection1IT /
XxeChallenge1IT tests) covering both cases end to end against a real
MariaDB-backed instance of the actual servlet: a plain player session
now gets 403 attempting the admin endpoint, and a real admin session
still receives the correct result key.

Locally verified: ran the new UrlAccess2AdminIT via
mvn failsafe:integration-test/verify against a disposable MariaDB
container (docker-compose bring-up was infeasible in this session due
to heavy shared-WSL-sandbox contention from concurrent sibling agents,
so this is a lighter but still live, real-code verification path).
Both tests passed (2/2): the exploit path (non-admin hitting the admin
servlet) now returns 403, and the legitimate admin flow still returns
the key.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

🏆 Security Shepherd — CTF Patch Score

░░░░░░░░░░░░░░░░░░░░  0 / 79 pts  (0%)

0 / 40 challenges patched

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

Commit: ce9f834 · scoring run

No points yet — this commit didn't solve any challenges, so there's nothing on the leaderboard for it. Patch a vulnerability and push again! 💪

…ormat)

CI's spotless-check failed on the class javadoc's line wrapping. Ran
mvn spotless:apply locally and confirmed mvn spotless:check now passes
clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@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