Fölsun beiðna milli vefja
Vafrar senda kökur gjarnan með sjálfvirkum hætti. Af þeim sökum þurfum við sem betur fer ekki að skeyta lotuauðkenninu handvirkt við sérhvern tengil að innskráningu lokinni. Sú sjálfvirkni sem þarna býr að baki skapar hins vegar nýstárlegt viðfangsefni í gagnaglímum: Síða á einu vefsvæði getur hæglega knúið vafrann til þess að senda beiðni á annað vefsvæði, og þá með lotuköku markvefsins með í för.
Ef beiðnin breytir ástandi án frekari sönnunar getur komið upp fölsun beiðna milli vefja (e. cross-site request forgery, CSRF). Hér ber að hafa hugfast að árásarsíðan þarf síst af öllu að geta lesið svarið; það eitt að markvefurinn framkvæmi sjálfa aðgerðina dugar fyllilega til.
Verkefnið Litaskipti styðst við sakleysislega gervistillingu. Þú hefur leikinn á því að opna verkefnið til þess að hljóta lotuköku, en því næst opnar þú hnitmiðaða HTML-skrá úr algerlega öðru samhengi og fylgir þar tengli sem hlutast til um litabreytinguna. Snúir þú aftur að verkefninu mun stillingasíðan þá opinbera lokafánann.
Aðeins gervistilling verkefnisins
Notaðu aðeins handout-skrána og litastillinguna í þessu verkefni. Ekki smíða beiðnir sem breyta raunverulegum reikningum, netföngum, aðgangsorðum eða greiðslum. Verkefnið notar sýnilega tengilleiðsögn og enga fórnarlambshermun.
Sjálfvirk aðgangsgögn
Við svo búið, að vefurinn hafi komið lotuköku fyrir, gæti hefðbundin beiðni tekið á sig þessa mynd:
GET /settings HTTP/1.1
Host: nordurmarkadur.example
Cookie: sid=abc123
Notandinn átti engan þátt í því að rita sjálfan Cookie-hausinn. Vafrinn valdi kökuna einvörðungu á grundvelli hýsis, slóðar og eiginleika á borð við Secure og SameSite.
CSRF-veikleikar verða einkar áhugaverðir hvenær sem aðgangsgögn fylgja beiðnum með sjálfvirkum hætti. Kökur eru þar skýrasta dæmið, en jafnframt má nefna HTTP-auðkenningu eða vottorð biðlara í ákveðnum tilvikum. Tákn, sem JavaScript-kóði grefur upp úr localStorage og kemur handvirkt fyrir í Authorization-haus, fylgir hins vegar aldrei venjulegum tenglum á milli vefsvæða af sjálfu sér.
Hagnýta spurningin er því:
Hvað nákvæmlega fær vafrann til þess að láta gögn fylgja beiðni, án þess að upprunasíðan sjálf þurfi að hafa nokkurt nánara kyn af leyndarmálinu?
Einfalt CSRF-flæði
Hér má greina fjögur meginskref í þessu ferli:
1. notandi býr yfir gildri gervilotu hjá markvefnum
2. notandi opnar síðu eða smellir á tengil sem á uppruna sinn á öðru vefsvæði
3. vafrinn varpar fram beiðni á markvefinn og gætir þess að láta allar leyfðar kökur fylgja með í för
4. markvefurinn tekur við og framkvæmir hina tilætluðu ástandsbreytandi aðgerð
Ástandsbreytandi beiðni (e. state-changing request) breytir gögnum eða stöðu: litastillingu, netfangi, pöntun eða öðru sem lifir lengur en svarið sjálft.
Í verkefninu Litaskipti hefur beiðninni verið sniðinn afar einfaldur stakkur:
GET /settings/color?value=flag HTTP/1.1
Host: <hýsir verkefnisins>
Cookie: sid=<gervilota þín>
Sú síða sem við deilum með ykkur (e. handout) hefur enga vitneskju um gildið sid. Vafrinn sér hins vegar alfarið um að geyma kökuna og kveða á um hvort hún skuli fylgja með þegar smellt er á tengilinn.
Af hverju krossvefjasíðan þarf ekki að lesa svarið
Sama-upprunareglan leggur vitaskuld ákveðnar hömlur á það hvernig JavaScript-kóði á einum stað getur lesið svör frá öðrum. Hún rís þó engan veginn sem óhagganlegur múr gegn hvers kyns beiðnum á milli ólíkra vefsvæða. Vafranum er til að mynda fyllilega heimilt að fylgja tenglum, hlaða inn myndum eða senda frá sér hefðbundin HTML-eyðublöð.
Þó svo að árásarsíðunni reynist með öllu ómögulegt að komast yfir textann:
Litur uppfærður.
þá breytist sjálf stillingin engu að síður. CSRF-veikleikinn tekur þannig mið af raunverulegum áhrifum beiðninnar, en snýst síst af öllu um hvort árásarsíðan hljóti sjálf lesaðgang að svarinu.
Þarna skilur á milli feigs og ófeigs, eða öllu heldur á milli CSRF og hinna fjölmörgu CORS-vandamála. CORS stýrir að miklu leyti hvort JavaScript fær að lesa krossupprunasvar og hvort tiltekin skriftuð beiðni fær að fara. Tenglar og hefðbundin HTML-eyðublöð telst til fornra vafraeiginleika sem búa yfir þeim mætti að senda beiðnir, án þess þó að upprunasíðan fái nokkurn tíma gæst ofan í sjálfan svarlíkamann.
Ástandsbreytandi GET
Þótt GET-aðferðinni sé að jafnaði ætlað það hlutverk að sækja gögn, þá neyða samskiptareglurnar forrit engan veginn til að fylgja þeirri hefð af einskærri hlýðni. Vefur gæti hæglega tekið upp á því að breyta stillingum á vafasaman hátt með eftirfarandi hætti:
/settings/color?value=blue
Slíkri slóð reynist sérstaklega auðvelt að koma fyrir í tengli:
<a href="https://nordurmarkadur.example/settings/color?value=blue">
Opna litakort
</a>
Smelli notandinn á tengilinn, flyst markvefurinn yfir í æðsta stig vafrans (e. top-level). Stillingin SameSite=Lax heimilar oft á tíðum að kakan fylgi slíkri leiðsögn, svo fremi sem stuðst sé við örugga HTTP-aðferð á borð við GET.
Þótt aðgerðin styðjist við POST-aðferðina, þá lokar það alls ekki sjálfkrafa fyrir möguleikann á CSRF-falsönum. Öðru vefsvæði reynist í lófa lagið að smíða eigið HTML-eyðublað:
<form action="https://nordurmarkadur.example/settings/color" method="post">
<input type="hidden" name="value" value="blue">
<button type="submit">Opna litakort</button>
</form>
Vafranum é fyllilega fært að senda eyðublaðið á sniðinu application/x-www-form-urlencoded. Í raun skilur þarna aðeins á milli sjálf beiðniaðferðin og snið líkamans; markvefurinn stendur samt sem áður frammi fyrir því verkefni að greina hvort beiðnin eigi í raun erindi í lögmætt ferli.
Í okkar verkefni munum við láta okkur nægja að styðjast við sýnilegan smell. Sjálfvirk sending eyðublaða myndi í þessu tilfelli engu bæta við sjálft námsmarkmiðið, heldur gæti hún fremur gert atferli vafrans öllu óskýrara í augum nemandans.
SameSite og vefsvæði
Eiginleikinn SameSite ræður því hvenær köku er heimilt að fylgja beiðni sem á upptök sín á öðru vefsvæði (e. site).
| Gildi | Einföld byrjendatúlkun |
|---|---|
Strict |
Kakan fylgir almennt ekki krossvefja beiðnum |
Lax |
Kakan getur fylgt ákveðinni toppstigsleiðsögn, einkum GET |
None |
Kakan má fylgja krossvefja beiðnum; nútímavafrar krefjast einnig Secure |
Rétt er að hafa í huga að hugtakið vefsvæði fellur alls ekki nákvæmlega saman við hugtakið uppruni. Tveir hýsar geta verið af ólíkum uppruna en talist sama vefsvæði samkvæmt vafrareglum. Við þurfum engan veginn að sökkva okkur ofan í útreikninga á skráningarhæfum lénum í þessum kafla; DevTools-glugginn mun fúslega ljóstra því upp hvort kakan hafi raunverulega fylgt beiðninni eftir.
Bregðist CSRF-prófun þín skaltu staldra við og rýna í Network-flipann. Var beiðninni varpað af stað? Var Cookie-hausnum örugglega með í för? Gáfu Console- eða Issues-fliparnir ef til vill til kynna að vafrinn hefði hreinlega girt fyrir köku frá þriðja aðila? Slík rannsóknarvinna er langtum vænlegri en að giska í blindni á að þjónninn hafi vísað aðgerðinni á bug.
Verkefnið Litaskipti styðst við SameSite=Lax og GET-tengil á æðsta stigi til þess að tryggja að atferlið verði mun fyrirsjáanlegra en ef um ræddi ósýnilega mynd frá þriðja aðila.
CSRF-tákn
CSRF-tákn (e. CSRF token) telst vera ófyrirsjáanlegt gildi sem lögmæt síða kemur fyrir í eyðublaði eða beiðni, og þjónninn nýtir svo til þess að tengja viðeigandi lotu eða aðgerð órjúfanlegum böndum:
<input type="hidden" name="csrf_token" value="RANDOMT_GILDI">
Lögmæt beiðni ber þá bæði kökuna og reitinn:
POST /settings/color HTTP/1.1
Cookie: sid=abc123
Content-Type: application/x-www-form-urlencoded
value=blue&csrf_token=RANDOMT_GILDI
Vefsíðu á öðru svæði er vissulega fært að knýja vafrann til þess að senda kökuna, en sama-upprunareglan stendur þar sem vörður og kemur að öllu jöfnu í veg fyrir að henni takist að rýna í eyðublaðið og hrifsa þannig til sín táknið úr markvefnum.
Í CTF skaltu skoða hvort táknið sé:
- til staðar í lögmætri beiðni,
- bundið við sömu gervilotu,
- í raun sannreynt,
- og nauðsynlegt fyrir allar sambærilegar aðferðir eða slóðir.
Sú staðreynd að formreitur sé falinn felur alls ekki í sér sjálfvirka vörn. Sýni það sig að þjónninn láti sér lynda hvaða gildi sem er, sætti sig við tómt gildi eða jafnvel tákn sem hrifsað hefur verið úr annarri tilbúinni lotu, verður sjálf athugunin að teljast afar veikburða. Slík próf nota aðeins gervireikninga sem verkefnið gefur.
Litaskipti hefur ekkert CSRF-tákn; það er viljandi grunnverkefni.
Origin og Referer
Vafri setur oft Origin-haus á ástandsbreytandi beiðnir:
Origin: https://annad.example
Hausinn Referer getur svo varpað enn skýrara ljósi á hina nákvæmu upphafsslóð, allt eftir því hvaða stefnu vafrinn sjálfur fylgir hverju sinni:
Referer: https://annad.example/attack.html
Nemi þjónninn staðar og beri þessa hausa saman við sinn eigin uppruna, getur krossvefjabeiðni hæglega mætt höfnun. Í Repeater má breyta texta hauss, en það sýnir ekki hvort raunverulegur vafri árásarsíðu geti gert það; Origin er vafrastýrður haus sem venjulegt JavaScript fær ekki frjálst að falsa.
Í CTF skaltu því greina tvær spurningar:
- Hvað samþykkir HTTP-endapunkturinn í Repeater?
- Hvaða beiðni getur vafrinn raunverulega myndað frá öðru samhengi?
Verkefnið verður að vera unnt að leysa inni í vafra, en ekki einungis með tilstilli einhvers óraunhæfs hauss sem Repeater leyfir þér að rita.
JSON, sérsniðnir hausar og forkönnun
Hefðbundnu HTML-eyðublaði er fært að senda nokkur af hinum hefðbundnu líkamasniðum, en því reynist með öllu ómögulegt að varpa fram application/json með sérsniðnum haus. Hlaupi JavaScript-kóði hins vegar til og freisti þess að senda slíka krossupprunabeiðni (e. cross-origin request), gæti það kallað fram svokallaða CORS-forkönnun (e. CORS preflight) með OPTIONS-aðferðinni.
Krefjist forritaskilin (API) hvort tveggja; JSON-gagna og sérsniðins hauss, og hafni jafnframt forkönnun frá öðrum uppruna, má telja einfalt HTML-eyðublað fremur ólíklegt sem vopn í CSRF-árás. Athugaðu samt hvort önnur leið taki við formgögnum, hvort GET breyti sama ástandi eða hvort þjónninn les JSON án réttrar Content-Type.
Varastu að ganga út frá því sem gefnu að hugtakið „API“ feli sjálfkrafa í sér friðhelgi gagnvart CSRF-falsönum. Reyndu heldur að rekja sjálft aðgangsgagnið og þá beiðni sem vafranum er í raun kleift að senda.
Tengsl XSS, CORS og CSRF
Hafa ber í huga að þessi þrjú hugtök eiga það gjarnan til að flækjast fyrir mönnum:
| Hugtak | Meginspurning |
|---|---|
| XSS | Getur ótraustur texti orðið að kóða í uppruna markvefsins? |
| CSRF | Getur annað vefsvæði fengið vafra með gilda lotu til að senda ástandsbreytandi beiðni? |
| CORS | Má JavaScript frá öðrum uppruna lesa svar eða senda ákveðna skriftaða beiðni? |
JavaScript-kóði í XSS-árás keyrir innan uppruna markvefsins. Því reynist honum oft leikur einn að lesa CSRF-tákn beint úr DOM-trénu og senda beiðni frá sama uppruna. XSS-veikleiki getur þannig gert margvíslegar CSRF-varnir algjörlega máttlausar gagnvart viðkomandi lotu.
Hitt er svo annað mál, að CSRF-falsanir útheimta alls ekki tilvist XSS-veikleika. Stakur tengill eða eyðublað á algerlega annarri síðu getur dugað fyllilega til, svo fremi sem vafrinn sjálfur sendir kökuna og markvefurinn gerir hvorki kröfu um tákn né heldur sönnun á uppruna.
Þótt CORS-reglur neiti lesaðgangi, kemur það síður en svo í veg fyrir að HTML-eyðublað eða leiðsögn vafrans varpi fram beiðni. Sama-upprunareglunni getur nefnilega tekist að verja sjálfan svarlíkamann, jafnvel þótt aðgerðin sjálf hafi fyllilega heppnast.
Göngudæmi: Litaskipti
Hefðu nú leikinn á því að opna hið lifandi verkefni og halda rakleiðis á /settings. Veldu þar hefðbundinn lit í viðmótinu og rýndu í beiðnina inni í Network-flipanum. Gakktu úr skugga um að litabreytingin fari fram með GET-aðferðinni, þar sem gildið value hvílir í fyrirspurnarstrengnum, og að gervilotukakan fylgi snyrtilega með í för.
Sæktu attack.html úr challenge-kortinu og opnaðu skrána í sama vafra. Skráin biður um grunnslóð verkefnisins og býr til sýnilegan tengil. Athugaðu tengilinn áður en þú smellir: hann á aðeins að vísa á úthlutaða verkefnið og stilla gildið flag.
Láttu nú vafrann vaða af stað og smelltu á tengilinn. Vafrinn mun þá færast yfir á æðsta stig (e. top-level) yfir á verkefnið og senda með sér hina leyfðu SameSite=Lax-kökuna. Farðu síðan á /settings ef framsendingin gerir það ekki sjálfkrafa. Ef liturinn breyttist í verkefnisgildið birtist fáninn.
Inni í Network-flipanum gefst þér kostur á að bera krossvefjabeiðnina saman við hversdagslega litabreytingu. Þar muntu sjá að slóðin, aðferðin og sjálf kakan eru keimlík, þó svo að upphafssamhengið sé af allt öðrum toga. Gættu þess að hafa í huga að sjálf áskorunarskráin (handout) hafði hvorki kynni af lotuauðkenninu né var hún fær um að lesa það.
Birtist fáninn þér ekki, skaltu fyrst og fremst ganga úr skugga um hvort áskorunarskráin hafi verið opnuð í nákvæmlega sama vafraprófíl og sjálf gervilotan. Kannaðu einnig hvort kakan hafi sannanlega fylgt með og hvort grunnslóðin hafi verið rituð með réttum hætti. Vinsamlegast stilltu þig um að eiga samtímis við SameSite-stillingar, falsaða hausa og sjálfa beiðniaðferðina.
Vísbendingar gegn veikleikum
Krefjist leiðin, sem breytir ástandi kerfisins, einhvers konar ófyrirsjáanlegs og lotubundins tákns sem krossvefjasíðunni reynist með öllu ómögulegt að lesa, má telja víst að einfalt eyðublað muni skila litlum árangri. Sömu sögu er að segja ef þjónninn leggur metnað sinn í að sannreyna hið vænta Origin-gildi, en hinn raunverulegi vafri sendir frá sér allt annan uppruna.
Stillingin SameSite=Strict, eða hrein og klár vafrablokkun sem kemur í veg fyrir að aðgangskakan fái að fylgja með í för, getur hæglega stöðvað tiltekna krossvefjabeiðni á miðri leið. Lax getur samt leyft toppstigs GET, svo skoðaðu aðferð og Network í stað þess að álykta aðeins út frá kökustillingunni.
Styðjist beiðnin einvörðungu við Authorization: Bearer ... hausinn, sem JavaScript-kóði grefur upp úr vafrageymslunni, og sé engri sjálfvirkri köku né annarri vafraauðkenningu fyrir að fara, má telja hefðbundnar CSRF-falsanir harla ólíklegar. Árásarsíðan situr þá einfaldlega ekki yfir sjálfu aðgangsgildinu til þess að geta komið því fyrir í hausnum.
Að síðustu verður að hafa hugfast að beiðnin verður að hafa raunveruleg áhrif. 200 OK-svar þar sem stillingar standa óhaggaðar færir okkur engar sönnur á CSRF-veikleika. Leggðu þig því fram um að sækja stöðuna aftur innan sömu gervilotu og sýna þannig fram á afmarkaða og skýra breytingu.
Samantekt
CSRF-veikleikar notfæra sér þá staðreynd að vafrar senda tiltekin aðgangsgögn frá sér með sjálfvirkum hætti. Öðru vefsvæði reynist því leikur einn að mynda tengil, koma fyrir mynd eða jafnvel varpa fram beiðni úr eyðublaði; markvefurinn sér þá hina gildu köku og gæti hæglega framkvæmt ástandsbreytingu, þrátt fyrir að upprunasíðunni sjálfri reynist með öllu ómögulegt að lesa svarið.
POST eitt og sér er ekki vísbending gegn tilgátu, því HTML-form getur sent POST. SameSite, lotubundin CSRF-tákn og athugun á Origin eða Referer breyta því hvaða vafrabeiðnir eru raunhæfar. JSON og sérsniðnir hausar geta kallað fram CORS-forkönnun, en skoða þarf allar leiðir sem breyta sama ástandi.
XSS-kóði keyrir ávallt innan uppruna markvefsins, á meðan CSRF-falsanir eiga rætur sínar að rekja til algerlega annarra vefsvæða. CORS-reglur annast svo stjórnun á lestri og ákveðnum skrifuðum beiðnum á milli ólíkra uppruna (e. cross-origin). Í eftirfarandi kafla munum við færa okkur frá vafrareglum yfir á vit ófyrirsjáanlegra viðskiptaraka (e. business logic): Þar munu þættir á borð við verðlagningu, magn, röðun skrefa og jafnvel kapphlaup á milli beiðna bera ofarlega á góma.