GET或POST比另一个更安全吗?

将HTTP GET与HTTP POST进行比较时,从安全angular度来看有什么区别? 其中一个select本质上比另一个更安全吗? 如果是这样,为什么?

我意识到,POST不公开URL上的信息,但有没有真正的价值呢,还是只是安全通过默默无闻? 是否有一个理由,当安全是一个问题时,我应该更喜欢POST?

编辑:
通过HTTPS,POST数据被编码,但是第三方可能会嗅到URL? 另外,我正在处理JSP; 当使用JSP或类似的框架时,最好的做法是避免将敏感数据放在POST或GET中,并使用服务器端代码来处理敏感信息。

就安全性而言,它们本质上是一样的。 尽pipePOST不会通过URL公开信息,但它在客户端和服务器之间的实际networking通信中公开与GET相同的信息。 如果您需要传递敏感信息,您的第一道防线就是使用安全HTTP传递。

GET或查询stringpost对于为特定商品添加书签所需的信息,或者用于协助search引擎优化和索引项目都非常有用。

POST适用于提交一次数据的标准表单。 我不会使用GET来发布实际的表单,除非在search表单中您希望允许用户将查询保存在书签中,或者沿着这些行。

GET请求比POST请求稍微安全一些。 既不能提供真正的“安全” 使用POST请求不会神奇地使您的网站的安全性,以防止恶意攻击明显的金额。 但是,使用GET请求可能会使安全的应用程序不安全。

“不得使用GET请求进行更改”的口号仍然非常有效,但这与恶意行为无关。 login表单是使用错误的请求types发送的最敏感的表单。

search蜘蛛和networking加速器

这是您使用POST请求更改数据的真正原因。 search蜘蛛将遵循您网站上的每一个链接,但不会提交他们发现的随机表格。

networking加速器比search蜘蛛更糟糕,因为它们在客户端的机器上运行,并在login用户的上下文中 “点击”所有链接。 因此,即使需要pipe理员,使用GET请求删除东西的应用程序也会很乐意服从(非恶意!)networking加速器的命令,并删除它看到的所有东西 。

困惑的副攻击

无论您使用GET还是POST请求,都可能发生 混淆副攻击 (代理浏览器)。

在攻击者控制的网站上,GET和POST 同样很容易在 没有用户交互的情况下 提交 。

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

有人可能会争辩说,networking加速器是一个混乱的副攻击的例子,但这只是一个定义的问题。 如果有的话,一个恶意的攻击者无法控制这个,所以即使副手感到困惑,也不是什么攻击

代理日志

代理服务器可能会完整loggingGET URL,而不会剥离查询string。 POST请求参数通常不会被logging。 在任何情况下,Cookie都不可能被logging。 (例)

这是支持POST的一个非常弱的理由。 首先,可以将未encryption的stream量整体logging下来; 恶意代理已经拥有了它所需要的一切。 其次,请求参数对攻击者的使用有限:他们真正需要的是cookies,所以如果他们唯一的东西是代理日志,他们不太可能攻击GET或POST URL。

login请求有一个例外:这些例子往往包含用户的密码。 将其保存在代理日志中会打开一个在POST情况下不存在的攻击向量。 但是,通过普通的HTTPlogin本质上是不安全的。

代理caching

caching代理可能保留GET响应,但不保留POST响应。 话虽如此,GET的反应可以做成不可caching的,比把URL转换成POST处理程序的工作量更less。

HTTP“Referer”

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

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

浏览器历史

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

浏览器刷新操作

只要用户点击“刷新”,浏览器就会重试GET请求。 这可能会在closures后恢复标签时执行此操作。 任何行为(比如支付)都将在没有任何警告的情况下重复。

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

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

所以我该怎么做?

  • 主要是因为与安全无关的原因,只使用POST请求来更改数据。
  • 只使用POST请求login表单; 否则会引入攻击媒介。
  • 如果您的网站执行敏感操作,您确实需要知道自己在做什么的人,因为这不能用一个答案来涵盖。 您需要使用HTTPS,HSTS,CSP,缓解SQL注入, 脚本注入(XSS) , CSRF以及其他可能特定于您的平台的事情(如各种框架中的批量分配漏洞: ASP.NET MVC , Ruby on Rails等)。 没有任何东西会影响“安全”(不可利用)和“不安全”之间的区别。

