Search code examples
phpsqloraclesql-injection

Does oci_bind_by_name prevent SQL injection safely?


I have read the documentation provided by oracle here, where it states that:

Binding is important for Oracle database performance and also as a way to avoid SQL Injection security issues.

How safe is it to use oci_bind_by_name to escape variables? Are there better practices to avoid SQL Injection, or does oci_bind_by_name suffice?

TIA!


Solution

  • Using bound parameters is sufficient in common cases, and good practice for avoiding SQL injection.

    But a parameter in a prepared statement can be used only for a value in an SQL expression. In other words, where you would normally write a quoted string literal, quoted date literal, or a numeric literal. And one parameter == one value (no lists).

    You should use bound parameters for those cases. If you're asking this question because you think you may want to skip using bound parameters if someone answers that they aren't sufficient, then sorry, you're not going to get excused from secure programming practices.

    However, there are other (perhaps less common) cases for which bound parameters don't work. If you need to write a query with a dynamic table name, column name, or other identifier, or a whole expression, or an SQL keyword, then you need another method. These cases must be fixed in the SQL syntax at prepare time, so they cannot be parameterized.

    For example, here's a query with dynamic parts denoted by use of variables, which cannot be parameters:

    $sql = "SELECT * FROM mytable ORDER BY $column_of_users_choice $asc_or_desc";
    

    You should use whitelisting for those cases. In other words, make sure that a string you interpolate into your query as a dynamic table name is actually one of the tables that exists in your database. Make sure that SQL keywords are legitimate keywords.

    Never take user input verbatim and interpolate it into SQL (or any other code that is parsed at runtime, like the argument you feed to eval() or shellexec()). And it's not just user input that can be unsafe content.

    See also my presentation SQL Injection Myths and Fallacies for more explanation.