whip1ash

HTTP Desync Attacks - Request Smuggling Reborn[翻译]

2019-08-18

原文在这里。其实这篇Paper很值得研究,并能够应用在日常的漏洞挖掘中。本文不是直译过来的,原文党请移步原版。翻译此文只是为了加深的理解,我的英语也很一般,尽量讲得让大家都看懂吧。能力一般,水平有限,多多谅解,有问题希望大家与我多交流,共同探讨。Orz

Abstract

HTTP请求通常被认为是相互独立的实体。在这篇文章中,我将探讨一些被遗忘的技术。通过这种技术,远程未授权的攻击者能够打破HTTP请求的独立性,并拼接攻击者的请求到其他请求中。我在数个军方和商业的Web基础设施上找到了这个问题,并将我的exp拼接到正常的用户请求中,因此我在赏金项目中获得了7万刀的奖励。

通过案例,我将为你展示如何精巧地篡改受害者的请求,使这些请求被送到一个恶意的域中,使其得到有害的响应,并获得回显(lure credentials into your open arms)。我同样将证明使用后端重组请求的方式,将会使得前端(请求)[注:这里的前后端是指服务器在数据流中不同的位置]的信任被利用,这会导致能够使用最大权限来调用内部API,污染Web缓存,使PayPal的登录页面不再安全。

HTTP Request Smuggling最早的记录是在2005年,由Watchfire提出。但由于其难以利用,所以它多年来一直被忽略,但是近年来Web设备受这个漏洞影响的概率在增加。我将帮助您解决这个遗留问题,包括新的攻击形式和利用向量,通过定制的开源工具和一种可靠的黑盒测试的新方法,同时将收到影响的风险降到最低。

Core concepts

自动HTTP/1.1开始,通过单个TCP或者SSL/TLS套接字来发送多个HTTP请求就被广泛的支持。这个协议非常的简单,HTTP请求被简单的拼接在一起,然后服务器通过解析HTTP头部来分别同一个套接字中的不同的HTTP请求。它经常和HTTP管道(HTTP pipelining)搞混,HTTP管道是一种不常见的子类型,不在本文的探讨范围之内。

仅仅针对这项功能而言,这是无害的。而然,现代的网站由一系列的系统组成,全通过HTTP通信。这种多层架构导致不同用户的HTTP请求通过同一个TCP/TLS链接来传输。

这就意味着后端在处理请求时,需要和前端识别的请求结束的位置一样,这是至关重要的。换种说法,攻击者可能发送一个边界模糊的消息,它将会在后端被分割成两个不同的HTTP请求。

这使得攻击者能够在下一个用户请求开始的地方构造任意内容。贯穿这篇文章,被偷运的内容将使用’prefix’表示,并高亮为橘黄色。

我们假设前端解析HTTP头中出现的第一个’Content-Length’而后端解析第二个。对于后端来说,这个TCP流看起来是这样的:

在这种情况下,前端发送蓝色和橘黄色的数据到后端,然而后端只处理蓝色的内容。这就使得后端的套接字被橘黄色的内容污染。当另一个正产的绿色请求拼接到黄色的内容之后时,将会导致一个非预期的响应。

在这里例子中,注入的’G’将会污染绿色用户的请求,并且他将会得到一个”Unknown method GPOST”的响应。

本文的每一个攻击都是基于这个格式。Watchfire的论文描述了一种交互的途径叫’backward request smuggling’,但是是基于前后端的管道链接的,所以那是一种很少见的情况。

在真实环境中,这个包含两个content-length头的方法很少奏效因为很多系统都会拒绝多个content-length头的请求。所以,我们将攻击使用了chunked编码的系统,并且这次RFC2616标准也站在我们这一边。

If a message is received with both a Transfer-Encoding header field and a Content-Length header field, the latter MUST be ignored.
如果一个消息包含Transfer-Encoding和Content-Length,后者必须被忽略。

由于这份标准隐式的允许处理同时包含Transfer-Encoding: chunked 和 Content-Length头的请求,所以很少有服务器会拒绝这样的请求。只要在前后端的所有服务器中,有一个方法能够隐藏Transfer-Encoding头,那么后续对于HTTP的处理将会使用Content-Length头来判断HTTP包的长度,这样我们就能使整个系统(在对于HTTP的处理上)不同步。