通过HTTPS,POST数据被编码,但是第三方可能会嗅到URL?

不,他们不能被嗅到。 但是这些URL将被存储在浏览器历史logging中。

最好的做法是避免将敏感数据放在POST或GET中,并使用服务器端代码来处理敏感信息。

取决于它是多么敏感,或者更具体地说,以何种方式。 客户很明显会看到它。 任何有权访问客户计算机的人都会看到它。 当客户发回给你时,客户端可以欺骗它。 如果这些问题是肯定的,请将敏感数据保存在服务器上,不要让它离开。

你没有提供更高的安全性,因为variables是通过HTTP POST发送的,而不是通过HTTP GET发送的variables。

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

  • OPTIONS
  • 得到
  • POST
  • 删除
  • 跟踪
  • CONNECT

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

 <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请求都是:

  • 未encryption
  • 包含在这两个例子中
  • 可以被淘汰,并受到MITM的攻击。
  • 轻松由第三方复制,脚本机器人。

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

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

所以要具体:

那么另一个本质上更安全吗? 我意识到,POST不公开URL的信息,但是有没有真正的价值,或者它只是安全通过默默无闻? 这里最好的做法是什么?

这是正确的,因为你用来说HTTP的软件倾向于用一种方法存储请求variables,而不是另一种只能阻止某人查看你的浏览器历史logging,或者从一个认为他们了解h4x0r1ng的10岁的人那里得到一些其他天真的攻击,或检查您的历史logging的脚本。 如果你有一个可以检查你的历史存储的脚本,你可以很容易地检查你的networkingstream量,所以通过默默无闻的整个安全只是提供晦涩的脚本小子和嫉妒的女朋友。

通过https,POST数据被编码,但可以被第三方嗅探?

以下是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 GET

 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会话是encryption的,唯一可见的通信部分在TCP / IP层(即IP地址和连接端口信息)上。

所以让我在这里做一个大胆的陈述。 你的网站在一个HTTP方法上的安全性比另一个方法要高,全世界的黑客和新手都知道如何去做我刚刚演示的东西。 如果您想要安全,请使用SSL。 浏览器倾向于存储历史logging,RFC2616 9.1.1build议不要使用GET来执行一个操作,但是认为POST提供的安全性是错误的。

POST是唯一一个安全措施? 通过浏览器历史防止您的嫉妒。 而已。 世界其他地方都login到你的账户上嘲笑你。

为了进一步说明POST为什么不安全,Facebook使用POST请求,那么FireSheep等软件如何存在?

请注意,即使您使用HTTPS,并且您的站点不包含XSS漏洞,您也可能会受到CSRF攻击。 简而言之,这种攻击scheme假设受害者(您的网站或服务的用户)已经login并且拥有一个正确的cookie,然后受害者的浏览器被要求对您的(据称是安全的)网站做些事情。 如果您没有针对CSRF的保护,则攻击者仍然可以使用受害者凭据执行操作。 攻击者无法看到服务器的响应,因为它会被转移到受害者的浏览器,但是通常在那个时候已经造成了破坏。

没有增加的安全性。

发布数据不会显示在历史和/或日志文件中,但是如果数据应该保持安全,则需要使用SSL。
否则,无论如何,任何人都可以读取你的数据。

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

  1. POST ed信息不会保存在用户的历史logging中。
  2. 在表单中发送的敏感信息(密码等)将不会在URL栏中显示(通过使用GET ,它将显示在历史logging和URL栏中)。

另外, GET具有数据的理论极限。 POST不会。

对于真实的敏感信息,请确保使用SSLHTTPS

GET和POST两者中的任何一个都不会比另一个更“安全”,就像传真和电话中的任一个都比另一个更“安全”。 提供了各种HTTP方法,以便您可以select最适合您要解决的问题的方法。 GET更适合幂等查询,而POST则更适合“动作”查询,但如果您不了解您所维护的应用程序的安全体系结构,则可以轻而易举地开始自己的脚步。

如果你仔细阅读第9章: HTTP / 1.1 RFC的 方法定义 ,可能是最好的,以便全面了解GET和POST最初设想的意思。

GET和POST之间的区别不应该从安全angular度来看,而应该看作是对服务器的意图。 GET不应该更改服务器上的数据 – 至less在日志以外 – 但POST可以创build新的资源。

Nice代理不会cachingPOST数据,但可能会caching来自URL的GET数据,所以您可以说POST应该更安全。 但是,POST数据仍然可用于不能很好地播放的代理。

正如许多答案中提到的那样,唯一可以确定的就是通过SSL。

但是请确保GET方法不提交任何更改,如删除数据库行等

我通常select的方法是这样的:

  • 获取稍后将由URL 检索的项目
    • 例如search应该是GET,所以你可以做search.php?s = XXX稍后
  • 发送将被发送的项目
    • 这是相对隐蔽的共同GET和更难发送,但数据仍然可以通过curl发送。

无论是神奇地赋予请求的安全性,但GET意味着一些通常阻止其安全的副作用。

GETurl显示在浏览器历史logging和networking服务器日志中。 出于这个原因,他们不应该用于像login表单和信用卡号码的东西。

但是,只是发布数据也不能保证安全。 为此,你需要SSL。 通过HTTP使用时,GET和POST都通过networking以明文forms发送数据。

POST数据还有其他很好的理由,比如提交无限量数据的能力,或者隐藏临时用户的参数。

缺点是用户无法将通过POST发送的查询结果join书签。 为此,你需要GET。

这不是安全相关的,但是… 浏览器不会cachingPOST请求

考虑这种情况:一个草率的API接受GET请求,如:

 http://www.example.com/api?apikey=abcdef123456&action=deleteCategory&id=1 

在某些设置中,当您请求这个URL时,如果有关于请求的错误/警告,整行将被logging在日志文件中。 更糟糕的是,如果您忘记在生产服务器中禁用错误​​消息,则这些信息只会在浏览器中显示出来! 现在,您只需将您的API密钥交给每个人即可。

不幸的是,真正的API是这样工作的。

我不喜欢在日志中显示敏感信息或在浏览器中显示敏感信息的想法。 POST和GET是不一样的。 在适当的地方使用。

  1. SECURITY作为数据传输的安全性:POST和GET没有区别。

  2. 安全性作为数据的安全性在计算机上:POST更安全(无URL历史logging)

很多人采用了一个约定(由罗斯暗示),GET请求只能检索数据,不会修改服务器上的任何数据,POST请求用于所有的数据修改。 虽然一个人比另一个人本质上更安全,但如果遵循这个约定,则可以应用交叉安全逻辑(例如,只有拥有账户的人才能修改数据,因此未经身份validation的POST被拒绝)。

更改POST请求比较困难(需要比编辑查询string更多的工作)。 编辑:换句话说,这只是安全的默默无闻,几乎没有。

我不打算重复所有其他的答案,但有一个方面,我还没有看到提及 – 这是数据消失的故事。 我不知道在哪里find它,但…

基本上,这是一个神秘的networking应用程序,每隔几天晚上就会丢失所有的数据,没有人知道为什么。 后来检查日志显示,该网站是由谷歌或其他任意蜘蛛find,愉快地GET(阅读:GOT)在网站上find的所有链接 – 包括“删除此条目”和“你确定吗? 链接。

其实 – 其中一部分已经提到。 这是“不要在GET上更改数据,但只在POST上”的背后的故事。 爬行者会很乐意跟随GET,永远不会POST。 即使是robots.txt也不会对行为不端的爬虫有帮助。

您还应该知道,如果您的网站包含指向您不控制的其他外部网站的链接,那么当您按下网站上的链接时,GET会将这些数据放在外部网站的重新引用页眉中。 所以通过GET方法传输login数据总是一个大问题。 因为这可能会暴露login凭证,只需检查日志或查看Google Analytics(或类似)即可轻松访问。

安全的概念是没有意义的,除非你定义什么是你想要的安全。

如果您希望保存浏览器历史logging,某些types的日志logging以及查看您的URL的人员,则POST更安全。

如果你想要对某人嗅探你的networking活动是安全的,那么没有什么区别。

RFC7231:

“URI即使在识别安全资源时也是共享的,而不是安全的,URI通常显示在屏幕上,在打印页面时添加到模板中,并存储在各种不受保护的书签列表中,因此不明智URI内的信息敏感,个人可识别或泄露风险。

服务的作者应该避免提交敏感数据的基于GET的表单,因为这些数据将被放置在请求目标中。 许多现有的服务器,代理和用户代理在第三方可能看到的地方logging或显示请求目标。 这种服务应该使用基于POST的表单提交。“

本RFC明确指出,不应使用GET提交敏感数据。 由于这种说法,一些实现者可能不会同样处理从GET请求的查询部分获得的数据。 我正在自己的协议工作,确保数据的完整性。 根据这个规范,我不应该保证GET数据的完整性(我会这样做,因为没有人遵守这些规范)

正如以前有人所说,HTTPS带来了安全性。

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

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

任何人都可以看到GET(即使是现在的那个),并保存在caching中,所以不太安全的使用后,没有一些cryptographics例程btw后不知道,为了一点安全,你必须使用SSL HTTPS)

POST对安全性更糟糕的一个原因是,GET是默认logging的,参数和所有数据几乎都是通过Web服务器logging的。

POST是相反的 ,它几乎没有被logging ,导致非常难以发现攻击者的活动。

我不会购买“太大”这个说法,没有理由不logging任何东西 ,至less1KB,这会让人们发现攻击者在一个弱的入口处工作,直到它popup为止。通过使任何基于HTTP的后门无声地通过无限数量的数据,这是一个双重的解除服务。

不同的是,GET发送数据打开和POST隐藏(在http-header中)。

所以对于非安全的数据,比如Google中的查询string,更好。 validation数据永远不会通过GET发送 – 所以在这里使用POST。 当然整个主题更复杂一点。 如果你想阅读更多,阅读这篇文章 (德文)。

最近发布了一个攻击 ,允许中间的人揭示压缩的HTTPS请求的请求主体。 因为请求标头和URL没有被HTTP压缩,所以GET请求可以更好地抵御这种特殊的攻击。

GET请求也有脆弱的模式,SPDY压缩请求头,TLS也提供可选的(很less使用的)压缩。 在这些情况下,攻击更容易防止(浏览器供应商已经提供了修复)。 HTTP级别的压缩是一个更基本的function,供应商不太可能会禁用它。

这只是一个例子,显示了一个GET比POST更安全的场景,但是我不认为从这个攻击原因中selectGET over POST是一个好主意。 攻击是相当复杂的,需要非平凡的先决条件(攻击者需要能够控制部分请求内容)。 在攻击有害的情况下最好禁用HTTP压缩。

这是一个旧post,但我想反对一些答案。 如果您要传输敏感数据,则需要使用SSL。 如果您使用带GET参数的SSL(例如?userid = 123),那么这些数据将以纯文本forms发送! 如果您使用POST进行发送,则这些值将被放入消息的encryption体中,因此对大多数MITM攻击无法读取。

最大的区别就是数据通过的地方。 只有数据放在URL中才有意义,它不能被encryption,否则你将无法路由到服务器,因为只有你可以读取URL。 GET就是这样工作的。

简而言之,您可以通过SSL安全地传输数据,但是您无法使用SSL或SSL进行传输。

即使POST也接受GET请求。 假设你有一个input如user.name和user.passwd的表单,这些表单应该支持用户名和密码。 如果我们只是添加一个?user.name =“我的用户&user.passwd =”我的密码“,那么请求将被”绕过login页面“接受。

一个解决scheme是在服务器端实现filter(javafilter作为e),并检测没有string查询作为GETparameter passing。