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

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

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


当前回答

即使POST与GET相比没有提供真正的安全优势,对于登录表单或任何其他具有相对敏感信息的表单,请确保您使用POST作为:

post的信息不会保存在用户的历史记录中。 表单中发送的敏感信息(密码等)以后将不会在URL栏中可见(通过使用GET,它将在历史记录和URL栏中可见)。

此外,GET有理论上的数据限制。不。

对于真正敏感的信息,请确保使用SSL (HTTPS)

其他回答

由于通过HTTP POST发送的变量比通过HTTP GET发送的变量更安全,因此没有提供更高的安全性。

HTTP/1.1为我们提供了一系列发送请求的方法:

选项 得到 头 帖子 把 删除 跟踪 连接

让我们假设你有以下HTML文档使用GET:

<html>
<body>
<form action="http://example.com" method="get">
    User: <input type="text" name="username" /><br/>
    Password: <input type="password" name="password" /><br/>
    <input type="hidden" name="extra" value="lolcatz" />
    <input type="submit"/>
</form>
</body>
</html>

你的浏览器会问什么?它问的是:

 GET /?username=swordfish&password=hunter2&extra=lolcatz HTTP/1.1
 Host: example.com
 Connection: keep-alive
 Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/ [...truncated]
 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) [...truncated]
 Accept-Encoding: gzip,deflate,sdch
 Accept-Language: en-US,en;q=0.8
 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

现在让我们假设我们将请求方法更改为POST:

 POST / HTTP/1.1
 Host: example.com
 Connection: keep-alive
 Content-Length: 49
 Cache-Control: max-age=0
 Origin: null
 Content-Type: application/x-www-form-urlencoded
 Accept: application/xml,application/xhtml+xml,text/ [...truncated]
 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; [...truncated]
 Accept-Encoding: gzip,deflate,sdch
 Accept-Language: en-US,en;q=0.8
 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

 username=swordfish&password=hunter2&extra=lolcatz

这两个HTTP请求都是:

不加密的 包括在两个例子中 可以被偷取,并受到MITM攻击。 很容易被第三方复制,和脚本机器人。

许多浏览器不支持POST/GET以外的HTTP方法。

许多浏览器行为存储页面地址,但这并不意味着您可以忽略任何其他问题。

具体来说:

一种天生就比另一种更安全吗?我意识到POST不会暴露URL上的信息,但其中是否有任何真正的价值,或者它只是通过隐匿性来安全?这里的最佳实践是什么?

This is correct, because the software you're using to speak HTTP tends to store the request variables with one method but not another only prevents someone from looking at your browser history or some other naive attack from a 10 year old who thinks they understand h4x0r1ng, or scripts that check your history store. If you have a script that can check your history store, you could just as easily have one that checks your network traffic, so this entire security through obscurity is only providing obscurity to script kiddies and jealous girlfriends.

在https上,POST数据被编码,但url可能被第三方嗅探?

下面是SSL的工作原理。还记得我上面发送的两个请求吗?下面是它们在SSL中的样子: (我将页面更改为https://encrypted.google.com/,因为example.com在SSL上没有响应)。

通过SSL POST

q5XQP%RWCd2u#o/T9oiOyR2_YO?yo/3#tR_G7 2_RO8w?FoaObi)
oXpB_y?oO4q?`2o?O4G5D12Aovo?C@?/P/oOEQC5v?vai /%0Odo
QVw#6eoGXBF_o?/u0_F!_1a0A?Q b%TFyS@Or1SR/O/o/_@5o&_o
9q1/?q$7yOAXOD5sc$H`BECo1w/`4?)f!%geOOF/!/#Of_f&AEI#
yvv/wu_b5?/o d9O?VOVOFHwRO/pO/OSv_/8/9o6b0FGOH61O?ti
/i7b?!_o8u%RS/Doai%/Be/d4$0sv_%YD2_/EOAO/C?vv/%X!T?R
_o_2yoBP)orw7H_yQsXOhoVUo49itare#cA?/c)I7R?YCsg ??c'
(_!(0u)o4eIis/S8Oo8_BDueC?1uUO%ooOI_o8WaoO/ x?B?oO@&
Pw?os9Od!c?/$3bWWeIrd_?( `P_C?7_g5O(ob(go?&/ooRxR'u/
T/yO3dS&??hIOB/?/OI?$oH2_?c_?OsD//0/_s%r

通过SSL

rV/O8ow1pc`?058/8OS_Qy/$7oSsU'qoo#vCbOO`vt?yFo_?EYif)
43`I/WOP_8oH0%3OqP_h/cBO&24?'?o_4`scooPSOVWYSV?H?pV!i
?78cU!_b5h'/b2coWD?/43Tu?153pI/9?R8!_Od"(//O_a#t8x?__
bb3D?05Dh/PrS6_/&5p@V f $)/xvxfgO'q@y&e&S0rB3D/Y_/fO?
_'woRbOV?_!yxSOdwo1G1?8d_p?4fo81VS3sAOvO/Db/br)f4fOxt
_Qs3EO/?2O/TOo_8p82FOt/hO?X_P3o"OVQO_?Ww_dr"'DxHwo//P
oEfGtt/_o)5RgoGqui&AXEq/oXv&//?%/6_?/x_OTgOEE%v (u(?/
t7DX1O8oD?fVObiooi'8)so?o??`o"FyVOByY_ Supo? /'i?Oi"4
tr'9/o_7too7q?c2Pv

(注意:我将HEX转换为ASCII,其中一些显然是不可显示的)

整个HTTP会话都是加密的,通信的唯一可见部分是在TCP/IP层(即IP地址和连接端口信息)。

让我在这里做一个大胆的声明。你的网站并没有通过一种HTTP方法提供比另一种更大的安全性,世界各地的黑客和新手都确切地知道如何做我刚才在这里演示的事情。如果需要安全性,请使用SSL。浏览器倾向于存储历史,RFC2616 9.1.1建议不要使用GET来执行操作,但认为POST提供了安全性是完全错误的。

POST的唯一安全措施是什么?防止嫉妒的前任翻看你的浏览记录。就是这样。全世界的人都登录了你的账户嘲笑你。

为了进一步证明为什么POST不安全,Facebook到处都在使用POST请求,那么像FireSheep这样的软件是如何存在的呢?

Note that you may be attacked with CSRF even if you use HTTPS and your site does not contain XSS vulnerabilities. In short, this attack scenario assumes that the victim (the user of your site or service) is already logged in and has a proper cookie and then the victim's browser is requested to do something with your (supposedly secure) site. If you do not have protection against CSRF the attacker can still execute actions with the victims credentials. The attacker cannot see the server response because it will be transferred to the victim's browser but the damage is usually already done at that point.

免责声明:以下几点仅适用于API调用,不适用于网站url。

网络安全:必须使用HTTPS。在这种情况下,GET和POST同样安全。

浏览器历史记录:对于前端应用程序,如Angular JS, React JS等,API调用是前端进行的AJAX调用。这些不会成为浏览器历史的一部分。因此,POST和GET是同样安全的。

服务器端日志:通过使用写入数据屏蔽和访问日志格式,可以隐藏所有或仅从request-URL中隐藏敏感数据。

浏览器控制台中的数据可见性:对于怀有恶意的人来说,查看POST数据和查看GET数据几乎是一样的。

因此,通过正确的日志记录实践,GET API与POST API一样安全。在所有地方都使用POST,会强制执行糟糕的API定义,应该避免。

GET和POST之间的区别不应该从安全性的角度来看待,而应该从它们对服务器的意图来看待。GET永远不应该改变服务器上的数据——至少除了日志之外——但是POST可以创建新的资源。

好的代理不会缓存POST数据,但它们可能缓存来自URL的GET数据,因此可以说POST应该更安全。但是POST数据仍然可以用于那些性能不佳的代理。

正如在许多答案中提到的,唯一确定的赌注是通过SSL。

但是一定要确保GET方法不会提交任何更改,比如删除数据库行等等。

POST在安全性方面较差的一个原因是GET在默认情况下被记录,参数和所有数据几乎都被你的web服务器记录。

POST则相反,它几乎没有被记录,导致很难发现攻击者的活动。

我不相信“它太大了”的说法,这不是不记录任何东西的理由,至少1KB,这对人们识别攻击者很有帮助,直到它出现,然后POST做了双重破坏服务,通过启用任何基于HTTP的后门来无声地传递无限数量的数据。

正如之前一些人所说,HTTPS带来了安全性。

但是,POST比GET更安全,因为GET可以存储在历史记录中。

但更令人遗憾的是,有时POST或GET的选择并不取决于开发人员。例如,一个超链接总是通过GET发送(除非它使用javascript转换成post表单)。