0

我有一个 php 文件,它在开始时从使用 $_GET 发送的内容中分配一些变量。

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

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

这足以防止攻击吗?

还有什么可以做的?

4

5 回答 5

5

好吧,你mysql_real_escape_string大错特错了。
但这不是你的错——它是 PHP 社会中最邪恶的错觉之一。甚至官方手册页都错了。

此功能与保护任何东西无关,尤其是 GET 变量

该函数只是对字符串分隔符进行转义,使字符串分隔符无法打断字符串。因此,两个最重要的后果:

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

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

您可以从我之前关于类似主题的回答中了解如何保护您的 SQL:在 PHP 中,当向数据库提交字符串时,我应该使用 htmlspecialchars() 还是使用正则表达式来处理非法字符?

更新
一个场景以说明为什么 mysql_real_escape_string 不是灵丹妙药

使用 url
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";

如果不是像小鲍比桌那样华丽,但也会造成同样的灾难性后果。

于 2011-03-02T09:36:19.253 回答
0

mysql_real_escape_string当您在MySQL 字符串声明中使用返回值时,只会保护您免受 SQL 注入,例如:

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

ASC如果您在任何其他上下文中使用它(使用/指定排序顺序DESC、行限制、表/行名称等),它不会保护您。在这种情况下,您需要分别验证/过滤/清理该值。

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

于 2011-03-02T11:25:15.860 回答
0

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

http://www.owasp.org/

于 2011-03-02T09:30:54.180 回答
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

于 2011-03-02T11:05:51.703 回答
-1

如果 get 变量具有使用 isset() 和 empty() 函数的值,你有

于 2011-03-02T09:25:28.913 回答