question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Use real binds with PreparedStatements instead of just replacing them in the query string

See original GitHub issue

System information:

  • Windows 10 and Ubuntu 20.04
  • 21.3.3

Connection specification:

  • Oracle Enterprise Database 19
  • Driver name: ojdbc8-19.7.0.0.jar

Describe the problem you’re observing:

While reading the documentation https://dbeaver.com/docs/wiki/SQL-Execution#dynamic-parameter-bindings a developer thinks this results in a proper sql binding using PreparedStatements (https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html). But instead the parameters/binds/variables are just replaced inside the query string (see org.jkiss.dbeaver.model.sql.SQLUtils.fillQueryParameters) and are sent as simple sql without sqlBinding to the database. This means the dynamic binding inside dbeaver is only a “pseudo-binding” on the client side. Most applications today uses sql-binding to increase speed and to prevent SQL injection. For a proper use of sql-bindings the applications uses PreparedStatements. Therefore it would be appropriate to support this too in dbeaver. Otherwise developers never can reproduce the same behaviour like in the applications. SQL Performance optimizations are not really possible within dbeaver without PreparedStatements.

Other database clients like e.g. Oracle SQL Developer uses PreparedStatements.

Steps to reproduce, if exist:

Execute this as SQL script:

@set bind1 = 5

SELECT /* dbeaver */ :bind1 FROM dual;
SELECT /* dbeaver */ :bind1 FROM dual;

@set bind1 = 6

SELECT /* dbeaver */ :bind1 FROM dual;

@set bind1 = 7

SELECT /* dbeaver */ :bind1 FROM dual;

Check the executed SQLs on the oracle database itself:

SELECT sql_id, last_active_time, executions, sql_fulltext 
FROM v$sql
WHERE 1=1
AND upper(sql_fulltext) LIKE upper('%dbeaver%')
AND upper(sql_fulltext) NOT LIKE upper('%v$sql%')
ORDER BY last_active_time asc

This is the result:

SQL_ID       |LAST_ACTIVE_TIME       |EXECUTIONS|SQL_FULLTEXT                    |
-------------+-----------------------+----------+--------------------------------+
19uwd1n192qjd|2022-01-27 10:37:23.000|         2|SELECT /* dbeaver */ 5 FROM dual|
2wqhcq906m43a|2022-01-27 10:37:23.000|         1|SELECT /* dbeaver */ 6 FROM dual|
fcmvh0bnpc9q2|2022-01-27 10:37:24.000|         1|SELECT /* dbeaver */ 7 FROM dual|

And this is the expected result if PreparedStatements would be used:

SQL_ID       |LAST_ACTIVE_TIME       |EXECUTIONS|SQL_FULLTEXT                     |
-------------+-----------------------+----------+---------------------------------+
19uwd1n192qjd|2022-01-27 10:37:23.000|         2|SELECT /* dbeaver */ :1 FROM dual|

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:15
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

10reactions
imotschcommented, Jan 27, 2022

In order to analyze an sql statement in its real form it is not only crucial that it looks like the real one but also that it behaves that way. In particular with regard to OWASP top ten and other database related topics it should be a “must” criteria that dbeaver sends an sql statement containing binds using the bind mechanisms of the driver. Especially since the bind popup dialog pretends to the user as if he would now be entering the valud of the bind variable. Just imagine what happens if a user enters original bind data from a log file that contains malicious bind data…Using binds that security risk is mitigated. But with the current dbeaver plain bind concatenation this is simply a not no well “sql-injection”. Please try to consider closing this sql injection risk as it will at the same time make analysis in dbeaver richer, sound, and integer.

10reactions
schifferlecommented, Jan 27, 2022

Hi, thanks for your fast answer. We know that not all JDBC Drivers supports parameter binding properly. But for the “main” databases used in the real world PreparedStatements are supported.

Without this support in single SQLs it is impossible to reproduce statements from applications which uses PreparedStatements. Oracle and PostgreSQL creates not always the same execution plan for this two statements - it depends on the amount of data and on the gathered histogram of the data:

SELECT * FROM table t1 WHERE t1.row1 = 1; SELECT * FROM table t1 WHERE t1.row1 = :1;

Therefore in dbeaver we can not reproduce the same execution plan like within an application with PreparedStatements. This means dbeaver can not really be useful for performance tuning.

Is there a possibility to enable PreparedStatements in single SQL Query too? Ideas:

  • Add “Execute SQL Statement with binds” additionaly to “Execute SQL Statement (CTRL-Enter)”
  • Add a checkbox in the “SQL Processing / Parameters” like “Use serverside binds for parameters”
Read more comments on GitHub >

github_iconTop Results From Across the Web

Using Prepared Statements - JDBC Basics - Oracle Help Center
This JDBC Java tutorial describes how to use JDBC API to create, insert into, update, and query tables. You will also learn how...
Read more >
When should we use a PreparedStatement instead of a ...
It's simply a Java DESIGN MISTAKE tie "prepared statement" with "parameterized query / bind variables". Databases does have API to accept ...
Read more >
22425: Prepared Statements fail to correctly bind parameters
It looks like the problem is prepared statement parameter replacements, 'cause strings used with java.sql.Statement objects seem to work.
Read more >
SQL Bind Variables/Parameters in Databases
It saves effort in rebuilding the execution plan but works only if the SQL ... When using bind parameters you do not write...
Read more >
Prepared statements - DataStax Java Driver
Use PreparedStatement for queries that are executed multiple times in your ... When you bind and execute a prepared statement, the driver will...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found