你可能对chunked编码不是很熟悉,因为像Burp Suite在内存中将请求和响应解码成了常规的格式,为了方便编辑。在一个chunked的消息中,其中包含零个或多个chunk(块)。每一个chunk都有一个chunk size,后接一个\r\n,然后紧接着是chunk内容。这条消息以一个长度是0的chunk结尾。这里有一个简单的使用chunk编码的不同步攻击(desynchronisation attack)样例:

目前我们没有尝试去隐藏Transfer-Encoding头,所以上述的这个利用只能在前端不支持chunked编码的前端使用,比如很多网站使用的内容分发网络厂商Akamai。

如果后端不支持chunked编码,我们需要调整一下位置。

这种方法可以在相当多的系统上工作,但是我们可以通过隐藏Transfer-Encoding头使其得到更加广泛的应用,这样会使(前端或者后端)一个服务器找不到这个头。这可以通过服务器的HTTP解析差异实现。这里有一些服务器只能识别Transfer-Encoding: chunked头请求的例子。下面的每一个用法都在这次研究的系统中有至少一个服务器可以被利用。

上面的这种特性是无害的,如果前端和后台的服务器都有这种特性的话,否则就有极大的威胁存在。更多技术资料,请查看Regilero正在进行的研究。我们将简短的研究几个使用其他技术的特殊例子。

Methodology

Request smuggling 背后的原理是显而易见的,但是由于不可控变量的数量以对于前后端发生的事情不了解将会导致很多复杂情况。

我已经开发了一些工具来解决这些挑战,并且将他们总结成下列简单的方法论,可以通过这个方法论来发现Request smuggling漏洞并且验证它们的影响。

Detect

最简单的方法去发现Request smuggling漏洞的方法是在一个普通”受害者”的请求下面发送一个任意请求,然后判断是否得到了一个非预期的响应。然而,这极易受到干扰;如果另一个用户的请求在我们的受害者之前击中了受污染的socket,那么他们将会得到受到破坏的响应,但是我们无法发现漏洞。这就意味着在一个大流量的线上站点中,如果没有在这个过程中利用大量的用户(账号)的话,很困难去证明Request Smuggling存在。然而在没有其他用户流量的站点中,你依然有几率得到一个错误的判断由于应用层面偶然的终止连接。

为了定位这个漏洞,我开发了一个发现策略,它发送一系列的消息,这些消息将会使得存在漏洞的后端系统对于请求超时。这种技术误报率很低,包括应用层面的异常所导致的误报,并且对其他用户几乎没有影响。

现在我们假设前端服务器使用了Content-Length头,但是后端系统使用了Transfer-Encoding头。简称这种情况为CL.TE。我们可以发现潜在的Request smuggling通过发送下列请求:

我们感谢比实际内容短的Content-Length头,前端服务器将只会处理蓝色标识的部分,而后端服务器将超时,因为在等待标识下一个chunk大小的数据。这将会导致显而易见的延时。

如果前后端服务器是同步的(TE.TE或者CL.CL[TE => Transfer-Encoding CL => ContentLength]),这个请求将会被前端服务器拒绝,或者被正常处理。最后,如果是另外一种不同步的情况(TE.CL)前端服务器将会拒绝这条消息,并且不再向后转发,因为无效的chunk大小’Q’。这就防止了后端的套接字被污染。

我们可以安全的发现TE.CL的前后端不同步情况使用下列的请求:

由于chunk被’0’结束,所以前端服务器将只能处理蓝色表示的文本,并且后端服务器将因为等待’X’而超时。

如果这种不同步的情况发生在另一种方式(CL.TE),’X’污染后端的套接字,可能使合法的用户请求受到损害。幸运的是,如果我们首先使用上一种检测方法(CL.TE),将可以排除这种情况。

这些请求可以利用目标站点对于HTTP头解析的差异性,并且他们也用于一个开源的Burp Suite插件 - HTTP Request Smuggler,自动化发现Request Smuggling漏洞。它们同样也被用在Burp Suite的核心扫描器中。虽然这是一个服务器层面的漏洞,同一个域名下的不同端点(接口)将有不同的路由路径,所以这种技术可以被独立应用的每一个端点(接口)。[也就是每一个接口都可能存在这种情况。]

Confirm

