Search code examples
phpsqlpdoprepared-statementsql-injection

Proper Order for Prepare Statements to prevent SQL Injection for User Input


I have a web application which accepts user input, in this case having someone enter a username. I am preparing statements to have my system check if there is already an existing username before the administrator automatically creates another user with the same username.

I have been doing a little reading on PDO prepared statements for use in a dynamic web application, but as far as I have seen, no one states the proper order for a prepare statement

Are there any differences in the order of which the values and variables are parsed to the prepare statement from user input?

It would make more sense if the 'prepare' statement will have access to the user entered input (username)

Example 1

Username variables entered second. Seems like Prepare wont know what variables to actually escape, and therefore cant protect from SQL injection

$query = $general->db->prepare('SELECT * FROM users WHERE username = :username');
$username = array('username' => $_POST['addUserName']);
$query->execute($username);
$usernames_exist = $query->fetchAll();

Example 2

Username variables entered first for proper SQL prepare

$username = array('username' => $_POST['addUserName']);
$query = $general->db->prepare('SELECT * FROM users WHERE username = :username');
$query->execute($username);
$usernames_exist = $query->fetchAll();

Can someone please clarify if there is any advantage to which order works first, in order to properly prevent SQL injection


Solution

  • There 2 code snippets are essentially equal in either way.

    but as far as I have seen, no one states the proper order for a prepare statement

    May be that's because order doesn't matter at all?

    It would make more sense if the 'prepare' statement will have access to the user entered input (username)

    It wouldn't. prepare() has nothing to do with user input. And even if you create just ordinal PHP array before calling prepare(), it won't become aware of the user input all of sudden.

    What deals with user input is execute() /bind functions where you pass your user input. Sounds quite logical, eh?

    All you need to know about SQL injection prevention is that every single variable should go into query via placeholder only. As long as you can follow this simple rule, you can consider yourself safe from injection. Any other matter, be it order of operators or number of spaces, affects nothing, as long as your code works as intended.