38 lines
1.6 KiB
Plaintext
38 lines
1.6 KiB
Plaintext
==== Use prepared statements
|
|
|
|
As a rule of thumb, the best approach to protect against injections is to
|
|
systematically ensure that untrusted data cannot break out of an interpreted
|
|
context.
|
|
|
|
For database queries, prepared statements are a natural mechanism to achieve
|
|
this due to their internal workings. +
|
|
Here is an example with the following query string (Java SE syntax):
|
|
|
|
----
|
|
SELECT * FROM users WHERE user = ? AND pass = ?
|
|
----
|
|
|
|
*Note: Placeholders may take different forms, depending on the library used. For the above example, the question mark symbol '?' was used as a placeholder.*
|
|
|
|
When a prepared statement is used by an application, the database server
|
|
compiles the query logic even before the application passes the literals
|
|
corresponding to the placeholders to the database. +
|
|
Some libraries expose a `prepareStatement` function that explicitly does so,
|
|
and some do not - because they do it transparently.
|
|
|
|
The compiled code that contains the query logic also includes the placeholders:
|
|
they serve as parameters.
|
|
|
|
After compilation, the query logic is frozen and cannot be changed. +
|
|
So when the application passes the literals that replace the placeholders, they
|
|
are not considered application logic by the database.
|
|
|
|
Consequently, the database server prevents the dynamic literals of a prepared
|
|
statement from affecting the underlying query, and thus sanitizes them.
|
|
|
|
On the other hand, the application does not automatically sanitize third-party
|
|
data (for example, user-controlled data) inserted directly into a query. An
|
|
attacker who controls this third-party data can cause the database to execute
|
|
malicious code.
|
|
|