什么是最好的PHP输入消毒功能?

我对PHP /编程非常陌生,考虑到这一点,我试图想出一个函数,可以将所有字符串传递给sanatize。 所以来自它的字符串对于数据库插入将是安全的。 但是那里有太多的过滤功能,我不确定我应该使用/需要哪些功能。 请帮我填补空白:

function filterThis($string) {
    $string = mysql_real_escape_string($string);
    $string = htmlentities($string);
    etc...
    return $string;
}

停止!

你在这里犯了一个错误。 哦,不,你已经选择了正确的PHP函数来使你的数据更安全一些。 没关系。 您的错误是按照操作顺序 ,以及如何以及在哪里使用这些功能。

理解清理和验证用户数据,转义数据以供存储以及转义数据进行演示之间的区别很重要。

消毒和验证用户数据

当用户提交数据时,您需要确保他们提供了您期望的内容。

消毒和过滤

例如,如果你期望一个号码,确保提交的数据是一个数字。 您还可以将用户数据转换为其他类型。 所有提交的内容最初都被视为一个字符串,因此将已知数字数据强制为一个整数或浮点数使得消毒过程快速而轻松。

自由形式的文本字段和textareas呢? 你需要确保在这些领域没有任何意外。 主要是,你需要确保不应该有任何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应用程序攻击方法,以便您可以构建针对它们的防御措施。


防止SQL注入的最有效的清理是使用PDO参数化。 使用参数化查询,查询与数据分离,从而消除了一阶SQL注入的威胁。

就删除HTML而言, strip_tags可能是删除HTML的最佳方法,因为它只会删除所有内容。 htmlentities做它听起来像,所以这也适用。 如果您需要解析哪些HTML允许(即您想允许某些标记),则应使用成熟的现有解析器,如HTML Purifier


数据库输入 - 如何防止SQL注入

  • 例如,通过确保实际上是一个整数来确保整数类型的数据是有效的
  • 在非字符串的情况下,您需要确保数据实际上是正确的类型
  • 在字符串的情况下,你需要确保字符串被查询中的引号包围(显然,否则它甚至不能工作)
  • 输入值到数据库中,同时避免SQL注入(mysql_real_escape_string或参数化查询)
  • 从数据库中检索值时,确保避免跨站点脚本攻击,方法是确保HTML无法注入页面(htmlspecialchars)
  • 在插入或更新到数据库之前,您需要转义用户输入。 这是一个更老的方法来做到这一点。 你现在想要使用参数化查询(可能来自PDO类)。

    $mysql['username'] = mysql_real_escape_string($clean['username']);
    $sql = "SELECT * FROM userlist WHERE username = '{$mysql['username']}'";
    $result = mysql_query($sql);
    

    数据库输出 - 如何防止XSS(跨站点脚本)

    仅在从数据库输出数据时使用htmlspecialchars() 。 这同样适用于HTML净化器。 例:

    $html['username'] = htmlspecialchars($clean['username'])
    
  • 如果可以,请购买此书:基本PHP安全性
  • 另请阅读这篇文章:为什么mysql_real_escape_string很重要,有些问题
  • 最后......你要求什么

    我必须指出,如果你使用带有参数化查询的PDO对象(正确的方法),那么确实没有简单的方法来实现这一点。 但是如果你使用旧的'mysql'方式,那么这就是你需要的。

    function filterThis($string) {
        return mysql_real_escape_string($string);
    }
    
    链接地址: http://www.djcxy.com/p/4505.html

    上一篇: What are the best PHP input sanitizing functions?

    下一篇: When are you supposed to use escape instead of encodeURI / encodeURIComponent?