PHP安全抵制他人

时间:2011-03-02 09:20:09

标签: php mysql sql-injection mysql-real-escape-string

我有一个php文件,在开始时,使用$ _GET分配一些变量。

然后执行一些mysql查询,处理输出,然后回显一些文本和变量。

我在代码中设置的唯一保护是GET上的mysql_real_escape_string

这足以阻止攻击吗?

还能做些什么?

5 个答案:

答案 0 :(得分:5)

好吧,你认为mysql_real_escape_string非常错误 不过这不是你的错 - 这是PHP社会中最令人讨厌的妄想之一。即使是官方手册页也说错了。

此功能与保护任何内容无关,特别是GET变量

这个函数只是转义字符串分隔符,使字符串分隔符无法破坏字符串。因此,2个最重要的后果:

  • 不仅是GET变量,而且用引号括起来的所有变量都应该用mysql_real_escape_string()处理,无论其来源或来源或可能的危险性
  • 它只会对引用的字符串产生影响。将此函数用于查询的任何其他部分,例如LIMIT子句变量是完全没用的。

因此,为了保护您的SQL查询,您必须遵循整套规则,而不仅仅是欺骗“使用mysql_real_escape_string清理您的数据”。

您可以了解如何保护您的SQL免受我之前关于类似主题的回答:In PHP when submitting strings to the database should I take care of illegal characters using htmlspecialchars() or use a regular expression?

<强>更新
一个场景,以显示为什么mysql_real_escape_string不是一个银弹

给予网址
http://www.example.com/news.php?offset=99999+UNION+SELECT+password+FROM+users+--

代码

$offset = mysql_real_escape_string($_GET['offset']);
$sql    = "SELECT title FROM news LIMIT $offset,20";

如果没有那么轻松的话,不会像小小的桌子一样,但在某种程度上也不会带来灾难性的后果。

答案 1 :(得分:0)

不,有很多攻击你可能没有保护。一个例子是CSRF。这是一个很大的领域,所以我建议在Owasp网站上阅读这些内容:

http://www.owasp.org/

答案 2 :(得分:0)

使用它绝对是不够的。当你只考虑sql注入时它甚至不够。当你考虑只对字符串进行sql注入时, 就足够了,但是只要你有一个整数(比如一个id)就会出错:

http://example.com/foo.php?id=10

通过:

$q = "SELECT * FROM foo where id = " + mysql_real_escape_string($_GET['id'])

导致de SQL查询:

SELECT * FROM foo where id = 10

这很容易被利用,例如:

http://example.com/foo.php?id=10%3B%20DROP%20TABLE%20foo

通过:

$q = "SELECT * FROM foo where id = " + mysql_real_escape_string($_GET['id'])

导致de SQL查询:

SELECT * FROM foo where id = 10;DROP TABLE foo

我希望这可以澄清为什么它还不够。

你应该如何解决这个问题?定义允许的输入,并检查输入是否确实是该表单,例如:

if(preg.match("^[0-9]+$",$_GET['id']){
  // your code here
}else{
  // invalid id, throw error
}

但是安全方面(关于SQL注入)的最佳方法是使用预准备语句: http://php.net/manual/en/pdo.prepared-statements.php

答案 3 :(得分:0)

mysql_real_escape_string只会在MySQL string declaration中使用返回值时再次保护您的SQL注入:

'SELECT foo FROM bar WHERE quux="'.mysql_real_escape_string($val).'"'

如果您在任何其他上下文中使用它(指定带有ASC / DESC的排序顺序,行限制,表/行名称等),它将无法保护您。在这种情况下,您需要单独验证/过滤/清理值。

如果用户数据也可以是您要输出的查询结果的一部分,请使用htmlspecialchars替换任何HTML特殊字符。

答案 4 :(得分:-1)

如果get变量使用isset()和empty()函数

,则有