保护此查询免受sql注入的最佳方法是什么? 这个例子只是一个例子,我在互联网上阅读了一些文章,但无法理解参数化查询。任何有用文章的链接都会得到投票,但我认为看到这个例子会对我有所帮助。
$id = $_GET["id"];
$connection = odbc_connect("Driver={SQL Server};Server=SERVERNAME;Database=DATABASE-NAME;", "USERNAME", "PASSWORD");
$query = "SELECT id firstname secondname from user where id = $id";
$result = odbc_exec($connection, $query);
while ($data[] = odbc_fetch_array($result));
odbc_close($connection);
谢谢,
编辑:我没有说明显,但我使用的是SQL Server而不是mysql。 这只是一个例子,它并不总是我正在搜索的数字。 如果答案使用参数化查询会很好,因为很多人建议这样做,并且对于所有查询都是相同的,而不是针对不同类型的用户输入的不同类型的验证。答案 0 :(得分:3)
我认为PDO objects是最好的。
简而言之,这就是你如何使用它们。
$databaseConnection = new PDO('mysql:host='. $host .';dbname=' . $databaseName, $username, $password);
$sqlCommand = 'SELECT foo FROM bar WHERE baz=:baz_value;';
$parameters = array(
':baz_value' => 'some value'
);
$preparedStatement = $databaseConnection->prepare($sqlCommand);
$preparedStatement->execute($parameters);
while($row = $preparedStatement->fetch(PDO::FETCH_ASSOC))
{
echo $row['foo'] . '<br />';
}
您为SELECT条件输入的值将替换为以冒号开头的参数(如:field_value
)。然后在参数中为参数分配值,这些值将单独传递。
在我看来,这是一种更好的处理SQL查询的方法。
参数与查询分开发送到数据库,并防止SQL注入。
答案 1 :(得分:1)
首先,请注意您在查询中使用的变量,尤其是那些来自外部来源的变量,例如$_GET, $_POST, $_COOKIE and $_FILES。要在查询中使用变量,您应该:
mysql数据库的一个简单示例:
$id = $_GET["id"]; // contains: OR 1 = 1
$name = $_GET["name"]; // contains: ' OR '' ='
$query = "SELECT * FROM table WHERE id = " . intval($id) . " AND name = '" . mysql_real_escape_string($name) . "'";
// SELECT * FROM table WHERE id = 0 AND name = '\' OR \'\' =\''
对于其他数据库,转义练习会有所不同。但通常你应该用'
转义''
字符,所以:
$id = $_GET["id"]; // contains: OR 1 = 1
$name = $_GET["name"]; // contains: ' OR '' ='
$query = "SELECT * FROM table WHERE id = " . intval($id) . " AND name = '" . str_replace("'", "''", $name) . "'";
// SELECT * FROM table WHERE id = 0 AND name = ''' OR '''' ='''
话虽如此,也许您可能想切换到PDO。它允许您使用prepared statements,PDO驱动程序可以执行所有转义。
答案 2 :(得分:1)
使用准备好的陈述。首先使用odbc_prepare()函数构建一个语句,然后将参数传递给它并使用odbc_execute()执行它。
这比自己逃避字符串更安全,更容易。
Lewis Bassett关于PDO的建议是好的,但可以使用ODBC编写的语句,而无需切换到PDO。
示例代码,未经测试!
try {
$dbh = new PDO(CONNECTION_DETAILS_GO_HERE);
$query = 'SELECT id firstname secondname from user where id = :id';
$stmt = $dbh->prepare($query);
$stmt->bindParam(':id', $id, PDO::PARAM_STR);
$result = $stmt->execute();
$data = $stmt->fetchAll();
} catch (PDOException $e)
echo 'Problem: ', $e->getMessage;
}
注意:$ e-&gt; getMessage();可能会暴露您不想暴露的内容,因此当您的代码生效时,您可能希望在该行上执行不同的操作。它虽然可用于调试。
编辑:不确定您是否需要PDO或ODBC示例,但两者基本相同。
编辑:如果你对我不以为然,请发表评论并告诉我原因。
答案 3 :(得分:0)
mysql变体附带了一个名为mysql_real_escape_string的方法,该方法适用于所针对的SQL版本。你能做的最好的事情是编写一个方法来逃避Id。重要的是你的转义方法适用于目标数据库。您还可以执行基本类型检查,如is_numeric,数字输入将立即拒绝SQL字符串注入。
参见How to escape strings in SQL Server using PHP? 并按照一些相关链接获取明确的例子