Question

What is the recommended method for escaping variables before inserting them into the database in Java?

As I understand, I can use PreparedStatement.setString() to escape the data, but PreparedStatement seems somewhat impractical if I don't plan to run the same query ever again.. Is there a better way to do it without preparing every query?

Was it helpful?

Solution

Yes, use prepared statements for everything.

  1. They're parsed once.

  2. They're immune from SQL injection attacks.

  3. They're a better design because you have to think about your SQL and how it's used.

If you think they're only used once, you aren't looking at the big picture. Some day, your data or your application will change.


Edit.

Why do prepared statements make you think about your SQL?

  • When you assemble a string (or simply execute a literal block of text) you aren't creating a new PreparedStatement object. You're just executing SQL -- it can be done very casually.

  • When you have to create (and save) a PreparedStatement, you have to think just a tiny bit more about encapsulation, allocation of responsibility. The preparation of a statement is a stateful event prior to doing any SQL processing.

The extra work is small, but not insignificant. It's what causes people to start thinking about ORM and a data caching layer, and things like that to optimize their database access.

With Prepared statements, database access is less casual, more intentional.

OTHER TIPS

You should never construct a SQL query yourself using string concatenation. You should never manually escape variables/user data when constructing a SQL query. The actual escaping that is required varies depending on your underlying database, and at some point somebody WILL forget to escape.

The point is this: with prepared statements, it is impossible to create a SQL injectable statement. With custom escaping, it is possible. The choice is obvious.

Preparing a statement isn't that expensive. It's safer than most of the alternatives.

I've heard the argument that PreparedStatement costs a little extra overhead over a plain Statement, and that it should be safe if I'm not concatenating user input into my query. This may be true, but the extra cost isn't that much, and SQL queries change over time. If you start out using a Statement today because you've proven to yourself that your query is injection-proof, you're setting yourself up for failure on the day that a maintenance programmer changes the SQL to accept user input, but doesn't think to change that Statement to a PreparedStatement. My advice is to always use a PreparedStatement to head off trouble before it finds you.

Even better, don't use the JDBC API directly, because it's so error-prone (e.g. failing to properly clean up all resources in all cases). Use a JDBC helper object such as Spring's JdbcOperations interface, which considerably reduces the size and bugginess of your code. If you only use Spring for this one feature, you've still done yourself a massive favour compared to using the JDBC API directly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top