sqlmysqlspring-bootjdbccrud-repository

How to be sure entered query is a SELECT and not a DDL or DML in JDBC


I have an admin panel where users can run queries. I need to be sure that only SELECT queries can run there. I am using JdbcTemplate's queryForList method jdbcTemplate.queryForList(sql)

Can I be sure that it will only run select and not any DDL or DML command?

I tried running an update query and it returned

Statement.executeQuery() cannot issue statements that do not produce result sets.; nested exception is java.sql.SQLException: Statement.executeQuery() cannot issue statements that do not produce result sets.

It actually give exception just as I wanted but the description did not satisfy me. Is it possible to run a query that produce result set but also add/delete row?


Solution

  • You can't guarantee this. Possibly problematic cases:

    I'm not that familiar with MySQL, so I can't say 100% certain if (all of) my scenarios are correct for MySQL, but this pattern is common enough that I suspect some or all of them apply.

    In other words, things that produce a result set are not necessarily only reading data.

    In addition, some JDBC drivers will actually execute the statement, and then find out it didn't produce a result set and then produce an exception. Depending on whether auto-commit was enabled or not, and how auto-commit is implemented (server-side or driver-side), your statement may already have been executed and maybe even committed!

    If you want to prevent a user from modifying your database you need to use one of the following: