简体   繁体   中英

How does binding values work in PDO and PHP

So ive read a couple of articles on binding and to be honest although i understand the benefits im struggling to see the real value. The benefits are very clear but i cannot get my head around a real world example.

Can someone show me a simple query where a user can input a value then submit it where SQL injection can take place, then show me how binding avoids that. That should make it super clear what is going on.

Im obviously new to PDO making the transition from standard MySql statements.

Also is it correct to assume its only needed where user imput is involved, otherwise we can just skip binding?

Check out my presentation SQL Injection Myths and Fallacies .

Or watch a webinar recording of me presenting it: http://www.percona.com/webinars/2012-07-25-sql-injection-myths-and-fallacies (free, but requires registration).

I show several examples, such as the following:

Suppose you have a page that allows users to change their password, and you intend users to access it using an URL like this:

http: //example.com/changepass.php?acctid=1234 &pass=xyzzy

(Of course, they'd normally use a POST request, but for purposes of simple illustration let's go with this GET format.)

In the script for that page, you have an SQL update statement like this:

UPDATE Accounts 
SET password = SHA2('$password')
WHERE account_id = $account_id

Now what if a malicious user sets the parameters cleverly, like this:

http: //example.com/changepass.php?acctid= 1234 OR TRUE &pass= xyzzy'), admin=('1

Then your SQL would end up running this statement:

UPDATE Accounts SET password = SHA2(' xyzzy'), admin=('1 ')
WHERE account_id = 1234 OR TRUE

Which would set the password but also set another column in the table to grant the user admin privilege. And the injection in the WHERE clause applies the change to all users in your site, not just the user who is logged in.

The value of parameters is: one parameter is always treated as one value in the SQL expression.

That is, even if the string you pass for that parameter happens to contain SQL syntax that exploits injection, using a parameter means that it can't be interpreted as anything other than a single string or numeric value. So it can't terminate the string, or contain parentheses or OR or anything else that would modify the syntax or semantics of your SQL statement.

So by using bound parameters, it's more like this:

UPDATE Accounts SET password = SHA2(' xyzzy\\'), admin=(\\'1 ')
WHERE account_id = ' 1234 OR TRUE '

Where the password may look funny, with spaces and quotes inside it, but it won't change the meaning of your SQL. And the WHERE clause will use the integer value of that string, which will just be 1234.


Re your comment:

I haven't traced every line of the code, but I believe it keeps the SQL statement string separate from the values at every stage of execution. At some point, the SQL is parsed and then is represented in some internal fashion (not human-readable text); then the parameter values are combined into this, but they are forced to be a single syntactic element. The point is, they are combined after the query has been parsed, so there's no way for parameter values to alter the syntax.

One exception: the general query log interpolates values into the original SQL string for purposes of logging the query combined with its parameters on a given execution. But this combined query string is not executed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM