停!
你在这里犯了一个错误。哦,不,你已经选择了正确的PHP函数,使你的数据更安全一些。没关系。您的错误在于操作顺序,以及如何以及在何处使用这些函数。
请务必了解清理和验证用户数据、转义数据以进行存储以及转义数据以进行演示之间的区别。
清理和验证用户数据
当用户提交数据时,您需要确保他们提供了您期望的内容。
消毒和过滤
例如,如果您需要一个数字,请确保提交的数据是一个数字。您还可以将用户数据转换为其他类型。提交的所有内容最初都被视为字符串,因此强制将已知数字数据转换为整数或浮点数会使清理快速而轻松。
自由格式的文本字段和文本区域呢?您需要确保这些字段中没有任何意外。主要是,您需要确保不应包含任何HTML内容的字段实际上不包含HTML。有两种方法可以解决此问题。
首先,您可以尝试使用 htmlspecialchars
转义 HTML 输入。您不应该使用 htmlentities
来中和 HTML,因为它还会对重音符号和其他它认为也需要编码的字符进行编码。
其次,您可以尝试删除任何可能的 HTML。strip_tags
既快捷又简单,但也很草率。HTML Purifier在剥离所有HTML并允许标记和属性的选择性白名单方面做得更彻底。
现代 PHP 版本附带了筛选器扩展,它提供了一种全面的方法来清理用户输入。
验证
确保提交的数据没有意外内容只是工作的一半。您还需要尝试并确保提交的数据包含您可以实际使用的值。
如果您期望一个介于 1 和 10 之间的数字,则需要检查该值。如果您使用带有微调器和步骤的那些新的花哨的HTML5时代数字输入之一,请确保提交的数据与步骤一致。
如果该数据来自应为下拉菜单的值,请确保提交的值是显示在菜单中的值。
满足其他需求的文本输入呢?例如,应通过 strtotime 或 DateTime
类来验证日期输入。给定日期应介于预期的范围之间。电子邮件地址呢?前面提到的过滤器扩展可以检查地址是否格式正确,尽管我是is_email库的粉丝。
对于所有其他窗体控件也是如此。有单选按钮吗?根据列表进行验证。有复选框吗?根据列表进行验证。要上传文件?确保文件属于预期类型,并将文件名视为未过滤的用户数据。
每个现代浏览器都内置了一套完整的开发人员工具,这使得任何人都可以轻松操作您的表单。您的代码应假定用户已完全删除了对表单内容的所有客户端限制!
转义数据以进行存储
现在,您已确保数据采用预期格式且仅包含预期值,接下来需要担心如何将该数据保存到存储中。
每个数据存储机制都有一种特定的方式来确保数据正确转义和编码。如果要生成 SQL,则在查询中传递数据的可接受方法是通过带占位符的预准备语句。
在 PHP 中使用大多数 SQL 数据库的更好方法之一是 PDO 扩展。它遵循准备语句的常见模式,将变量绑定到语句,然后将语句和变量发送到服务器。如果您之前没有使用过PDO,这里有一个非常好的面向MySQL的教程。
一些SQL数据库在PHP中有自己的专业扩展,包括SQL Server,PostgreSQL和SQLite 3。这些扩展中的每一个都具有预准备语句支持,其操作方式与 PDO 相同,即准备-绑定-执行方式。有时,您可能需要使用这些扩展而不是 PDO 来支持非标准功能或行为。
MySQL也有自己的PHP扩展。事实上,其中两个。你只想使用一个名为mysqli的。旧的“mysql”扩展已被弃用,在现代使用起来并不安全或理智。
我个人不是mysqli的粉丝。它对预准备语句执行变量绑定的方式不灵活,使用起来可能很痛苦。如有疑问,请改用 PDO。
如果不使用 SQL 数据库来存储数据,请查看所使用的数据库接口的文档,以确定如何安全地通过该数据库传递数据。
如果可能,请确保数据库以适当的格式存储数据。在数值字段中存储数字。在日期字段中存储日期。将资金存储在十进制字段中,而不是浮点字段。查看数据库提供的有关如何正确存储不同数据类型的文档。
转义数据以进行演示
每次向用户显示数据时,都必须确保数据已安全转义,除非您知道不应转义数据。
在发出 HTML 时,您几乎总是应该传递最初通过 htmlspecialchars
提供的任何数据。事实上,您唯一不应该这样做的情况是,当您知道用户提供了HTML,并且您知道它已经使用白名单对其进行了清理时。
有时你需要使用PHP生成一些Javascript。Javascript没有与HTML相同的转义规则!通过PHP向Javascript提供用户提供的值的一种安全方法是通过json_encode
。
以及更多
数据验证还有更多细微差别。
例如,字符集编码可能是一个巨大的陷阱。您的应用程序应遵循“UTF-8 自始至终”中概述的实践。当您将字符串数据视为错误的字符集时,可能会发生假设攻击。
前面我提到了浏览器调试工具。这些工具还可用于操作 Cookie 数据。Cookie 应被视为不受信任的用户输入。
数据验证和转义只是 Web 应用程序安全性的一个方面。您应该了解Web应用程序攻击方法,以便可以针对它们建立防御措施。