php 保护他人免受攻击
我有一个 php 文件,它在开始时从使用 $_GET 发送的内容中分配一些变量。
然后它执行一些 mysql 查询,处理输出,然后回显一些文本和变量。
我在代码中设置的唯一保护是 GET 上的 mysql_real_escape_string
。
这足以防止攻击吗?
还可以做什么?
I have a php file which at the start, assigns some variables from what was sent using $_GET.
It then does some mysql queries, processes the output, then echos out some text and variables.
The only protection I have set in the code is mysql_real_escape_string
on the GETs.
Is that enough to prevent attacks?
What else can be done?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
好吧,你对 mysql_real_escape_string 的理解是非常错误的。
但这不是你的错——这是 PHP 社会中最邪恶的错觉之一。甚至官方手册页也把这一切都错了。
此函数与保护任何一般内容和特定的 GET 变量无关
此函数只是转义字符串分隔符,使字符串分隔符无法破坏字符串。因此,有两个最重要的后果:
因此,为了保护您的 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+--
一段代码
将导致即使不像小鲍比表那么浮夸,但在某种程度上也同样是灾难性的。
Well, you take
mysql_real_escape_string
awfully wrong.It's not your fault though - its one of wickedest delusions among PHP society. Even official man page put it all wrong.
This function has nothing to do with securing anything in general and GET variables in particular
This function is merely escaping string delimiters, to make string delimiters unable to break a string. Thus, 2 most important consequences:
mysql_real_escape_string()
, no matter of their source or origin or possible dangerousnessThus, to secure your SQL query, you have to follow whole set of rules, not just deceiving "sanitize your data with mysql_real_escape_string".
You can learn how to protect your SQL from my earlier answer on the similar topic: In PHP when submitting strings to the database should I take care of illegal characters using htmlspecialchars() or use a regular expression?
update
a scenario to show why mysql_real_escape_string is not a silver bullet
being given with url
http://www.example.com/news.php?offset=99999+UNION+SELECT+password+FROM+users+--
a code
Will result if not in not so pompous as little bobby tables' one but in somewhat no less disastrous.
不,有很多攻击您可能无法防御。 CSRF 就是一个例子。这是一个很大的领域,所以我建议在 Owasp 网站上阅读这些内容:
http://www.owasp.org/
No, there are plenty of attacks that you might not have protection for. One example is CSRF. It's a big field, so I recommend reading up on this stuff on the Owasp site:
http://www.owasp.org/
使用这个绝对是不够的。当您只考虑 sql 注入时,这甚至是不够的。当您仅考虑字符串上的 sql 注入时,这就足够了,但是一旦您有一个整数(例如 id),它就会出错:
遍历:
导致 SQL 查询:
这很容易被利用,例如:
遍历:
导致 SQL 查询:
我希望这能澄清为什么它还不够。
你应该如何解决这个问题?定义允许什么输入,并检查输入是否确实是这种形式,例如:
但安全的最佳方法(关于 SQL 注入)是使用准备好的语句:
http://php.net/manual/en/pdo.prepared-statements.php
Using this is definitely not sufficient. It is not even sufficient when you only consider sql injection. It is sufficient when you consider sql injection on strings only, but as soon as you have an integer (say an id) it goes wrong:
Goes through:
Which results in de SQL query:
This is easily exploitable, for instance:
Goes through:
Which results in de SQL query:
I hope this clarifies why it isn't enough.
How you should solve this? Define what input is allowed, and check that the input is indeed of that form, for instance:
But the best way to be on the safe side (regarding SQL Injection) is using prepared statements:
http://php.net/manual/en/pdo.prepared-statements.php
mysql_real_escape_string
仅当您在 MySQL 字符串声明 就像:如果你在任何其他上下文中使用它(使用
ASC
/DESC
指定排序顺序、行限制、表/行名称等)。在这种情况下,您需要单独验证/过滤/清理该值。如果用户数据也可以是您要输出的查询结果的一部分,请使用
htmlspecialchars
替换任何 HTML 特殊字符。mysql_real_escape_string
will only protect you agains SQL Injections when you use the return value in a MySQL string declaration like:It won’t protect you if you use it in any other context (specifying the sorting order with
ASC
/DESC
, row limits, table/row names, etc.). In that case you’ll need to validate/filter/sanitize the value separately.And if the user data can also be part of the query result that you are about to output, use
htmlspecialchars
to replace any HTML special character.如果使用 isset() 和 empty() 函数获取变量有值,则有
you have if the get variables have values using the isset() and empty() functions