在这里,你已经尽可能的去不影响其他用户。而然,在没有进一步能够证明危害的情况下, 很多厂商不愿意去严肃的对待这个问题,这就是我们这里要探讨的东西。所以下一步将证明使用Request Smuggling污染后端套接字是非常有可能的。为了做到这一点,我们将发出一个污染后端套接字的请求,使其拼接到一个受害者的请求中,从而使响应被明显的更改。

如果首次请求引起了一个错误,那么后端服务器将会关闭这个连接,忽略被污染的缓冲区并且终止这次攻击。通过将一个接受POST请求的后端服务器作为目标站点,并保留预期内的GET/POST请求,可以避免这种情况。

由于一些站点是分布式的系统,请求的路由取决于请求的方法,URL和HTTP Header。如果受害者的请求被路由到了一个与攻击请求不同的后端服务器,那么攻击将会失败。所以,’attack’和’victim’请求应该被构造的尽可能一样。

如果目标的请求长这样:

那么一个CL.TE的攻击尝试应该像这样:

如果攻击成功,那么受害者将会得到一个404的响应。

TE.CL攻击也是类似的,但是需要一个闭合的chunk,这就意味着我们需要指定所有的HTTP头,并且将它拼接到受害者的请求中。确保在受害者请求之前拼接的Content-Length头要大于请求包的内容。

如果这个站点是线上的,其他用户的请求也可能在你的请求之前命中这个受污染的套接字,这将会导致你的攻击失败并且使其他人感觉到不爽。因此,这个过程往往需要几次尝试,在高流量的网站上可能需要数千次尝试。请仔细并且有耐心,目标是有可能存在漏洞的。

Explore

我将会使用一些线上的网站证明其他部分的方法论。像往常一样,我将目标定为那些明确表示愿意与安全研究人员合作的公司,为此开启了一个Bug Bounty项目。由于私人程序的激增和无聊的补丁,我不得不修改了不少。如果网站是明确命名的(explicitly named),请记住,它们是目前少数能够抵御此攻击的网站之一。

现在我们已经能够污染socket了,下一步我们需要收集一些信息为了一个全面(well-informed)的攻击。

前端服务器经常使用一些难猜的自定义的值追加或者重写HTTP请求头,比如X-Forwarded-Host和X-Forwarded-For。我们攻击的请求可能会缺失这些头,这将会导致一个非预期的应用程序行为并且使我们的攻击失败。

幸运的是,通过一个简单的方法我们可以得到一些隐藏HTTP头的信息。这使得我们可以通过手动添加头来恢复功能,甚至可能会引发进一步的攻击。

简单的找一个目标站点使用POST参数的页面,将受害的者的请求拼在最后,并且增加一点Content-Length长度,然后发送最终的请求:

在命中login[email]参数之前,绿色标识的部分将会被前端服务器重写,所以这将会得到一个反射式(输出输入内容)的响应,这将会泄露内部的头信息。

通过增加Content-Length头的长度,你可获取更多的信息,知道尝试读取受害者请求的结尾并超时为止。

有些系统完全依赖于前端系统的安全性,一旦你突破了,你就可以直接跳华尔兹舞(庆祝)了。在login.newrelic.com上,后端服务器是一个代理,因此更改拼接的HTTP头允许我访问不同的NewRelic系统。最初,我以为命中的每个内部系统都认为我的请求是通过HTTP发送的,并以重定向响应:

它被(我)简单的使用X-Forwarded-Proto头修复(绕过了这个限制):

通过一些信息泄露,我找到了一个目标站点上的有用的接口。

错误信息告诉我,我需要一个认证的HTTP头,但是却没给出具体的信息。所以我决定使用更早一段时间发现的X-nr-external-service头。

不幸的是这并没有生效,这得到了一个同样的Forbidden的响应,但是我们发现这已经直接访问这个URL了。这就意味着前端服务器使用X-nr-external-service头去判断请求是否是内部请求,但是通过拼接(Smuggling)丢失了这个头,我无意间欺骗了他们的系统,使得系统认为我们的请求是内部的。这很有启发,但是并不直接有用,我们仍然需要缺失的认证头的名字。

在这一点上,我可以将processed-request-reflection技术应用于一系列接口,直到找到一个具有正确请求头的接口。相反,我决定偷个懒,查阅我上次的关于New Relic系统的信息泄露的记录。

New Relic更新了一个热补丁,并将根本原因诊断为F5网关中的一个弱点。据我所知没有可用的补丁,这意味着在撰写本文时,这仍然是0day。

Exploit

直接调用内部api是很棒的,但它很少是我们唯一的选择。我们还可以对浏览目标网站的每个人发起大量不同的攻击。

为了实施一个可以影响其他用户的攻击,我们需要理解哪种类型的请求是可以被我们污染的。从’Confirm’阶段重复套接字投毒,但是反复使用’victim’请求直到它像典型的GET请求。你可能会发现你只能投毒特定方法、路径、HTTP头的请求。另外,尝试从不同的IP地址发出’victim’请求 - 在极少数情况下,你可能会发现,你只能毒害来自同一IP的请求。

最后,检查网站是否使用了缓存,这将会帮助我们绕过很多限制,增加我们对于投毒资源的控制,并最终增加Request Smuggling漏洞的危害。

Store

如果这个应用支持编辑或者存储任意类型的文本数据,利用它将会变得容易。通过将恶意请求拼接到受害者写入存储的请求前,我们可以使应用程序保存他们的请求而执行我们的请求,这可以盗取任意认证Cookie/headers。这里有一个Trello的例子,使用他们的编辑个人资料接口。

一旦受害者的请求到达,它就会保存在我的文件中,泄露他们所有的HTTP头和cookies:

这种方式唯一的问题是,在”&”之后发生的任何数据都将丢失,这使得从表单编码的post请求中窃取正文变得很困难。我花了一段时间试图通过使用其他请求编码来解决这个限制,但最终还是放弃了,但我仍然怀疑这是有可能的。

数据存储机会并不总是如此明显 - 在其他站点,我使用”Contact Us”表单,最终使邮件内容中包含了受害者的请求,这使我赚了$2500。

Attack

能够将任意的前缀拼接到其他人的响应中,这同样获得了另一种攻击方法 - 触发有害的响应。

这里有两个基础的方式去使用有害响应。最简单的就是构造一个’attack’请求,然后等到另一个请求命中后端服务器的套接字,并触发有害的响应。一个有用的技巧性的方式是我们同时构造’attack’和’victim’请求,然后等待有害的响应被Web缓存存储,这样可以使奏效于请求同样URL的所有人 - web缓存投毒。

在下列的每一个请求/响应片段中,黑色的部分是绿色部分请求的响应。蓝色部分请求的响应被隐藏了,因为它并不可见。

Upgrading XSS

在审计一个SaaS应用的时候,Param Miner发现了一个参数,叫SAML,并且Burp的扫描器确认这是个反射型XSS。反射型XSS是很好的,但是利用有一定的局限性,因为需要用户交互。

使用Request Smuggling我们可以构造一个响应包含XSS,攻击浏览这个网站的任意用户,实现大规模的应用。我们同样可以获取用于认证的HTTP头和HTTP only的Cookie,同样可以跨域。

Grasping the DOM

在www.redhat.com上查找与Request Smuggling相关的漏洞时,我发现了一个基于DOM的开放式重定向,它提出了一个有趣的挑战:

页面上一些JavaScript代码将从受害者的浏览器的url中读取’redir’参数,但是我如何利用它?Request Smuggling给了机会,能让我们控制服务器所读取到的url,但是受害者的浏览器对于url的感知只是他们正在访问的页面。

我通过服务器端的非开放式的url跳转解决了这个问题:

受害者的浏览器得到了一个301响应,跳转到 https://www.redhat.com/assets/x.html?redir=//redat.com@evil.net/ ,这里将触发一个基于DOM的开放式跳转,然后跳转到恶意的网站。

CDN Chaining

一些网站使用了多层的反向代理或者CDN。这给了我们额外的机会来利用这种(前后端对于HTTP头理解的)差异性,并且这将提升这个漏洞的危害。

这里有一个以某种方式使用了两层Akamai的目标站点,尽管服务器是由同一个供应商提供的,但是仍有可能使他们不同步,从而使受害站点从Akamai中的任意一个服务器上获取内容:

这个方法对于SaaS供应商同样奏效,通过将请求定向到构建在同一平台上的不同系统,我可以攻击一个构建在著名的SaaS平台上的关键网站。

‘Harmless’ response

