Search code examples
mysqlisql-injection

Prepared statement security while fetching


I just don't get it. How is a prepared statement more safe than a non-prepared statement for fetching data. I am not talking about writing to the database, only fetching data. I cant see how userFname and userLname is any more safe than userEmail and userPassword. Thanks in advance.

$stmt = $mysqli->stmt_init();
    if ($stmt->prepare("SELECT userFname, userLname FROM users WHERE userEmail = ? and userPassword = ?")) {
        $stmt->bind_param("ss", $userEmail, $userPassword);
        $stmt->execute();
        $stmt->bind_result($userFname, $userLname);
        while ($stmt->fetch()) {
            //Remember first name, last name, and email
            $_SESSION['Email']=$userEmail;
            $_SESSION['Fname']=$userFname;
            $_SESSION['Lname']=$userLname;
            $stmt->close();
            //go to dashboard page
            header ("location: dashboard.php");    
        }
        $error2="Email and Password do not match, please try again."; 
    }

Solution

  • There is one huge Babylonian Tower in the field of SQL injection.

    Everybody's using a dozen of words, hardly understood their meaning and - worse of that - having their own idea on the meaning at all.

    Example: 99% of PHP users will tell you that data have to be "escaped". While technically escaping is a very special action, insufficient for the protection in one case while useless and harmful in another.

    The same goes for every other word from the list of "sanitizing", "filtering", "escaping", "prepared statements" and the like.

    Thus, figuratively speaking, every conversation turns to a dispute between the blind and the deaf.

    Exactly the same goes for the thing called "input input". It's another a source of many confusions and - worse of that - vulnerabilities. While, in its most obvious meaning, it has absolutely nothing to do with SQL injection at all.

    So, reading recommendations from various sites keep in mind that you have to understand the terminology and - more than that - understand what the author meant.

    Back to your question, the answer is fairly simple:

    1. Prepared statements have to be used for the everything that moves into query dynamically.
    2. For the case where prepared statements cannot be used, whitelisting have to be used instead.

    These rules are fairly simple to memorize. So - do not add any complexity in them! Do not bother your self with questions like "Where did this data come from?" "In what query it goes?" - they are of no use and error prone.

    To follow these rules is not that easy, but that's another topic.