创建参数以停止sql注入

时间:2015-12-06 21:03:12

标签: php sql pdo parameters code-injection

现在我有一个网站,我需要保护基本的SQL注入攻击。该网站非常基础,只是一个登录表单和产品搜索页面。现在我有一个文件,我将保留我在网站上使用的所有功能。以下是几个例子:

function createUser($userName,$userPass){
$query = <<<STR
INSERT INTO Users (userName,userPass,userTypeID)
VALUES ('$userName','$userPass',2)
STR;
return executeQuery($query);
}

function getProductByName($productName){
$query = <<<STR
SELECT productID,productName, productPic,productDesc 
FROM Products
WHERE productName LIKE '%$productName%'
STR;


return executeQuery($query);
}

我想改变这些,以便他们使用预备语句,但我很难理解如何转换它们。我找到了使用bindParam的例子,例如:

$stmt = $dbh->prepare("INSERT INTO Customers (CustomerName,Address,City) 
VALUES (:nam, :add, :cit)");
$stmt->bindParam(':nam', $txtNam);
$stmt->bindParam(':add', $txtAdd)
$stmt->bindParam(':cit', $txtCit);
$stmt->execute();

我能以某种方式将bindparam合并到我的函数中吗?任何线索都会很棒。

1 个答案:

答案 0 :(得分:1)

要转换它们,只需在显示的函数中执行prepare()bindParam()部分,然后执行execute()函数中的executeQuery()

function createUser($userName,$userPass,$dbh) {
    $stmt = $dbh->prepare("INSERT INTO Users (userName, userPass, userTypeID) VALUES (:name, :pass, :id)");
    $stmt->bindParam(':name', $userName);
    //etc
    return executeQuery($stmt);
}

function executeQuery($stmt) {
    $stmt->execute();
}

如果您不想注入$dbh,则可以在功能中使用global $dbh;或类似方法(并且不必更改现有代码库)。

但当然这将是非常重复的,因为您需要编写多个bindParam()语句。假设您正在使用PDO,更简单的方法是将数组传递给execute()as shown in the manual

function createUser($userName,$userPass,$dbh) {
    $stmt = $dbh->prepare("INSERT INTO Users (userName, userPass, userTypeID) VALUES (:name, :pass, :id)");
    $params = array(
        ':name' => $userName,
        //etc
    );
    return executeQuery($stmt, $params);
}

function executeQuery($stmt, $params) {
    $stmt->execute($params);
}

详细说明:当你a)想要使用bindParam()$data_type参数(What are those?)或b)时,$length的真正力量来了正在使用多个execute()语句,例如批量插入

$stmt = $dbh->prepare("INSERT INTO users (name) VALUES (:name)");
$stmt->bindParam(":name", $name);
for (...) {
    $name = ...
    $stmt->execute();
}