Admin posistemis nesustabdo CSRF: keturi patikrinimai prieš paleidimą
Naujas prieglobos vardas yra naujas kilmės šaltinis, dažnai ta pati svetainė, todėl same-site slapukai ir paprastos formos jį peržengia. Patikrinkite žetonus, vartus ir autorizaciją.
Administravimo sąsajos perkėlimas į admin.example.com yra tikras pagerinimas: jis laiko administravimo slapukus toli nuo viešų puslapių, suteikia abiem programoms atskiras talpyklas ir leidžia griežtesnę tinklo politiką nukreipti į vieną prieglobos vardą. Bet tai nėra CSRF kontrolė ir nepadaro viešos svetainės kodo saugiu laikyti atidarytą prisijungusio administratoriaus akivaizdoje. Atskyrimas keičia tai, ką naršyklė laiko riba, o ne tai, ką tikrina serveris, todėl atlikite šiuos keturis patikrinimus prieš sakydami, kad baigta.
Skaitykite kilmę ir svetainę kaip du skirtingus žodžius
Kilmė yra schema, priegloba ir prievadas, todėl https://www.example.com ir https://admin.example.com yra skirtingos kilmės. Svetainė SameSite prasme yra schema plius registruojamas domenas, todėl tie du prieglobos vardai paprastai yra ta pati svetainė. Šis skirtumas ir yra visa spąstai: SameSite atributas nepadės tarp seserinių posistemių, nes naršyklė užklausos visai nelaiko tarp svetainių. Nukreipkite administravimo sąsają į tikrai kitą registruojamą domeną, pavyzdžiui, admin-example.net, ir užklausa tikrai taps tarp svetainių, ir ten SameSite=Lax arba Strict pradeda daryti darbą, kuriuo galima pasikliauti.
Išbandykite tai naršyklėje, o ne samprotaudami apie tai.
Įkelkite viešą svetainę, atidarykite kūrėjo įrankius ir pažiūrėkite, kuriuos slapukus naršyklė prideda prie užklausos administravimo prieglobai. Jei slapukas neturi Domain atributo, jis skirtas tik prieglobai ir lieka savo vardu; jei jis turi Domain=example.com, jis keliauja pas kiekvieną seserį, ir naujas posistemis tam slapukui nieko nedavė.
Atskirkite atsakymo skaitymą nuo užklausos siuntimo
Tos pačios kilmės politika riboja atsakymų skaitymą tarp kilmių. Ji nesustabdo užklausos siuntimo ir netrukdo formai perduoti kredencialų, kuriuos naršyklė jau turi. Paprasta užklausa, su formos turinio tipu ar paprastu GET, pristatoma be išankstinio patikrinimo; tada CORS nusprendžia, ar kviečiantis scenarijus gali skaityti atsakymą. CSRF gyvena visiškai siuntimo pusėje.
Todėl serveriui reikia aiškaus patikrinimo operacijoms, kurios keičia būseną. Su sesija susietas sinchronizavimo žetonas arba servere lyginamas dvigubo pateikimo slapukas apima tą atvejį; Origin arba Referer palyginimą verta pridėti kaip antrus vartus, bet ne kaip vienintelius, nes ne kiekviena užklausa neša antraštę ir ne kiekvienas tarpinis serveris ją išsaugo. OWASP CSRF prevencijos gairės SameSite laiko vienu sluoksniu tarp kelių būtent dėl šios priežasties.
Nuspręskite, ką tinklo vartai iš tikrųjų įrodo
VPN išėjimų leidimų sąrašas prieš administravimo prieglobą yra gera kontrolė ir silpnas tapatybės teiginys. Jis įrodo, kad užklausa atėjo iš adreso, kurį suteikia VPN, kurį gali dalytis visi tame išėjime, ir nieko nesako apie tai, kuris asmuo ar įrenginys yra už jo. Traktuokite jį kaip įėjimo filtrą, o ne kaip autentifikaciją.
Laikykite jį nepriklausomą nuo užklausos lygio patikrinimų. Jei sąrašas yra vienintelis dalykas tarp užpuoliko ir būseną keičiančio galinio taško, vienas neteisingai sukonfigūruotas maršrutas, vienas split-tunnel klientas ar vienas pasiskolintas nešiojamas kompiuteris visiškai panaikina kontrolę.
Registruokite ir atmetimus už numatomų diapazonų. Jų protrūkis yra naudingiausias signalas, kad kažkas zondavo ką tik pastatytą ribą, o tyla yra signalas, kad filtras visai nepasiekiamas.
Laikykite slapukus, prisijungimą ir autorizaciją aiškius
Slapuko apimtis nusprendžia didžiąją dalį rezultato. Pagrindinio domeno slapukas siunčiamas administravimo prieglobai, todėl scenarijaus įterpimas viešoje svetainėje gali veikti administratoriaus sesija; slapukas tik prieglobai to negali. Rinkitės tik prieglobos formą, pridėkite Secure atributą ir naudokite __Host- priešdėlį ten, kur platforma jį palaiko, nes šis priešdėlis reikalauja Secure, Path=/ ir jokio Domain atributo. Skaitykite atsakymo antraštę, o ne slapukų stiklainį: Set-Cookie: __Host-admin_session=...; Secure; Path=/; HttpOnly; SameSite=Lax, be Domain atributo. Naršyklė išmeta __Host- slapuką su Domain, todėl slapukas, kuris vis dar matomas seserinėse prieglobose, yra įrodymas, kad priešdėlis niekada nebuvo pritaikytas.
Tada laikykite autorizaciją serveryje, kiekvienai užklausai, kiekviename administravimo galiniame taške, ne tik prisijungiant. Užklausa iš leidžiamo tinklo vis tiek turi būti autentifikuota ir autorizuota operacijai, kurios ji prašo; prieglobos vardas nėra veikėjas. Jei viešoji ir administravimo programos bendrina prisijungimo srautą arba sesijų saugyklą, užrašykite tą ryšį, nes tai trumpiausias kelias nuo viešos svetainės klaidos iki administravimo veiksmo.
Dar kartą patikrinkite ribą po atskyrimo
Paleiskite neigiamus testus, ne tik laimingą kelią: forma tarp svetainių be žetono turi būti atmesta, žetonas iš kitos sesijos turi būti atmestas ir joks GET neturi keisti būsenos. Patikrinkite slapukų atributus kūrėjo įrankiuose, patvirtinkite, kad Origin patikrinimas suveikia su neatitinkančia užklausa, ir išbandykite administravimo prieglobą už VPN diapazono, kad pamatytumėte filtrą veikiant.
Niekas iš to nepanaikina XSS trūkumo pačioje administravimo programoje. Atskiras prieglobos vardas yra naršyklės pusės izoliacijos riba, turinti tikrą vertę, ir ji nepakeičia nesaugaus kodo vykdymo prevencijos ar serverio pusės užklausų apsaugos. Po atskyrimo sąrašas trumpesnis, nei atrodo: skirtinga kilmė, slapukai tik prieglobai, žetonas prie kiekvieno pakeitimo, įėjimo filtras, kuriuo nepasitikite kaip tapatybe, ir kiekvienai užklausai nusprendžiama autorizacija.