still got sql injection hacked using PDO parameterized query

I have inherited an old php based website that keeps getting hacked. Per the information I found here: How can I prevent SQL injection in PHP?, I updated the sql queries using PDO parameterized queries. We got hacked last week again and it looked like a sql injection attack.
All of the usernames were deleted from the user table and replaced with their own information. Then the hackers were able to get into the admin section of the site and create all sorts of havoc.

How could this have happened with a parameterized query?

See my code below - what am I missing? I'm going to change the permissions of my db login used for this query so that only selects are allowed, but I really want to know why the query is vulnerable.

class pdoConnection
{ 
    var $conn;

    function pdoConnection()
    {               
        $this->createConnection();
    }

        function createConnection()
    {
        try
        {
            $dbConnection = new PDO('mysql:host=mysqlhostname.com;dbname=mydbname;charset=utf8', 
                    'dbusername', 'dbpassword',
                    array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));                   
            $dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
            $dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $dbConnection -> exec('SET NAMES utf8');
            $dbConnection -> exec('SET CHARACTER SET utf8');
            $this->conn =$dbConnection;
        }
        catch(PDOException $e)
        {
            die('Could not connect: ' .$e->getMessage(). "<br><br>");
        }

    }

    //  GET CONNECTION
    //  --------------------------------------------------------------------- 
    function getConnection() 
    {   
        return $this->conn;
    } 

} 

$login = htmlspecialchars($_REQUEST['login'], ENT_QUOTES, 'UTF-8');
$pass =  htmlspecialchars($_REQUEST['pass'], ENT_QUOTES, 'UTF-8');

$msg = '';


//check to see if there is a value
if($login == '' || $pass == '') {
    $error = 1;
    $msg = "Please enter a username and password.<br />";

} 
else 
{
    //try to validate

    $clsPDO = new pdoConnection();
    $con = $clsPDO->getConnection();
    $stmt = $con->prepare('SELECT * FROM users where userName = :login');
    $stmt->execute(array(':login' => $login)) or die($con->errorInfo());
    $row = $stmt->fetch();

    if (isset($row))
    {
        if( $pass == $row['userPassword']) {

            $required_login = $row['userName'];
            $required_pass = $row['userPassword'];
            $userLevel = $row['userLevelID'];
            $userName = $row['userName'];
            $userID = $row['userID'];
        }
        else 
        {
            $error = 1;
            $msg = "Your username/password did not match. Please check your entries and try again.";
        }

    }
    else 
    {
        //did not validate
        $error = 1;
        $msg = "Your username/password did not match. Please check your entries and try again.";
    }

}

I have recently surveyed several discussions and tutorials on this topic, and I cannot see any security vulnerabilities in your code. You are turning off emulation, setting the character set to a known-safe one, and properly using the prepared statement. That said, two points come to mind:

  • You could confirm that a true prepared statement is being used on the database server, and not being emulated by PDO. You told it what you wanted, but that's not quite the same as confirming that it happened. Ditto for the character set configuration. Your multiple attempts at setting it properly are evidence that you don't trust the system to listen to you. Which is very understandable, from what I read about the history of the feature.

  • Even if someone finds a vulnerability in the code you posted, that would not seem to be sufficient cause to believe it was exploited in this case. Nor does the absence of people pointing out vulnerabilities mean that the code is safe. So, security would seem to lie in the direction of further forensics, increased logging for "next time", and the consideration of alternative attack vectors.

  • 链接地址: http://www.djcxy.com/p/93462.html

    上一篇: 如何检测坐在反向代理的SQL注入?

    下一篇: 仍然使用PDO参数化查询攻击了SQL注入