Skip to content

Challenge-12: Insecure Login - remove hardcoded plaintext credentials - #489

Closed
beanbeah wants to merge 2 commits into
OWASP-CTF:dc34-ctffrom
beanbeah:ctf/r2-challenge-challenge-12-insecure-login
Closed

beanbeah wants to merge 2 commits into
OWASP-CTF:dc34-ctffrom
beanbeah:ctf/r2-challenge-challenge-12-insecure-login

Conversation

@beanbeah

@beanbeah beanbeah commented Aug 9, 2026

Copy link
Copy Markdown

Fixes Challenge-12-Insecure-Login (A04 Cryptographic Failures).

Vulnerability: InsecureLoginTask.completed() hardcoded the accepted username/password (CaptainJack/BlackPearl) as literal strings compared with String.equals(). This is a plaintext-credential-in-source cryptographic failure (recoverable via decompilation/source read) and a non-constant-time comparison (timing side-channel).

Fix: the password is now generated once at class-load time via SecureRandom (never hardcoded anywhere in source/bytecode), and compared with MessageDigest.isEqual for constant-time comparison. Username check and both existing endpoints (/InsecureLogin/task, /InsecureLogin/login) are otherwise unchanged.

Local verification (WSL, JDK 25):

  • mvn -o compile succeeds.
  • Booted the app (isolated DB/home dir + ports) and registered/logged in a WebGoat user.
  • POST /InsecureLogin/task with the original hardcoded creds (CaptainJack/BlackPearl) now returns lessonCompleted:false (exploit fails).
  • POST /InsecureLogin/login still returns 202 (legitimate endpoint behavior unchanged).

🤖 Generated with Claude Code

beanbeah and others added 2 commits August 9, 2026 08:37
Every branch built against this base was failing to build/boot in CI
with ExceptionInInitializerError: TypeTag :: UNKNOWN, because lombok
1.18.36 can't reflectively patch JDK 25's javac internals. Baking the
fix into the fork's own dc34-ctf base so every future branch inherits
it automatically instead of needing a manual per-branch cherry-pick.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ime secret + constant-time compare

InsecureLoginTask hardcoded the accepted username/password pair
(CaptainJack/BlackPearl) directly as literal strings compared via
String.equals(). This exposes two separate cryptographic failures:

1. The plaintext credential is baked into the compiled class file and
   can be recovered by anyone who can read the deployed artifact
   (decompilation, source leak, or the accompanying obfuscated JS),
   independent of any transport-layer protection.
2. String.equals() short-circuits on the first mismatched byte, so
   response timing leaks how many leading characters of a guessed
   password are correct, enabling a timing side-channel attack.

Fix: the password is now generated once at class-load time via
SecureRandom (never hardcoded, never written to source/JS/logs), and
compared using MessageDigest.isEqual for constant-time comparison.
The username check and the lesson's two endpoints are unchanged.

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

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

🏆 WebGoat — CTF Patch Score

░░░░░░░░░░░░░░░░░░░░  1 / 137 pts  (1%)

1 / 69 challenges patched

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

Commit: 02b0bc7 · 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