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.
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.
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 functiongetUserName
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:
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.