OWASP / OWASP/SecurityShepherd

Convert challenge/lesson servlets to try-with-resources (connection-leak cleanup)

Open
#857 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Java
Stars
1.5k
Forks
515
Avg merge
3h 46m
Merged PRs (30d)
1

Description

Summary

Convert the remaining challenge/lesson servlets that still use the raw Database.getChallengeConnection / closeConnection pattern to try-with-resources. ~35 files under src/main/java/servlets/module/challenge/ and src/main/java/servlets/module/lesson/.

This is item 3 of the deferred follow-ups from the #816 connection-pooling work (next-steps comment). Items 1 (Getter/Setter nested TWR — #846, #855) and 2 (ResultSet→DTO — #839) are tracked separately.

Severity / blast radius

Low, and isolated. Each challenge has its own per-schema pool (max=3, minIdle=0), separate from the core pool. So:

  • A leak in one challenge can exhaust only that challenge's 3 connections (knocking that one challenge offline), without threatening the rest of the app.
  • These paths are not exercised by the load-test harness or the IT suite, so they won't surface as test failures until a specific challenge endpoint is hammered (e.g. a real-world ZAP spider).

Suggested approach — batch by challenge family

One PR per family. Same mechanical try-with-resources conversion used for Setter.java in #834 / #846.

Family Files Notes
DirectObject* 5 DOR challenges, share a pool
SessionManagement* 12 Session-handling challenges
SqlInjection* + lesson 12 SQL injection family + SqlInjectionLesson
Misc 6 BrokenCrypto4, CsrfChallenge*, SecurityMisconfigStealTokens, UrlAccess3UserList, ModuleServletTemplate
Watch out for: Argon2-while-holding-connection

Some SessionManagement* paths run Argon2 hashes while holding a connection. Those need the same auth-hold-time split that #819 applied to authUser and #834 applied to Setter.updatePassword. Look for Argon2Factory.create() calls between the Connection borrow and the SQL execution.

Validation

A ChallengeCorePoolLeakIT (mirroring GetterCorePoolLeakIT / SetterCorePoolLeakIT) per family would prove each batch's blast radius. Use ConnectionPool.getChallengeActiveConnections(poolKey) if it exists, or add a similar helper. The tests/load/load-test.py harness is the gold standard for connection-leak verification.

Acceptance criteria

  • All challenge/lesson servlets under servlets/module/challenge/ and servlets/module/lesson/ use try-with-resources for Connection + statements + result-sets (no raw closeConnection in finally).
  • Argon2-hold paths split so connections aren't held across hashing.
  • Per-family leak IT (or load-test run) proves no challenge-pool exhaustion.
  • No behavior change to challenge functionality (challenges remain solvable, including intentionally-vulnerable behavior).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing Setter.java and the try-with-resources conversions from #834/#846, then inventory the files under src/main/java/servlets/module/challenge/ and src/main/java/servlets/module/lesson/. Check SessionManagement* paths for Argon2Factory calls between connection borrowing and SQL execution. Validate each family with its leak integration test or tests/load/load-test.py, confirming no raw closeConnection usage, no pool exhaustion, and unchanged challenge behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend, databases
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.