由于Request smuggling使我们能够通过任意请求影响服务器的响应,所以一些通常没有危害的的行为也变得可以被利用了。举个例子,即使是不起眼的开放式重定向,也可以通过重定向加载恶意域的JavaScript,使用户收到威胁。

重定向使用的307(HTTP Code)是非常有用的,当浏览器在发出一个POST请求后,接收到一个307重定向,那么这个请求将会被发送到新的目标站点。这就意味着你可以让不知情的受害者直接将明文密码发送到你的服务器。

典型的开放式重定向本来就很常见,但是变形同样也很常见,那是由于Apache和IIS的机制。它通常被认为是没有危害的,所以所有人都忽略了它,因为如果没有像Request Smuggling这样的漏洞的话,它确实无法被利用。如果你尝试访问一个文件夹,而末尾没有 / ,服务器将会响应这个重定向,并且追加 / ,并且使用请求HOST头作为重定向的地址:

当使用这个技术的时候,请关注重定向中使用的协议。你可能可以使用X-Forwarded-SSL这样的头来影响它。如果它使用HTTP协议,但是你正在攻击一个HTTPS站点,由于混合内容保护(mixed-content protection),受害者的浏览器将阻止这个连接。有两个已知的特殊情况 - 1. Internet Explorer的混合内容保护可以完全绕过。 2. 如果重定向目标在其HSTS缓存中,Safari将自动升级到https的连接。

Web Cache Poisoning

在尝试对某一个站点进行了数个小时基于重定向的攻击后,我打开了他们的主页去寻找更多的攻击面,然后我在开发控制台中发现了如下错误。

无论哪台机器加载这个网站都会发生这个错误,并且这个ip地址看起来非常熟悉。在我测试重定向漏洞的过程中,其他人请求的图片拼接到我构造的请求之后,然后被污染过的响应已经被保存至缓存。

这是对于潜在风险的一个很好的演示,但并不是一个理想的结果。除了依赖于延时的检测方法,目前还没有方法能够完全消除缓存被污染的可能性。这就是说,如果你想使风险降到最低,你可以:

  1. 确保“受害者”请求有cache-buster。
  2. 使用Turbo Intruder尽可能快速的发送’Victim’请求.
  3. 尝试用添加一个反缓存头的前缀来触发响应,或者一个不太可能被缓存的状态代码。
  4. 使用一个没有那么高流量的区域

Web Cache Deception ++

如果我们不去减少攻击者/用户的混合响应被缓存的几率,而是增加它呢?

除了使用引起有害响应的前缀,我们还可以(通过缓存响应)得到受害者的敏感信息,和Cookie:

前端视角:

当用户对于静态资源的请求击中了被污染的socket的时候,响应将包含他们的账户详细信息,并且缓存将通过静态资源存储起来。我们可以获取到他们的账户详情通过从缓存中加载/static/site.js。

这是Web Cache Deception攻击的一个非常有效的新向量。这是非常有效的由于两个关键方法 - 它不需要用户交互,也不需要目标站点允许你所使用的扩展。它唯一的问题就是攻击者无法确定受害者的响应在哪里落地(where the victim’s response will land)。

PayPal

通过Request Smuggling向缓存投毒,我能够劫持更多的JavaScript文件,其中一个是在PayPal的登录页面:
https://c.paypal.com/webstatic/r/fb/fb-all-prod.pp2.min.js.

然而这里有个问题,PayPal的登录页面使用了内容安全策略(CSP),其中的 script-src不允许我的重定向。

这刚开始看起来像是纵深防御(triumph of defence in depth)的胜利。然而,我注意到登录页面加载了一个子页面在 c.paypal.com ,使用了动态生成iframe的方式。这个子页面没有使用CSP,并且依然可以导入我们受污染的JS文件。这样我们可以控制iframe的内容,但是由于同源策略,我们依然无法从父页面读取用户的PayPal密码。

我的同事Gareth Heyes在 paypal.com/us/gifts 上发现了一个不使用CSP的页面,并且导入了我们的污染的JS文件。通过使用我们的JS重定向 c.paypal.com 的ifram到该URL(并在第三次触发我们的JS导入),我们可以直接访问父窗口并从使用Safari或IE登录的所有人窃取明文PayPal密码。

PayPal快速解决了这个漏洞,通过配置Akamai,拒绝了所有Transfer-Encoding: chunked头,并且奖励了$18900。

