正在创建参数以停止sql注入


Creating parameters to stop sql 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合并到我的函数中吗?任何线索都会很棒。

要转换它们,只需在所示函数中执行prepare()bindParam()部分,并在executeQuery()函数中执行类似的execute()部分

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()(如手册所示)

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)想要使用$data_type$length参数(这些是什么?)或b)使用多个execute()语句时,bindParam()的真正威力就来了,例如大容量插入

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