我有一个php文件,在开始时,使用$ _GET分配一些变量。
然后执行一些mysql查询,处理输出,然后回显一些文本和变量。
我在代码中设置的唯一保护是GET上的mysql_real_escape_string
。
这足以阻止攻击吗?
还能做些什么?
答案 0 :(得分:5)
好吧,你认为mysql_real_escape_string
非常错误
不过这不是你的错 - 这是PHP社会中最令人讨厌的妄想之一。即使是官方手册页也说错了。
此功能与保护任何内容无关,特别是GET变量
这个函数只是转义字符串分隔符,使字符串分隔符无法破坏字符串。因此,2个最重要的后果:
mysql_real_escape_string()
处理,无论其来源或来源或可能的危险性因此,为了保护您的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网站上阅读这些内容:
答案 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()函数
,则有