几周后,当我发现并测试一些新的去同步化(desynchronisation)的技术时,我决定尝试使用line-wrapped头:

这似乎使Akamai完全忽略了Transfer-Encoding头,这使它能够通过,并且我再次控制了paypal的登录页面。PayPal快速应用了一个更强大的补丁,并且我获得了可观的$20000奖励。

Demo

另一个目标使用了一系列的反向代理,其中一个不将”\n”作为有效的HTTP头终止符。这意味着他们的网络基础设施有相当大的一部分容易被HTTP Request Smuggler攻击。我录制了一个演示,演示如何使用HTTP Request Smuggler在Bugzilla安装的副本上有效地识别和利用此漏洞,这里面包含一些极其敏感的信息。

你可以在本白皮书的在线版 https://portswigger.net/blog/http-desync-attacks 上找到该视频。

Defence

通常,简单意味着安全。如果您的网站没有负载均衡、CDN和反向代理,则此技术不构成威胁。你使用的层次越多,你就越容易受到攻击。

每当我讨论攻击技术时,都会被问到HTTPS是否能阻止它。一如既往,答案是“不”。也就是说,你可以修补此漏洞及所有变形情况,可以通过配置前端服务器专门使用HTTP/2与后端系统通信,或者完全禁用重用后端连接。或者,你可以确保调用链中的所有服务器使用相同的配置,或者运行相同的服务器软件。

此漏洞的一些特殊情况可以通过重新配置前端服务器来解决,这能够在转发之前规范所有请求。对于那些不想让用户受到漏洞危害的厂商来说,这可能对于CDN唯一的解决方法,并且Cloudflare和Fastly似乎成功的应用了它。

使请求变得规范不是后端服务器的修复方法 - 它们需要直接拒绝不明确的请求,并断开相关的连接。由于拒绝请求比简单地规范化请求更可能影响用户真实的流量,因此我建议将重点放在防止前端服务器上。

当你的工具对你不利时,有效的防御是不可能的。大多数测试工具在发送请求时会自动“修正”Content-Length头,从而使Request Smuggling成为不可能。在Burp套件中,您可以使用Repeater选项卡禁用此行为 - 确保您选择的工具有同样的功能。此外,某些公司和漏洞赏金平台通过类似Squid的代理来路由测试人员的流量,以便进行监控。这些将破坏测试人员发起的任何Request Smuggling攻击,确保公司对此漏洞获得全覆盖。

与大多数类型的web漏洞不同,即使是小心的Request Smuggling攻击也会产生一定的影响。这使得对于任何想要获得Request Smuggling攻击经验的人来说,线上的网站是一个糟糕的培训场所。为了帮助解决这一问题,我们发布了一个免费的在线学习资源,其中有一些可交互的网站故意容易受到攻击,因此您可以在一个安全可控的环境中开始学习。

Conclusion

基于多年来一直被忽视的研究,我引入了新的技术来使服务器差异化,并展示了利用众多真实网站作为案例研究来利用结果的新方法,在此过程中获得了70,800美元的赏金。 通过这个我已经表明,Request Smuggling对Web构成主要威胁,其中HTTP解析功能的安全很关键,容忍模棱两可的消息是危险的。 我还发布了一种方法和一个开源工具包,以帮助人们审核Request Smuggling,证明影响,并以最小的风险获得赏金。 这些报告已被认真对待,导致超过70,800美元的漏洞奖励,其中我们已向慈善机构捐赠超过50%。

这个主题仍然没有得到充分研究,因此我希望这本出版物能够在未来几年内激发新的差异化技术和漏洞利用。

References

  1. https://www.cgisecurity.com/lib/HTTP-Request-Smuggling.pdf
  2. https://portswigger.net/blog/turbo-intruder-embracing-the-billion-request-attack
  3. https://tools.ietf.org/html/rfc2616#section-4.4
  4. https://regilero.github.io/tag/Smuggling/
  5. https://github.com/portswigger/http-request-smuggler
  6. https://portswigger.net/blog/cracking-the-lens-targeting-https-hidden-attack-surface
  7. https://github.com/PortSwigger/param-miner
  8. https://portswigger.net/blog/practical-web-cache-poisoning#hiddenroutepoisoning
  9. https://portswigger.net/blog/http-desync-attacks
  10. https://portswigger.net/web-security/request-smuggling

扫描二维码,分享此文章