I understand from my recent use of PHP-PDO over the last few months that you can do a PREPARE statement and then run the query. In fact I can see the usefulness of this if I'm going to either SELECT on a complex join, varying the where conditions, a repeated number of times.
Or, similarly, if I was wanting to insert multiple records.
However, if I know I only want to run a statement once, shouldn't I just EXECUTE the query? I'm basically querying the database twice.
It depends if you have any input you need to escape to prevent sql injection.
According to the manual on PDO::quote:
If you are using this function to build SQL statements, you are
strongly recommended to use PDO::prepare() to prepare SQL statements
with bound parameters instead of using PDO::quote() to interpolate
user input into an SQL statement. Prepared statements with bound
parameters are not only more portable, more convenient, immune to SQL
injection, but are often much faster to execute than interpolated
queries, as both the server and client side can cache a compiled form
of the query.
here are the benchmarks: http://jnrbsn.com/2010/06/mysqli-vs-pdo-benchmarks
prepared statements are close to within the margin of error in terms of slowdown and therefore can be considered insignificant for most purposes.
Related
I've used the following sort of code a few times in my current project to clear out some tables. Incase it's not obvious I'm using PDO.
$clearResult = $db->query('TRUNCATE TABLE table_name');
I'm currently going through and updating a few of my earlier scripts to make sure they all make use of prepared statements and are written in a way to reduce (hopefully stop) sql injection.
No, there's no user input in the actual query so there's no risk of injection.
You do have to make sure that a user isn't able to trigger the truncate though, unless they're authorized.
It's not the SQL operation that determines whether or not a prepared statement should be used. To prevent SQL Injection, a prepared statement should be used when any variable is involved in the query where bound parameters are permitted. That is not limited to just user input either, any variable at all should be a bound paremeter, regardless of where it came from.
In your example there are no variables required for the query, and so there is no security benefit of using a prepared statement.
Even if your table_name was coming from user input or a variable, a prepared statement would not be a solution because it is not possible to bind the table name.
Prepared statements would have no effect on your truncate query.
PDO prepared statements are useful when running queries with user input as they allow you to use features such as bound parameters to sanitise user input.
They are also useful for optimising queries that will run multiple times.
You might want to read up a little on prepared statements in the PHP documentation - PHP documentation for prepared statements:
Many of the more mature databases support the concept of prepared
statements. What are they? They can be thought of as a kind of
compiled template for the SQL that an application wants to run, that
can be customized using variable parameters. Prepared statements offer
two major benefits:
The query only needs to be parsed (or prepared) once, but can be
executed multiple times with the same or different parameters. When
the query is prepared, the database will analyze, compile and optimize
its plan for executing the query. For complex queries this process can
take up enough time that it will noticeably slow down an application
if there is a need to repeat the same query many times with different
parameters. By using a prepared statement the application avoids
repeating the analyze/compile/optimize cycle. This means that prepared
statements use fewer resources and thus run faster.
The parameters to
prepared statements don't need to be quoted; the driver automatically
handles this. If an application exclusively uses prepared statements,
the developer can be sure that no SQL injection will occur (however,
if other portions of the query are being built up with unescaped
input, SQL injection is still possible). Prepared statements are so
useful that they are the only feature that PDO will emulate for
drivers that don't support them. This ensures that an application will
be able to use the same data access paradigm regardless of the
capabilities of the database.
If I didn't get it wrong, prepared statements are faster because they are sent only the first time to the RDBMS, and then only the parameters are sent when it needs to be executed.
Should I always use prepared statements when using Doctrine2's DBAL, or only in the bottlenecks? Is there a limit to the amount of prepared statements I can have?
What about Doctrine2's ORM? Does it use normal queries by default, or prepared statements?
Regarding performance, it is hardly ever the case that one script runs a query more than once. So the benefit of having a prepared statement being "faster" is nearly not existing.
The benefit of prepared statements not allowing SQL injections is also not quite correct. Prepared statements have some limitations regarding the possibilities of dynamic queries, and they are not resistant to injection per se. You can do less bad things, but not zero.
Whenever trying to optimize things: Measure. And optimize the right thing first. For example, if you have a slow query, you should first check it's execution plan and see if all indexes are used correctly. Switching from non-prepared to prepared statement will not change very much.
It is recommended to always use prepared (or at least parameterized) statements for all database servers, not just for speed increase, but because it helps prevent SQL injection attacks.
Prepared statments add a significant amount of code...yet I keep hearing mentions to use them...what value is added by going from 1 line of code to about 6? Is this simply to protect against sql injection?
Similar post here.
php.net on prepared statements here
Prepared statements offer excellent protection against SQL injection.
In addition to SQL injection protection, prepared statements offer reduced load on the database server when the same query is to executed multiple times, such as in an INSERT loop. The statement is only compiled once by the RDBMS rather than needing to be compiled each time as it would in a mysql_query() call.
Different APIs require varying amounts of code to execute a prepared statement. I find that PDO can be a little less verbose than MySQLi, if for example your situation permits the use of implicit parameter binding inside the execute() call. This only works, if all your params can be evaluated as strings though.
// PDO implicit binding example:
// Not many lines of code if the situation allows for it
$stmt = $pdo->prepare("SELECT * FROM tbl WHERE col1=? AND col2=? AND col3=?");
$stmt->execute(array($val1, $val2, $val3));
It's not fair to say that prepared statements cause 1 line of code to explode to 6. Actually, to use one you need just 2 lines: one to prepare the statement, and one to bind the parameters. Any other code you write (execute query, bind results, fetch results, etc.) would also be needed even if you didn't use prepared statements.
So in essence we are talking about what one additional line of code buys you. It buys you two things:
Protection against sql injections (which also includes protection against non-malicious malformed queries, e.g. preventing your query from breaking if an injected variable contains a single quote)
Possible performance benefits, if you end up executing the same prepared statement for different injected values.
Point #2 may not always apply, but consider that point #1 also saves you the necessary trouble of manually escaping the values to be injected in your query. This would be additional code (even if you can do it inline on the same line) that you would need to write yourself if not using prepared statements.
As I see things, we can conclude that with prepared statements you end up getting security and possibly performance for free.
Can anybody explain me in plain English what parametrized queries are and how to implement it in PHP for a MySQL database to avoid SQL injection?
The prepared statements and stored procedures section of the PHP manual, whilst it relates specifically to PDO, covers this well when it says:
They can be thought of as a kind of
compiled template for the SQL that an
application wants to run, that can be
customized using variable parameters.
Prepared statements offer two major
benefits:
The query only needs to be parsed (or
prepared) once, but can be executed
multiple times with the same or
different parameters. When the query
is prepared, the database will
analyze, compile and optimize it's
plan for executing the query. For
complex queries this process can take
up enough time that it will noticeably
slow down an application if there is a
need to repeat the same query many
times with different parameters. By
using a prepared statement the
application avoids repeating the
analyze/compile/optimize cycle. This
means that prepared statements use
fewer resources and thus run faster.
The parameters to prepared statements
don't need to be quoted; the driver
automatically handles this. If an
application exclusively uses prepared
statements, the developer can be sure
that no SQL injection will occur
(however, if other portions of the
query are being built up with
unescaped input, SQL injection is
still possible).
If you're after specific example of how to use them, the above linked page also includes code samples.
I wonder if those prepared statements of PDO really increase security, or if they are just a "cheap" text-replace in the query. The point of prepared statements actually is, that whatever gets inserted as parameter, will not be parsed by the DBMS as part of the instructions itself, so a parameter like
"'; DROP TABLE foobar;"
has no effect and does not break the query. Does anyone know this in detail? I thought to use PDO with prepared statements for preventing sql injection. It turns out that they are hard to use (and don't even work, at least on my local machine), so I want to find this out before wasting much more time with PDO ;-)
Creating a prepared statement sends the query-with-wildcards to the server for parsing, and returns a token to call that statement.
A call merely involves sending the data bound to every parameter. This means there will be no parsing of the data (because it's not part of a query string), and that the structure of the query is fixed when the prepared statement is parsed and cannot be altered by injection.
So, yes, a prepared statement definitely increases safety.
It also means you do not have to incur the parsing overhead if you reuse a prepared statement for several requests.
Yes, they increase security. PDO or MySQLi also increases speed versus the regular MYSQL methods in PHP because the data is passed in a more compact form.