Nazaj na blog

Varnost GraphQL: Onkraj ranljivosti REST

September 19, 2024 8 min branja
Varnost GraphQL: Onkraj ranljivosti REST
Nazadnje posodobljeno:

GraphQL je hitro postal prevladujoča tehnologija API za sodobne aplikacije, ki odjemalcem ponuja prilagodljivost pri zahtevanju točno tistih podatkov, ki jih potrebujejo. Vendar ta prilagodljivost prinaša edinstveno napadalno površino, ki se bistveno razlikuje od tradicionalnih API-jev REST. Medtem ko so končne točke REST fiksne in predvidljive, GraphQL izpostavlja eno samo končno točko z močnim poizvedovalnim jezikom, ki ga napadalci lahko izkoristijo na nepričakovane načine. V tem vodniku bomo pregledali najkritičnejše varnostne težave GraphQL in predstavili strukturirano metodologijo testiranja.

Avtorizacijo, omejevanje zahtev in obremenitve s poizvedbami obravnava OWASP GraphQL Cheat Sheet.

Kaj naredi GraphQL drugačen od REST

Z varnostnega vidika več značilnosti GraphQL bistveno spremeni model groženj. API-ji REST izpostavljajo več končnih točk, od katerih vsaka vrača fiksno podatkovno strukturo. GraphQL vse konsolidira za eno samo končno točko in sprejema prilagodljive poizvedbe, ki jih strežnik dinamično razreši. To pomeni, da tradicionalne varnostne kontrole na ravni končnih točk, omejevanje pogostosti zahtev in pravila WAF pogosto odpovedo. Strogo tipizirana shema deluje kot prednost in slabost hkrati: uveljavlja podatkovne tipe, vendar lahko tudi razkrije celotno strukturo API prek introspekcije. Poleg tega narava poizvedb, ki jih vodi odjemalec, pomeni, da lahko napadalci oblikujejo zahteve, ki jih razvijalci med načrtovanjem nikoli niso predvideli.

Napadi z introspekcijo

Introspekcija je vgrajena funkcija GraphQL, ki odjemalcem omogoča poizvedovanje po sami shemi. Čeprav je med razvojem neprecenljiva, njena omogočenost v produkciji dejansko napadalcem preda popoln zemljevid vašega API-ja.

S pošiljanjem poizvedbe na __schema lahko napadalec pregleda vsak tip, polje, argument, mutacijo in naročnino, ki jo API izpostavlja. To vključuje polja, ki morda niso nikjer referencirana v uporabniškem vmesniku, vendar so še vedno dostopna, kot so administrativne mutacije ali zastarele končne točke s šibkejšimi varnostnimi kontrolami.

  • Odkrivanje sheme - Poizvedba { __schema { types { name fields { name type { name } } } } } razkrije celoten podatkovni model, vključno s skritimi ali nedokumentiranimi tipi
  • Popis mutacij - Napadalci lahko odkrijejo mutacije kot deleteUser, changeRole ali resetPassword, ki morda nimajo ustreznih preverjanj avtorizacije
  • Analiza argumentov - Argumenti polj razkrijejo pričakovane vhodne tipe, možnosti filtriranja in notranje konvencije poimenovanja, ki informirajo nadaljnje napade
  • Orodja za vizualizacijo - Orodja kot GraphQL Voyager generirajo interaktivne vizualne zemljevide sheme, kar olajša prepoznavanje visoko vrednih ciljev, kot so objekti uporabnikov, polja za plačila ali administrativne mutacije

Tudi ko je introspekcija onemogočena, lahko napadalci uporabijo napake s predlogi polj za rekonstrukcijo sheme z grobo silo. Mnoge implementacije GraphQL vračajo koristna sporočila o napakah, kot je "Ali ste mislili userEmail?", ko je poizvedeno neveljavno polje, kar omogoča postopno odkrivanje sheme.

Napadi z združevanjem in vzdevki

GraphQL izvorno podpira pošiljanje več operacij v eni sami zahtevi HTTP prek združevanja poizvedb in vzdevkov. Ta funkcija, čeprav priročna za legitimne odjemalce, ustvarja močne vektorje napadov.

  • Obvod omejitve pogostosti zahtev - Če se omejevanje pogostosti zahtev uporabi na ravni zahteve HTTP in ne na ravni operacije, lahko napadalec pošlje na stotine poizvedb v eni sami zahtevi, s čimer učinkovito v celoti obvozi omejitve pogostosti zahtev
  • Groba sila poverilnic - Z uporabo vzdevkov lahko napadalec poskusi na stotine prijavnih kombinacij v eni zahtevi: a1: login(user:"admin", pass:"pass1") { token } a2: login(user:"admin", pass:"pass2") { token } in tako naprej, s čimer testira ogromno število poverilnic, medtem ko se prikazuje kot ena sama zahteva
  • Obvod OTP - Kode za dvostopenjsko overitev je mogoče razbiti z grobo silo z združevanjem na stotine poskusov preverjanja, ki se pogosto zaključijo, preden OTP poteče
  • Popis v velikem obsegu - Združevanje iskanj uporabnikov ali mutacij za ponastavitev gesel za popis veljavnih računov brez sprožitve pragov zaznave

