PHP with PDO: Compare santized input (filter_var) with prepared statement data

504 views Asked by At

I am using PDO 'prepared statements' to insert otherwise unsanitized data into a mySQL db. It's my understanding that this is best practice to mitigate sql injection, as it acts as a sanitizing step by itself.

If I redundantly sanitize prior to this step with filter_var I get user input with escaped characters in the db, which of course looks ugly when outputed later.

I am concerned that if I want to later compare user input against the db data, by santizing at that stage I modify the input so that it will no longer match the db data.

Example:

$email = $_POST['email'];

//Insert the user supplied email (and other details) into the db
$sql = 'INSERT INTO author SET
        name = :userName,
        email = :email,
        password = :password';
    $s = $pdo->prepare($sql);
    $s->bindValue(':userName', $userName);
    $s->bindValue(':email', $email);
    $s->bindValue(':password', password_hash($password, PASSWORD_DEFAULT));
    $s->execute();

Then sometime later in the code...

//Call a function that will use the provided email to lookup the username
getUserName($email);

The getUserName function will use prepared statements again to access the database of course. But will php evaluate the $email var inside of the function call? (I'm not 100% clear on when or if variables are interpreted and executed inside of php). If the users email address (or whatever input I'm evaluating) was:

);Header('Location: evilsite.com');exit();@example.com

Would php close that getUserName function off, and execute the header instruction?

So if at this point I instead..

getUserName(filter_var($email, FILTER_SANITIZE_STRING));

..then I feel I have been diligent in sanitizing user input, but I can no longer use it to compare against info in the db because it may have been modified during the sanitizing process.

I used email as an example here, but the same applies to any input.

Ideally I would like to simply sanitize every input I receive, just to be safe and so that I can use these vars with impunity throughout my code. But then I believe I would need to decode the output to make it format correctly, and by doing so I would exposing my users to XSS attacks correct?

Thanks for your advice.

1

There are 1 answers

2
deceze On BEST ANSWER

No, PHP does not work that way. Variable content isn't interpolated into the source code and then the source code isn't reevaluated with the interpolated variable content. It works like this in shell scripts (insert a ton of asterisks and clarifications here), but not in PHP or most other sane programming languages.

getUserName($email);

Here $email contains whatever was assigned to it. It doesn't matter what that is. There is no vulnerability here under any circumstances. This code says call the function getUserName and pass it the value of $email as its first argument. Nothing more, nothing less. It will never be interpreted to mean anything else. There's no need to sanitise that value for this purpose.

The only time values are interpolated into "code" and that code is then being executed is when you very explicitly do so:

eval("getUserName($email)")
$db->query("SELECT * FROM foo WHERE bar = '$email'")

These are both examples of explicitly interpolating strings into strings to create new strings which are then interpreted as code of some form or another. As long as you stay away from such constructs, this particular vulnerability is of little concern.