Skip to content

fix: close JDBC resources in CSRF, crypto, URL access and misconfiguration challenges (part of #857) - #1016

Open
ismisepaul wants to merge 1 commit into
devfrom
dev#857-misc
Open

ismisepaul wants to merge 1 commit into
devfrom
dev#857-misc

Conversation

@ismisepaul

@ismisepaul ismisepaul commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

⚠️ Manual testing required before merging

The automated tests prove these levels no longer exhaust their connection pools. They don't prove each level can still be solved the intended way, and these are deliberately vulnerable training levels.

Please run this branch, follow the steps, and comment on this PR with the result: pass, or the step that failed and what you saw.

Branch: dev#857-misc

Set up. Use a machine where the Shepherd Docker volumes can be thrown away: down -v deletes their data. JDK 17 and Maven 3.9.2+ are needed.

git fetch origin
git checkout 'dev#857-misc'
mvn -Pdocker clean install -DskipTests
docker compose down -v
docker compose up -d --build
  1. Open https://localhost, accept the self-signed certificate warning, log in as admin / password and set a new password when asked.
  2. On the Get Started page, tick Enable Unsafe Levels and click Open All Levels.
  3. Admin → Module Management → Change Module Layout → Open Floor, then reload the page, so every level is listed on the left.
  4. Admin → Configuration → Cheat Sheet Management → Enable Cheat Sheets for Administrators. With a level open, the Cheat button in the left-hand menu then shows its solution.

Test

  1. Solve each of these with the solution from its Cheat button and check you get the result key: Failure to Restrict URL Access 3, Insecure Cryptographic Storage Challenge 4, CSRF 4, CSRF 7, Security Misconfig Cookie Flag.
  2. In Failure to Restrict URL Access 3, send the user-list request five or more times (from the page, or with a tampered currentPerson cookie in a proxy). It should keep answering.
  3. In CSRF 7, fetch your token list five times. It should keep returning your tokens.

It's broken if: a level's cheat-sheet solution no longer returns the result key; or a level answers An Error Occurred! You must be getting funky!, hangs for about 5 seconds, or mentions Connection is not available after the repeated inputs, and keeps doing so until Tomcat restarts.


Part of #857. With #998, #1004 and #1005, this covers every JDBC lesson and challenge servlet, except those in #919 (DirectObject) and #932 (SqlInjection1, 3, 4, 5).

What

  • UrlAccess3UserList never closed its connection, so every request leaked one. It's also injectable through the currentPerson cookie, so malformed cookies took the level offline after three requests.
  • BrokenCrypto4, CsrfChallengeSevenGetToken, CsrfChallengeSixGetToken, CsrfChallengeTargetFour and SecurityMisconfigStealTokens closed their connection only when no exception was thrown.
  • ModuleServletTemplate, the starting point for new levels, now uses the same pattern too.

The levels are exactly as vulnerable as before

Only resource handling changed. Exception routing is kept exactly:

  • in the CSRF 6/7 token servlets, a failure to get a connection still goes to the outer "funky" catch, and a failed query to error.noToken;
  • SecurityMisconfigStealTokens still logs and rethrows SQLException.

The explicit tokenRs.close() calls are gone because try-with-resources closes the result set. Review with git diff -w origin/dev.

Tests

MiscChallengesPoolLeakIT:

  • 5 malformed UrlAccess3 cookies, then 5 valid requests. On dev this fails ("Request 1 failed: An Error Occurred! You must be getting funky!").
  • 5 calls each to BrokenCrypto4, the CSRF 7 token list (GET, as the browser sends it), and SecurityMisconfigStealTokens' getUserToken / validToken.

All 4 tests pass with this change. Every step of test.yml also passed locally.

Two servlets have no test:

🤖 Generated with Claude Code

…ation challenges (part of #857)

Each challenge schema has its own connection pool of three connections.
UrlAccess3UserList never closed its connection, so the fourth request
waited for the pool timeout and failed until Tomcat was restarted. The
other servlets closed theirs only when no exception was thrown.

Open every Connection, statement and ResultSet in try-with-resources,
and do the same in ModuleServletTemplate so new levels start from the
safe pattern. Only resource handling changes: the queries, messages and
the catch block each exception reaches are the same as before.

MiscChallengesPoolLeakIT calls each servlet five times, five malformed
UrlAccess3UserList cookies included, and checks every well-formed
request still reaches the database.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ismisepaul ismisepaul added this to the 4.0.0 milestone Oct 25, 2026
Copilot AI balanced review requested due to automatic review settings October 25, 2026 04:33
@ismisepaul ismisepaul moved this from Backlog to Next Release Backlog in Security Shepherd Oct 25, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The changes are narrowly scoped resource-lifecycle improvements with regression coverage and no identified blocking defects.

No open issues 🎉

What changed in this PR

This PR advances #857’s JDBC cleanup by closing resources reliably in miscellaneous challenge servlets, preventing challenge-specific connection pool exhaustion while preserving intentionally vulnerable challenge logic.

Changes:

  • Converts connections, statements, and result sets to try-with-resources in six challenge servlets.
  • Updates the module template to demonstrate automatic resource cleanup.
  • Adds integration tests covering repeated requests and recovery after malformed URL-access cookies.
File Description
src/​main/​java/​servlets/​module/​ModuleServletTemplate.java Demonstrates try-with-resources for new modules.
src/​main/​java/​servlets/​module/​challenge/​UrlAccess3UserList.java Closes user-list query resources on success and failure.
src/​main/​java/​servlets/​module/​challenge/​SecurityMisconfigStealTokens.java Closes token lookup and validation resources.
src/​main/​java/​servlets/​module/​challenge/​CsrfChallengeTargetFour.java Closes CSRF token-check resources.
src/​main/​java/​servlets/​module/​challenge/​CsrfChallengeSixGetToken.java Adds automatic cleanup to token retrieval.
src/​main/​java/​servlets/​module/​challenge/​CsrfChallengeSevenGetToken.java Adds automatic cleanup to token enumeration.
src/​main/​java/​servlets/​module/​challenge/​BrokenCrypto4.java Closes coupon-query resources.
src/​it/​java/​servlets/​module/​challenge/​MiscChallengesPoolLeakIT.java Adds repeated-request and pool-exhaustion regression coverage.

Review effort: Balanced

@ismisepaul ismisepaul added the Needs Manual Testing Must be tested by hand from the PR's branch (steps in the PR) before merging label Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Levels Needs Manual Testing Must be tested by hand from the PR's branch (steps in the PR) before merging

Projects

Status: Next Release Backlog

Development

Successfully merging this pull request may close these issues.

2 participants