PHP MySQL $_GET Hack prevention
Possible Duplicate:
Best way to stop SQL Injection in PHP
如果我要使用$u get函数从URL中检索变量,我该如何使其不受黑客攻击?现在我只有加斜杠,我还应该加什么?
1 2
| $variable1 = addslashes($_GET['variable1']);
//www.xxxxx.com/GetTest.php?variable1=xxxx |
- 为了将来参考,这是我在get函数中保护数值的函数(删除floatval();非数值get值的函数):addslashes(mysql_real_escape_string(strip_tags(floatval())));。
第一个也是最重要的规则是任何输入,不仅是$u get,甚至是使用$u post、$u文件以及从磁盘或流中读取的任何内容,都应该始终进行验证。
现在,为了更详细地回答您的问题,您有几个黑客存在于这个世界上。让我给你看一些:
XSS注射剂
如果您接受来自url的数据,例如从$u获取并输出这些数据,而不去掉可能的标记,则可能会使您的站点倾向于XSS注入或代码注入。例如:
1
| http://myhoturl.com/?search=window.location.href="http://thisisahack.com/" |
这将输出一个黑客到您的网站,人们将被重定向到另一个页面。此页面可能是网络钓鱼企图窃取凭据
SQL注入
可以将SQL注入到应用程序中。例如:
1
| http://myhoturl.com/?search=%'; UPDATE users SET password=MD5('hello'); SELECT * FROM users WHERE username LIKE '% |
将使您的SQL如下所示:
1
| SELECT * FROM articles WHERE title LIKE '%%'; UPDATE users SET password =MD5('hello'); SELECT * FROM users WHERE username LIKE '%%'; |
因此,您可以将用户的所有密码更新为hello,然后返回不匹配的内容。
这只是您可以使用SQL注入做什么的简要概述。为了保护您自己,请使用mysql_real_escape_string或pdo或任何好的DB抽象层。
代码注入
很多人喜欢在磁盘上的某个地方包含数据,并允许上载文件。例如:
1 2
| //File igotuploaded.txt
<?php echo 'helloworld'; ?> |
URL允许您按名称包含一个文件。?显示=myhotfile.txt
1 2
| //In this file we include myhotfile.txt
include($_GET['show']); |
那个人把它改成了?show=./上传/igotuploaded.txt,运行echo"hello world";
那是危险的。
经验法则…从不信任用户输入,始终验证、阻止、验证、修复、验证并再次更正…
祝你好运
- 那么,我如何才能让我的PHP脚本忽略通过$u get检索到的SQL查询呢?谢谢所有的例子!
- mysql_real_escape_string,或者如果你使用pdo或者一个好的db层,它通常会为你做…
- "PDO"是什么意思?它代表什么?我如何使用它?我见过很多这样的事!再次感谢您的帮助!
- php.net/manual/fr/book.pdo.php-php数据对象
- "xss"代表跨站点脚本吗?我在另一个用户的回复中看到了这一点。
- 是的,XSS是跨站点脚本
这完全取决于你要用它做什么:
- mysql:mysql_real_escape_string/pdo/mysqli
- html:htmlspecialchars(特殊字符)
- 等。
不知道你将如何处理你的数据,就不可能说出什么会使数据安全。
- 假设我是按照下面的人说的方式使用它(我目前没有一个具体的用途,我只是想学习,所以当我决定以后使用get时,我会安全地使用它……总之,假设:mysql_query("select userid from user where password='.$_get["variable1"]";");
- 密码通常不应从get变量中读取。改为使用Post表单(HTML)中的密码字段。密码应该始终是md5()-安全的。(对于密码,您只需要mysql_real_escape_string();,因为您不会打印出来。
- 好的,太棒了!现在看看用户的个人资料页面,它不是密码,而是一个数字……比如54038。我检索并显示了所有的表条目,其中该用户的编号在一个名为"userid"的字段中,在那里什么类型的注入可能有害,我如何防止它?
- @Albert Renshaw你必须知道你的数据,如果一个字段应该是一个整数,你最好把它转换成一个整数:(int) $_GET['...']。
- 这是很好的建议!是否只有字母数字值?
- 因此,类似于hello的内容会显示为"bcenterhellocenterb",我想我还记得一些关于去掉HTML标记的内容,所以它只会显示为"hello",我该怎么做?
- @阿尔伯特·伦肖,你可能不得不求助于像[\w\d]+这样的正则表达式,但是如果你陷入困境,你最好问一个更具体的问题。
- @艾伯特·伦肖·埃多克斯(Albert Renshaw EDOCX1)(3)
- 为确保正确的密码安全,请务必阅读您可能存储的密码不正确。
- 要在php中过滤,请查看php.net/filter
使用用户输入(任何HTTP请求都算作用户输入)时面临的两个最大风险是:
你应该熟悉风险和防御措施。这些威胁的防御措施各不相同。使用addslashes()不是一个完整的防御。
了解有关安全Web编程的更多信息的一个很好的资源是OWASP十大项目。
我做了一个关于SQL注入神话和谬误的演示,希望对您有所帮助。
- 我注意到在另一个用户的评论中,他们说"XSS注入"代表跨站点脚本注入吗?
- 是的,XSS是跨站点脚本的常用缩写。
读取$获取原始变量并不危险,
危险通常存在于SQL注入中,
例如:
1
| $_GET["variable1"] ="' OR 1=1 --"; |
与查询:
1
| mysql_query("SELECT userid FROM user WHERE password='".$_GET["variable1"]."';"); |
要防止这种情况:
- - 1。mysql_real_escape_string()并不总能阻止注射。这可能让OP想到,如果他只是逃避输入,就不必担心SQL注入。
- mysql_real_escape_string很好!另外,还有什么其他的常见预防方法呢?
- @Albertrenshaw mysql_real_escape_string()只漏掉滴答、引号等。如果没有,那就根本没有帮助。例如,使用LIMIT 10, $page进行分页。如果$page包含1; DROP TABLE tbl --的话,那么转义就没什么用了。始终验证您的输入并确保您具有正确的值(例如,is_numeric和intval)。
- "或1=1——"背后的直觉是什么?我看过之前写在黑客防护文章上的声明(或类似声明)。它通过逻辑产生错误,对吗?这个实习生是否显示带有敏感信息的错误消息?
- 是数字!真的!那太好了!啊,太好了!谢谢你!这对页码之类的东西有很大帮助!甜美!谢谢你!+ 1
- @阿尔伯特伦肖不,它不会出错,它只会返回真的。考虑一个不好的登录系统,SELECT username FROM tbl WHERE username='$user' AND password='$pass'。如果$pass是' OR 1=1 --,那么查询将是SELECT username FROM tbl WHERE username='$user' AND password='' OR 1=1 --',因此返回用户名并引导应用程序相信输入了正确的密码。
- 哦!!!!这更有意义!好吧,这是个很好的建议,所以mysql_real_escape_string()会阻止这种黑客攻击吗?
- 另外,为了将来参考像我这样的笨手笨脚的人。(在Google中找到)如果您试图使用Kristian给出的函数"intval();",并且您有一个数字,但它不是一个整数(例如4.389),则intval将返回4,但如果您希望保留完整的数值,但仍要删除字母和SQL查询等内容,则可以使用"floatval();"
- 不,mysql_real_escape_string()所做的全部工作就是用等替换,这样输入就不能破坏封装。'foo \' bar'不会引起错误,但'foo ' bar'会引起错误。是的,intval只返回4—显然它返回的是整数值,而不是浮点值。:)
- 我没有花时间来详细说明这篇文章,但是看到所有的注释,是的,mysql_real_escape_string()只会阻止一个字符串中的所有SQL注入,对于数值,在执行mysql_query()之前,您应该使用is_numeric()进行验证。