在 PDO 准备和执行中使用 htmlspecialchars 函数

Using htmlspecialchars function with PDO prepare and execute

使用 htmlspecialchars() 函数使用 PHP PDO 在表单验证和数据库查询中将特殊字符转换为 HTML 实体真的有必要吗?

例如,我有一个带有简单登录系统的网站,大致如下:

$username = (string) htmlspecialchars($_POST['user']);
$password = (string) htmlspecialchars($_POST['pass']);

$query = $dbh->prepare("select id where username = ? and password = ?")
$query->execute($username, $password);

请注意,除了相关函数之外,我还使用了类型转换。那么,有必要吗?或者我可以安全地使用 $username = $_POST['user']; ?

你应该使用 htmlspecialchars 当你有一些纯文本(例如用户输入,或者你之前存储在数据库中并且刚刚用 SELECT 取出的用户输入,或者通过 HTTP 从第三方获取的文本等)并且您想将其插入 到 HTML 文档 中。这可以保护您免受 XSS 攻击。

一般来说,向数据库中插入数据时不应使用它(数据库不是 HTML 文档)。您可能希望稍后以某种非 HTML 形式使用它。

您的困惑很常见,因为书籍和互联网上的信息和示例(包括 php.net)具有误导性或含糊不清。在开发 Web 应用程序时,您可以学到的最重要的事情是 filter input, escape output.

过滤输入 这意味着对于任何数据输入,无论是由用户在表单上提供的还是由来自其他来源的文件提供的,都要过滤掉任何不属于的数据。一个示例是,如果您需要一个数值,请过滤掉任何非数字字符。另一个例子是 limit/ensure 数据的最大长度。但是,您不必为此发疯。例如,如果您希望一行文本可以包含字面上的任意字符组合,那么尝试使用过滤器可能只会让您的用户感到沮丧。

因此,您通常会将输入数据存储在数据库中,并事先提供一些可选的过滤。

转义输出 escape output 的意思是正确保护给定媒体的数据。大多数时候,这种媒体是网页 (html)。但是,它也可以是纯文本、xml、pdf、图像等。对于 html,这意味着使用 htmlspecialchars()htmlentities()(您可以阅读差异here)。对于其他媒体类型,您会 escape/convert 适当(或根本不适当)。

现在,您的问题是您是否应该对将用作 sql 查询参数的输入数据使用 htmlspecialchars()。答案是不。您不应以任何方式修改数据。

是的,$_POST 中包含的数据应被视为危险。这就是为什么你应该 1) 防止 sql 使用准备好的语句和绑定参数进行注入,以及 2) 如果将 $_POST 中的数据放置在 html 中,则正确 escape/convert 数据。

PHP 有许多框架可以为您处理这些细节,我建议您选择并使用一个。但是,如果不这样做,您仍然可以构建安全可靠的应用程序。无论你是否使用框架,我强烈建议你阅读OWASP建议的建议。不这样做只会给您的 Web 应用程序带来安全噩梦。