当比较HTTP GET和HTTP POST时,从安全角度看有什么不同?其中一个选择是否天生就比另一个更安全?如果有,为什么?

我意识到POST没有公开URL上的信息,但其中有任何真正的价值吗?或者它只是通过隐匿性来实现安全?当安全性是一个问题时,我是否有理由更喜欢POST ?

编辑: 通过HTTPS, POST数据被编码,但url会被第三方嗅探吗?此外,我正在处理JSP;当使用JSP或类似的框架时,是否可以公平地说,最佳实践是避免将敏感数据完全放在POST或GET中,而是使用服务器端代码来处理敏感信息?


当前回答

甚至POST也接受GET请求。假设您有一个表单,其中有user.name和user这样的输入。Passwd,这些应该支持用户名和密码。如果我们简单地添加?user.name="my user&user. name="Passwd =“我的密码”,则请求将通过“绕过登录页面”被接受。

对此的解决方案是在服务器端实现过滤器(java过滤器作为e),并检测到没有字符串查询作为GET参数传递。

其他回答

这是一篇旧文章,但我想反对其中的一些答案。如果要传输敏感数据,则需要使用SSL。如果您使用带有GET参数的SSL(例如?userid=123),该数据将以纯文本形式发送!如果使用POST发送,则将值放在消息的加密正文中,因此大多数MITM攻击都无法读取。

最大的区别在于数据传递的位置。如果数据放在URL中,就不能加密,否则就无法路由到服务器,因为只有你可以读取URL。这就是GET的工作方式。

简而言之,您可以在POST中通过SSL安全地传输数据,但您不能使用GET,无论是否使用SSL。

就安全性而言,它们本质上是相同的。虽然POST确实不通过URL公开信息,但它在客户机和服务器之间的实际网络通信中公开的信息与GET一样多。如果需要传递敏感信息,那么第一道防线就是使用Secure HTTP传递。

GET或查询字符串帖子对于标记特定项目或协助搜索引擎优化和索引项目所需的信息非常有用。

POST适用于用于提交一次性数据的标准表单。我不会使用GET来发布实际的表单,除非在搜索表单中,您希望允许用户将查询保存在书签中,或者类似的东西。

没有额外的安全性。

Post数据不会显示在历史和/或日志文件中,但如果数据应该保持安全,则需要SSL。 否则,任何嗅探线路的人都可以读取数据。

甚至POST也接受GET请求。假设您有一个表单,其中有user.name和user这样的输入。Passwd,这些应该支持用户名和密码。如果我们简单地添加?user.name="my user&user. name="Passwd =“我的密码”,则请求将通过“绕过登录页面”被接受。

对此的解决方案是在服务器端实现过滤器(java过滤器作为e),并检测到没有字符串查询作为GET参数传递。

GET请求的安全性略低于POST请求。两者本身都不能提供真正的“安全”;使用POST请求并不能神奇地使你的网站免受恶意攻击。但是,使用GET请求会使原本安全的应用程序变得不安全。

“不能使用GET请求进行更改”的咒语仍然非常有效,但这与恶意行为没有多大关系。登录表单对于使用错误的请求类型发送最为敏感。

搜索蜘蛛和网络加速器

这就是应该使用POST请求来更改数据的真正原因。搜索蜘蛛会跟踪你网站上的每个链接,但不会提交他们找到的随机表单。

Web加速器比搜索蜘蛛更糟糕,因为它们运行在客户端机器上,并且“点击”登录用户上下文中的所有链接。因此,使用GET请求删除内容的应用程序,即使它需要管理员,也会很高兴地服从(非恶意的!)web加速器的命令,删除它看到的所有内容。

混淆副攻

不管使用GET请求还是POST请求,都可能出现混淆代理攻击(代理是浏览器)。

在攻击者控制的网站上,GET和POST同样容易提交,无需用户交互。

POST不太容易受到影响的唯一情况是,许多不受攻击者控制的网站(比如第三方论坛)允许嵌入任意图像(允许攻击者注入任意GET请求),但阻止所有方式注入任意POST请求,无论是自动还是手动。

有人可能会说,网络加速器是混淆代理攻击的一个例子,但这只是一个定义的问题。如果有的话,恶意攻击者无法控制这一点,所以即使副手感到困惑,这也很难说是攻击。

代理日志

代理服务器可能会完整地记录GET url,而不剥离查询字符串。POST请求参数通常不会被记录。在这两种情况下,cookie都不太可能被记录。(例子)

这是支持POST的一个非常薄弱的论点。首先,未加密的流量可以被完整地记录;恶意代理已经拥有了它所需要的一切。其次,请求参数对攻击者的用处有限:他们真正需要的是cookie,所以如果他们唯一拥有的是代理日志,他们就不太可能攻击GET或POST URL。

登录请求有一个例外:这些请求往往包含用户的密码。将此保存在代理日志中会打开一个在POST情况下不存在的攻击向量。然而,通过纯HTTP登录本身就是不安全的。

代理缓存

缓存代理可能会保留GET响应,但不会保留POST响应。话虽如此,GET响应可以变得不可缓存,而不是将URL转换为POST处理程序。

HTTP“推荐人”

如果用户从响应GET请求的页面导航到第三方网站,该第三方网站将看到所有GET请求参数。

属于“向第三方透露请求参数”的类别,其严重性取决于这些参数中包含的内容。POST请求自然不受此影响,但是要利用GET请求,黑客需要在服务器的响应中插入到他们自己网站的链接。

浏览器历史记录

这与“代理日志”参数非常相似:GET请求连同它们的参数一起存储在浏览器历史记录中。如果攻击者有物理访问机器的权限,他们可以很容易地获得这些信息。

浏览器刷新动作

一旦用户点击“刷新”,浏览器就会重新尝试GET请求。它可能在关闭后恢复选项卡时这样做。因此,任何行为(比如付款)都会在没有任何警告的情况下重复发生。

浏览器不会在没有警告的情况下重试POST请求。

这是只使用POST请求来更改数据的一个很好的理由,但与恶意行为无关,因此与安全性无关。

那我该怎么办呢?

Use only POST requests to change data, mainly for non-security-related reasons. Use only POST requests for login forms; doing otherwise introduces attack vectors. If your site performs sensitive operations, you really need someone who knows what they’re doing, because this can’t be covered in a single answer. You need to use HTTPS, HSTS, CSP, mitigate SQL injection, script injection (XSS), CSRF, and a gazillion of other things that may be specific to your platform (like the mass assignment vulnerability in various frameworks: ASP.NET MVC, Ruby on Rails, etc.). There is no single thing that will make the difference between "secure" (not exploitable) and "not secure".


通过HTTPS, POST数据被编码,但url会被第三方嗅探吗?

不,他们不能嗅。但url将存储在浏览器历史记录中。

是否可以公平地说,最佳实践是避免将敏感数据完全放在POST或GET中,而是使用服务器端代码来处理敏感信息?

这取决于它有多敏感,或者更具体地说,以何种方式敏感。显然客户会看到它。任何可以实际访问客户端计算机的人都可以看到它。客户端可以在发送回给您时欺骗它。如果这些很重要,那么是的,把敏感数据保存在服务器上,不要让它离开。