Zavrnitev storitve prek kompleksnosti poizvedb

Rekurzivna narava tipov GraphQL ustvarja priložnosti za napade z izčrpavanjem virov, ki nimajo neposrednega ekvivalenta v API-jih REST.

  • Globoko vgnezdene poizvedbe - Ko se tipi sklicujejo drug na drugega (npr. Uporabnik ima Objave, Objava ima Avtorja, Avtor ima Objave), lahko napadalec sestavi poizvedbe, vgnezdene na desetine ravni globoko, kar povzroči eksponentno obremenitev baze podatkov
  • Eksplozija kompleksnosti poizvedb - Tudi brez globokega gnezdenja lahko zahtevanje mnogih polj s tipi seznamov, ki vsako sprožijo drage razreševalce, izčrpa vire strežnika
  • Krožne reference fragmentov - Zlonamerno oblikovani fragmenti, ki se sklicujejo drug na drugega, lahko ustvarijo neskončne zanke, če strežnik ne implementira ustrezne validacije. Čeprav večina zrelih implementacij to zdaj preprečuje, so lastne implementacije lahko ranljive
  • Izčrpavanje virov prek paginacije - Zahtevanje izjemno velikih velikosti strani (npr. first: 999999) na tipih povezav lahko prisili strežnik, da naloži in serializira ogromne nabore podatkov

Težave z avtorizacijo

Avtorizacija v GraphQL je zloglasno težka za pravilno implementacijo, ker je treba nadzor dostopa uveljavljati na ravni polj, ne le na ravni končnih točk kot pri REST.

  • Vrzeli avtorizacije na ravni polj - Poizvedba uporabnika morda pravilno omejuje dostop do profilov drugih uporabnikov, vendar še vedno izpostavlja občutljiva polja kot email, ssn ali salary, ko so dostopana prek drugačne poti v grafu
  • IDOR prek Relay ID-jev vozlišč - Implementacije, ki uporabljajo specifikacijo Relay, izpostavljajo globalno poizvedbo node(id: "..."). Ker so ID-ji vozlišč Relay pogosto zaporedna števila, kodirana v base64, jih napadalci lahko dekodirajo, povečajo in dostopajo do poljubnih objektov ne glede na predvideno pot dostopa
  • Obvod avtorizacije mutacij - Dostop za branje in dostop za pisanje sta pogosto nedosledna. Uporabnik, ki ne more pregledati administrativnih nastavitev prek poizvedbe, jih morda še vedno lahko spremeni prek mutacije, če so preverjanja avtorizacije implementirana samo na razreševalcih poizvedb
  • Avtorizacija naročnin - Naročnine na osnovi WebSocket pogosto nimajo enakih preverjanj avtorizacije, ki se uporabljajo za poizvedbe in mutacije, kar nepooblaščenim uporabnikom omogoča prejemanje posodobitev v realnem času o spremembah občutljivih podatkov

Napadi z vbrizgavanjem

GraphQL ni imun na tradicionalne ranljivosti vbrizgavanja. Poizvedovalni jezik je zgolj transportna plast, osnovni razreševalci pa še vedno komunicirajo z bazami podatkov in drugimi sistemi.

  • SQL-vrivanje - Argumenti GraphQL, posredovani neposredno v poizvedbe SQL brez parametrizacije, so ranljivi. To je posebej pogosto pri argumentih za filtriranje in iskanje
  • NoSQL-vrivanje - Ko razreševalci komunicirajo z MongoDB ali podobnimi bazami podatkov, je mogoče manipulirati strukture argumentov na osnovi JSON za vbrizgavanje operatorjev kot $gt, $regex ali $where

Razkritje informacij

Implementacije GraphQL pogosto uhajajo občutljive informacije prek obravnave napak in funkcij za razhroščevanje.

  • Podrobna sporočila o napakah - Podrobna sporočila o napakah lahko razkrijejo imena tabel baze podatkov, imena stolpcev, notranje URL-je storitev in informacije o tehnološkem skladu
  • Sledi sklada - Razvojne konfiguracije, po nesreči uvedene v produkcijo, izpostavljajo celotne sledi sklada s potmi do datotek, verzijami knjižnic in podrobnostmi notranje arhitekture
  • Način za razhroščevanje - Nekateri strežniki GraphQL izpostavljajo način za razhroščevanje, ki vrača načrte izvajanja poizvedb, časovne informacije razreševalcev in poizvedbe SQL, ki se izvajajo
  • Predlogi polj - Koristna sporočila o napakah, ki predlagajo veljavna imena polj, omogočajo rekonstrukcijo sheme tudi brez introspekcije

