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.
Related
I have the following code:
public function getDefinitions($wordID) {
$query = $this->dbc->prepare('SELECT * FROM definitions WHERE wordID = ?');
$query->bind_param('i', $wordID);
$query->execute();
// ...
$query->close();
return $result;
}
It would seem that this would recreate the prepared statement for each invocation. That does not seem to take advantage of the full benefit of prepared statements. Especially in the case these prepare statements were stored server side. Is that true?
If so, should I store the prepare statement (in this case as a property) to persist it between invocations. Is there a way to persist the prepared statement between requests? I assume that's essentially a stored procedure?
Currently I am using MySQLi. Please note any API difference if I were using another driver (e.g. PDO).
should I store the prepare statement (in this case as a property) to persist it between invocations.
I wouldn't say you "should". You may, if you foresee a lot of consequent invocations (which you cannot group up to call at once). Either way, you scarcely will be able to notice the real life difference.
Is there a way to persist the prepared statement between requests?
In PHP - no. Prepared statements are connection-based, connection is closed along with request, and persistent connections won't help you either, as mysqli is using designated mechanism to clean connection state before reuse.
Please note any API difference if I were using another driver (e.g. PDO).
PDO has an advantage over mysqli as it can emulate prepared statements, eliminating even such a negligible overhead of two database calls, which makes it more suitable for the real life usage (beside other key benefits).
In a nutshell, the "prepare once-multiple execute" feature of native prepared statements can have noticeable effect only for a huge number of queries, starting from thousands.
You should persist the query if you plan on using it again.
As you are using mysqli prepared statements should always be real prepared statements. (In contradiction to PDO, which emulates queries based on the used driver and might not send an additional database call). The data replacing the placeholders is then sent in a different pack of data.
A nativly-prepared statement takes therefore two trips to the database if only issued once.
Sending this extra action takes time. If you know that you only want to issue the query once, it might in certain circumstances be positive to use traditional queries. (However, this can only be advisable if you are absolutly sure about the potential negative security implications standard queries have in comparison to prepared statements. The added level safety using prepared statements outwights the benefit such a change may have in most cases.)
However, if you want to re-run the query preparing it is the right approach. MySQL is supposed to cache converted statements, so the php-site is the only way of optimizing and reusing.
What you can do is to prevent the additional call to the prepare method and the action it may trigger in the low-level database connector by preserving the statement in the method using a static variable or a property. The impact on most real applications is however arguable.
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.
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.