防御mysql注入和跨站点脚本的最佳方法

时间:2009-02-20 10:11:36

标签: php sql security xss

此刻,我应用了“把所有东西扔在墙上,看看有什么方法”来阻止上述问题。以下是我拼凑在一起的功能:

function madSafety($string)
{

$string = mysql_real_escape_string($string);
$string = stripslashes($string);
$string = strip_tags($string);
return $string;

}

但是,我确信有更好的方法可以做到这一点。我正在使用FILTER_ SANITIZE_STRING,这似乎并不完全安全。

我想我在问,你们采用哪种方法,这些方法有多成功?感谢

4 个答案:

答案 0 :(得分:35)

只是做了许多你并不理解的东西,对你没有帮助。您需要了解注入攻击是什么,以及您应该如何以及在何处做什么。

在要点中:

  • Disable magic quotes。他们是一个不充分的解决方案,他们混淆了事情。
  • 永远不要在SQL中直接嵌入字符串。使用绑定参数或转义(使用mysql_real_escape_string)。
  • 从数据库中检索数据时,不要 unescape(例如。stripslashes)。
  • 当你在html中嵌入字符串时(例如,当你echo时),你应该默认转义字符串(使用htmlentities ENT_QUOTES)。
  • 如果需要在html中嵌入html-strings,则必须考虑字符串的来源。如果它不受信任,您应该通过过滤器进行管道传输。 strip_tags理论上你应该使用什么,但它有缺陷;请改用HtmlPurifier

另请参阅:What's the best method for sanitizing user input with PHP?

答案 1 :(得分:10)

反对SQL注入的最好方法是绑定变量,而不是将它们“注入”到字符串中。 http://www.php.net/manual/en/mysqli-stmt.bind-param.php

答案 2 :(得分:3)

不要!使用mysql_real_escape_string足以保护您免受SQL注入,并且在之后您正在执行的<{1}}使您容易受到SQL注入攻击。如果您真的想要它,请将放在之前,如下所示:

stropslashes
如果您正在执行function madSafety($string) { $string = stripslashes($string); $string = strip_tags($string); $string = mysql_real_escape_string($string); return $string; }

stripslashes并没有用。

mysql_real_escape_string可以防止HTML / XML注入,而不是SQL。

需要注意的重要一点是,你应该以不同的方式转义你的字符串 ,具体取决于你对它的中级用法。

当您执行MYSQL请求时,请使用strip_tags。输出网页时,请使用mysql_real_escape_string。要构建网络链接,请使用htmlentities ...

正如vartec所说,如果你可以通过各种方式使用占位符。

答案 3 :(得分:1)

这个话题太错了!

您不应过滤用户的输入!这是他输入的信息。如果我想要密码,您打算做什么:'"'>s3cr3t<script>alert()</script>

过滤掉字符并给我更改密码,所以我第一次登录时甚至无法成功?这很糟糕。

正确的解决方案是使用预准备语句或mysql_real_escape_string()来避免sql注入并使用上下文感知的字符转义来避免你的html代码混乱。

让我提醒您,网络只是您表示用户输入信息的方式之一。如果有一些桌面软件可以接受这种剥离吗?我希望你的答案是否定的,你会理解为什么这不是正确的方法。

请注意,在不同的上下文中,必须转义不同的字符。例如,如果您需要将用户名作为工具提示显示,则可以使用以下内容:

<span title="{$user->firstName}">{$user->firstName}</span>

但是,如果用户将其名字设置为'"><script>window.document.location.href="http://google.com"</script>,您要做什么?剥去报价?这太错了!考虑在渲染数据时转义引号,而不是在保持数据时,而不是执行此操作!

您应该考虑的另一个上下文是在渲染值本身时。考虑以前使用的html代码,并想象用户的名字就像<textarea>。这会将后面的所有html代码包装到这个textarea元素中,从而分解整个页面。

再一次 - 考虑根据您使用它的上下文来转义数据!

P.S不确定如何对这些负面投票做出反应。人们,你真的在​​读我的回复吗?