Sorting by a column the user chooses
A medium Java puzzle in the sql and jdbc mistakes family. One line below contains a real bug. Try to spot it first, then read why it fails and how to fix it.
Highlighted: line 5. Play this one as a puzzle without the answer.
What is wrong
Using a PreparedStatement does not help when user input is concatenated into the statement text. Placeholders can only stand for values, not for column names or keywords, so sortColumn can carry arbitrary SQL, for example a subquery that leaks data.
The fix
How to avoid it next time
Allow-list identifiers and sort directions. Parameters are only for values.
Want the background? Read JDBC and prepared statements in the Java concepts library.
About sql and jdbc mistakes
Building SQL by string concatenation invites injection, and a handful of subtle JDBC habits leak connections, load too much data or commit half a change.
In code review: Search for plus signs inside strings passed to executeQuery, createQuery or createNativeQuery. Parameters belong in placeholders, never in the text.
More puzzles in this family
Frequently asked questions
What is the bug in "Sorting by a column the user chooses"?
Using a PreparedStatement does not help when user input is concatenated into the statement text. Placeholders can only stand for values, not for column names or keywords, so sortColumn can carry arbitrary SQL, for example a subquery that leaks data. The faulty line is line 5: String sql = "select id, name, price from products order by " + sortColumn;
How do I fix it?
Replace it with: Map the input to a fixed set: String col = switch (sortColumn) { case "name" -> "name"; case "price" -> "price"; default -> "id"; };. Allow-list identifiers and sort directions. Parameters are only for values.
How do I catch sql and jdbc mistakes in code review?
Search for plus signs inside strings passed to executeQuery, createQuery or createNativeQuery. Parameters belong in placeholders, never in the text.
Is there a new puzzle every day?
Yes. The daily Spot the Bug puzzle picks one of these snippets for each UTC day, with the difficulty set by the weekday. Your streak is stored only in your browser.