Metodologija testiranja po korakih

  1. Odkrijte končno točko - Poiščite pogoste poti: /graphql, /gql, /api/graphql, /v1/graphql. Preverite izvorne datoteke JavaScript za reference končnih točk
  2. Testirajte introspekcijo - Pošljite polno poizvedbo introspekcije in analizirajte celotno shemo. Če je onemogočena, poskusite z grobo silo polj z uporabo seznamov besed
  3. Preslikajte shemo - Uporabite GraphQL Voyager za vizualizacijo grafa tipov in prepoznavanje visoko vrednih ciljev: tipov uporabnikov, administrativnih mutacij, polj povezanih s plačili
  4. Testirajte overitev - Preverite, da vse poizvedbe, mutacije in naročnine zahtevajo ustrezno overitev. Testirajte s poteklimi, neveljavnimi in manjkajočimi žetoni
  5. Testirajte avtorizacijo - Za vsako poizvedbo in mutacijo testirajte dostop z različnimi uporabniškimi vlogami. Posebno pozornost posvetite poizvedbi node in razmerjem, ki presegajo meje avtorizacije
  6. Testirajte združevanje in vzdevke - Poskusite z grobo silo poverilnic in obvodom omejitve pogostosti zahtev z uporabo združenih poizvedb in operacij z vzdevki
  7. Testirajte kompleksnost poizvedb - Oblikujte globoko vgnezdene poizvedbe in merite odzivni čas strežnika ter porabo virov za prepoznavanje potenciala DoS
  8. Testirajte vbrizgavanje - Vbrizgajte vsebine SQL, NoSQL in ukaznega vbrizgavanja v vse argumente, zlasti parametre za filtriranje, iskanje in razvrščanje
  9. Analizirajte obravnavo napak - Pošljite napačno oblikovane poizvedbe in neveljavne vnose za preverjanje uhajanja informacij v odgovorih na napake
  10. Preglejte naročnine - Če so na voljo naročnine WebSocket, testirajte avtorizacijo in validacijo vnosov na vseh operacijah naročnin

Bistvena orodja

  • GraphQL Voyager - Interaktivna vizualizacija sheme, ki generira vizualni graf tipov in njihovih razmerij, neprecenljiva za razumevanje kompleksnih shem
  • InQL (razširitev za Burp Suite) - Avtomatizira introspekcijo GraphQL, generira poizvedbe za vse tipe in mutacije ter se integrira z Burp Scanner za avtomatizirano odkrivanje ranljivosti
  • Altair GraphQL Client - Zmogljivo razvojno okolje GraphQL s podporo za naročnine, nalaganje datotek in spremenljivke okolja, uporabno za ročno testiranje
  • graphql-cop - Orodje za varnostno revizijo, ki samodejno preverja pogoste napačne konfiguracije GraphQL, vključno z introspekcijo, predlogi polj, podporo za združevanje in omejitvami globine poizvedb
  • CrackQL - Namensko orodje za grobo silo poverilnic GraphQL z uporabo poizvedb z vzdevki

Priporočila za odpravo

  • Onemogočite introspekcijo v produkciji - To je najpomembnejši ukrep utrjevanja. Zagotovite, da je introspekcija onemogočena v vseh nerazvojnih okoljih
  • Uvedite omejevanje globine poizvedb - Nastavite maksimalno globino poizvedb (običajno 7-10 ravni) za preprečevanje napadov z globoko vgnezdenimi poizvedbami
  • Uporabite analizo kompleksnosti poizvedb - Dodelite ocene kompleksnosti poljem in nastavite maksimalno skupno kompleksnost na poizvedbo. Polja seznamov in polja z dragimi razreševalci naj imajo višje ocene
  • Uveljavljajte avtorizacijo na ravni polj - Uvedite preverjanja avtorizacije v vsakem razreševalcu, ne le na ravni poizvedbe ali mutacije. Uporabite pristop na osnovi vmesne programske opreme ali direktiv za doslednost
  • Omejite pogostost zahtev na ravni operacije - Štejte posamezne operacije znotraj združenih zahtev in uporabite omejitve pogostosti zahtev na operacijo, ne na zahtevo HTTP
  • Validirajte in očistite vse vnose - Obravnavajte argumente GraphQL z enako strogostjo kot katerikoli drug uporabniški vnos. Uporabite parametrizirane poizvedbe za vse interakcije z bazo podatkov
  • Uvedite ustrezno obravnavo napak - V produkciji vračajte generična sporočila o napakah. Nikoli ne izpostavljajte sledi sklada, napak baze podatkov ali notranjih podrobnosti sistema
  • Onemogočite predloge polj - Izklopite funkcijo "Ali ste mislili..." v produkciji za preprečevanje popisa sheme brez introspekcije

Sorodno branje: Avtorizacija API: odkrivanje in odprava BOLA/IDOR in Testiranje varnosti API: Praktični vodic.

Vid Grosek

Vid Grosek

Etični heker & Penetracijski tester

Pomagam slovenskim podjetjem odkriti varnostne ranljivosti, preden jih odkrijejo napadalci. Z več kot 18 leti izkušenj v kibernetski varnosti.

Vse objave

Komentarji

Ni še komentarjev. Bodite prvi!

Dodaj komentar

Vam je bil članek všeč?

Prijavite se na newsletter za mesečne varnostne vpoglede.

Prijavite se