转义用户数据,没有魔术引号

时间:2009-11-27 16:33:09

标签: php mysql post get escaping

我正在研究如何在将数据用于应用程序控制,存储,逻辑等之前正确地转义来自外部世界的数据。

显然,魔术语录指令很快在php 5.3.0+中被弃用,并在php6中删除,对于任何想要升级并进入新语言功能的人来说,这都变得更加紧迫,同时保留了遗留代码(不要我们喜欢它..)。

然而,有一件事我还没有看到过关于理论/最佳实践的讨论,一旦你保护你的数据怎么做 - 例如,存储是否有斜杠?我个人认为保存数据库中的数据是一个不好的举动,但希望听到讨论并最好阅读一些案例研究。

PHP手册中的一些链接仅供参考:

PHP Manual - mysql_real_escape_string

PHP Manual - htmlspecialchars

等等。

任何提示?

5 个答案:

答案 0 :(得分:6)

看看准备好的陈述。我知道在mysql中这非常有效,并且是一种将数据输入数据库的安全形式。它也有一些性能优势。

http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html

如果您有兴趣,我会有更多资源。

希望这就是你要找的,tc。

编辑:

我可以添加的一件事是将过滤器与预处理语句结合使用。例如,要检查值是否为使用FILTER_SANITIZE_STRING,或者使用FILTER_SANITIZE_EMAIL的电子邮件。

这节省了一些代码并且运行良好。您可以随后使用自己的方法检查数据,但可以使用很多过滤器。

答案 1 :(得分:2)

  • 在运行查询时使用正确的数据转义方法 mysql_real_escape_string,准备好的查询等......

  • 将数据存储在数据库中,不加改变

  • 使用正确的输出数据转义方法: htmlspecialchars等。

答案 2 :(得分:2)

对于数据库工作,请检查参数化查询和预准备语句。 PDOmysqli对此有好处。

Htmlspecialchars是在html文档中显示某些文本的正确工具。

而且,正如您提到的php 5.3,您可以访问处理用户数据时必须使用的filter functions

答案 3 :(得分:1)

对于数据库插入,解决方案是使用bind variables

通常,每当你发现自己转义任何东西时(shell命令,db命令块,用户提供的html等参数),它表示你没有使用正确的函数调用(例如,使用{ {1}}当你可以使用多个arg形式的system),或者你的框架有缺陷时。在缺陷框架中工作的标准方法是增强它,以便您可以回到不考虑引用。

考虑逃避的级别和引用的级别可能很有趣,但是如果你真的很喜欢那么在你的业余时间玩Tcl。对于实际工作,你不应该考虑引用,除非你设计一个供其他人使用的库,在这种情况下你应该正确引用并让你的用户不要考虑引用。 (并且你应该非常仔细地记录你做什么和不做什么样的引用)

答案 4 :(得分:0)

这很简单。在将数据插入数据库之前,应将所有传入数据运行mysql_real_escape_string()。例如,如果您知道某些内容需要是一个整数,请在插入之前将其设置为整数,等等。请记住这只是为了停止SQL注入。 XSS和数据验证是不同的。

如果你想要一些电子邮件,你显然需要在将它插入数据库之前验证它。

htmlentities()清理数据,意味着修改数据。我认为您应始终将原始数据存储在数据库中,当您获取该数据时,请选择您希望如何对其进行清理。

我喜欢使用以下函数作为mysql_real_escape_string()函数的“包装器”。

function someFunction( $value )
{
    if ( is_int( $value ) || is_float( $value ) ) {
        return $value;
    }
    return "'" . mysql_real_escape_string( (string) $value ) . "'";
}

如果值是浮点数或整数,则运行mysql_real_escape_string()没有意义。我在将值传递给mysql_real_escape_string()之前将其转换为字符串的原因是因为有时值可能不是字符串。

值不是字符串的示例:

http://localhost/test.php?hello[]=test

在test.php中,你在$ _GET ['hello']上运行mysql_real_escape_string(),希望你好成为一个字符串。好吧,因为人将值设置为数组,它实际上会引起通知,因为你好不是字符串。