为了安全起见,在获取所有结果时是不是需要绑定结果?
Posted
技术标签:
【中文标题】为了安全起见,在获取所有结果时是不是需要绑定结果?【英文标题】:Do I need to bind result when fetching all results for security?为了安全起见,在获取所有结果时是否需要绑定结果? 【发布时间】:2014-01-20 05:16:43 【问题描述】:我对 mysql 还很陌生,所以如果这听起来像一个愚蠢的问题,我深表歉意。
当我在学习 sql 安全性和防止 sql 注入时,我了解到在获取这样的 id 的结果时最好使用 bindparam:
//Prepare Statement
$stmt = $mysqli->prepare("SELECT * FROM my_table WHERE id=?");
if ( false===$stmt )
die('prepare() failed: ' . htmlspecialchars($mysqli->error));
$rc = $stmt->bind_param("i", $id);
if ( false===$rc )
die('bind_param() failed: ' . htmlspecialchars($stmt->error));
$rc = $stmt->execute();
if ( false===$rc )
die('execute() failed: ' . htmlspecialchars($stmt->error));
// Get the data result from the query. You need to bind results for each column that is called in the prepare statement above
$stmt->bind_result($col1, $col2, $col3, $col4);
/* fetch values and store them to each variables */
while ($stmt->fetch())
$id = $col1;
$abc = $col2;
$def = $col3;
$xyz = $col4;
$stmt->close();
$mysqli->close();
Atm,当我获取所有结果时,我正在使用这个:
$query= "SELECT * FROM my_table";
$result=mysqli_query($connect, $query);
if (!$result)
die('Error fetching results: ' . mysqli_error());
exit();
echo '<table border="1">'; // start a table tag in the HTML
//Storing the results in an Array
while ($row = mysqli_fetch_array($result)) //Creates a loop to loop through results
echo "<tr><td>" . $row['abc'] . "</td><td>" . $row['def'] . "</td><td>" . $row['xyz'] . "</td></tr>";
echo '</table>'; //Close the table in HTML
我的问题是:
1) 对于我的第二个代码,出于类似于我的第一个示例的任何安全原因,在获取所有结果时是否需要使用 bind_result
?
2) 如果是,当我获取所有结果而不使用 $id
时,如何使用带有 bind_result
的准备语句?
3) 如果我以获取所有结果的方式使用第二个示例,是否存在任何安全问题?
你能帮我理解一下吗...
【问题讨论】:
旁注:你有这个与if ( false===$stmt )
不同的方式,应该读作if($stmt===false)
至少......我很确定,除非有什么我不知道(还)。
如果您不与用户交互并且所有输入由您而不是您不必绑定结果。仅当查询本身中有变量时才使用绑定结果。我没有看到示例 2 有任何问题,前提是查询没有任何用户交互
@-Fred -ii 实际上是正确的 1 === 1 无论哪种方式。他的措辞实际上是避免 null 的好习惯
@PiotrKaluza 这是错误的措辞。与用户交互与准备好的语句无关。
我的意思是在查询中有占位符,这将是使用准备好的语句的一个明显情况。其他的则是性能和便利性。我应该更清楚。
【参考方案1】:
1) 对于我的第二个代码,出于与第一个示例类似的任何安全原因,在获取所有结果时是否需要使用 bind_result?
没有。 bind_result()
与安全无关。您可以对任何查询使用您希望的任何方法。
2) 如果是,当我获取所有结果而不使用 $id 时,如何使用带有 bind_result 的 prepare 语句?
与任何其他查询完全相同。实际上没有区别。并且有任何特定的变量根本不重要。
3) 如果我以获取所有结果的方式使用第二个示例,是否存在任何安全问题?
总是存在安全问题。但是在这个 sn-p 中没有来自 SQL 注入领域的内容。您可能希望检查 XSS 问题。
只是为了澄清您的模棱两可的问题:
如果您将bind_result
与bind_param
混淆了,这里有一条经验法则:您必须为要进入查询的每个变量使用占位符(并因此使用bind_param())。总是。没有例外。
根据这条规则,您可以简单地判断在任何特定情况下是否需要使用prepare()
。
另外,在第一个示例中,不需要如此冗长而冗长的代码。
$stmt = $mysqli->prepare("SELECT * FROM my_table WHERE id=?");
$rc = $stmt->bind_param("i", $id);
$rc = $stmt->execute();
$stmt->bind_result($id, $abc, $def, $xyz);
while ($stmt->fetch())
echo $id;
在连接之前将mysqli设置为异常模式:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
【讨论】:
好答案,我想说什么! 非常感谢您的出色回答!现在很有意义!非常感谢! 也感谢您解决有关 xss 问题的可能性。我没有意识到这一点,我已经对此做了记录。 :)以上是关于为了安全起见,在获取所有结果时是不是需要绑定结果?的主要内容,如果未能解决你的问题,请参考以下文章