Admin-undomænet stopper ikke CSRF: fire kontroller før lancering
Et nyt værtsnavn er en ny origin, ofte samme websted, så same-site-cookies og enkle formularer krydser det. Kontrollér tokens, gaten og autorisationen.
At flytte administrationsgrænsefladen til admin.example.com er en reel forbedring: det holder admin-cookies væk fra offentlige sider, giver de to applikationer hver sin cache og lader dig rette en strengere netværkspolitik mod ét værtsnavn. Det er ikke en CSRF-kontrol, og det gør ikke den offentlige sides kode sikker at holde åben for en administrator, der er logget ind. Opdelingen ændrer, hvad browseren betragter som en grænse, ikke hvad serveren kontrollerer, så gennemfør disse fire kontroller, før du kalder det færdigt.
Læs origin og websted som to forskellige ord
En origin er skema, vært og port, så https://www.example.com og https://admin.example.com er forskellige origins. Et websted, i SameSite-forstand, er skema plus registrerbart domæne, så de to værtsnavne er normalt samme websted. Forskellen er hele fælden: SameSite-attributten hjælper dig ikke på tværs af søsterundomæner, fordi browseren slet ikke betragter anmodningen som cross-site. Ret administrationsgrænsefladen mod et virkeligt andet registrerbart domæne, for eksempel admin-example.net, og anmodningen bliver faktisk cross-site, og det er dér, SameSite=Lax eller Strict begynder at gøre arbejde, du kan stole på.
Test det i browseren i stedet for at ræsonnere om det.
Indlæs den offentlige side, åbn udviklerværktøjerne, og se, hvilke cookies browseren knytter til en anmodning mod admin-værten. Hvis cookien ikke har et Domain-attribut, er den kun for værten og bliver på sit eget navn; hvis den bærer Domain=example.com, rejser den til hver søster, og det nye underdomæne har ikke givet dig noget for den cookie.
Adskil kan læse svaret fra kan sende anmodningen
Same-origin-politikken begrænser læsning af svar på tværs af origins. Den stopper ikke en anmodning i at blive sendt, og den stopper ikke en formular i at bære legitimationsoplysninger, som browseren allerede har. En simpel anmodning, en med en formular-indholdstype eller et almindeligt GET, leveres uden forhåndskontrol; CORS afgør derefter, om det kaldende script må læse svaret. CSRF lever helt på afsendelsessiden.
Derfor har serveren brug for en eksplicit kontrol for tilstandændrende handlinger. Et synkroniseringstoken bundet til sessionen, eller en cookie med dobbelt afsendelse sammenlignet på serveren, dækker tilfældet; en Origin- eller Referer-sammenligning er værd at tilføje som en anden gate, men ikke som den eneste, fordi ikke enhver anmodning bærer headeren, og ikke enhver proxy bevarer den. OWASPs vejledning i at forebygge CSRF behandler SameSite som et lag blandt flere netop af den grund.
Afgør, hvad netværksgaten faktisk beviser
En allowlist over VPN-udgange foran admin-værten er en god kontrol og en svag identitetspåstand. Den beviser, at anmodningen kom fra en adresse, VPN uddeler, som kan deles af alle på den udgang, og den siger intet om, hvilken person eller enhed der står bag. Behandl den som et indgangsfilter, ikke som autentifikation.
Hold den uafhængig af kontrollerne på anmodningsniveau. Hvis listen er det eneste mellem en angriber og et tilstandændrende endepunkt, fjerner én fejlkonfigureret rute, én split-tunnel-klient eller én lånt bærbar computer kontrollen helt.
Log også afvisninger uden for de forventede intervaller. En byge af dem er det mest nyttige signal om, at nogen undersøger den grænse, du netop har bygget, og stilhed er signalet om, at filteret slet ikke nås.
Hold cookies, login og autorisation eksplicitte
Cookiens omfang afgør det meste af resultatet. En cookie for forældredomænet sendes til admin-værten, så en scriptinjektion på den offentlige side kan handle med en administrators session; en cookie kun for værten kan ikke. Foretræk formen kun for værten, tilføj attributten Secure, og brug præfikset __Host-, hvor platformen understøtter det, fordi præfikset kræver Secure, Path=/ og intet Domain-attribut. Læs svarheaderen i stedet for cookiekrukken: Set-Cookie: __Host-admin_session=...; Secure; Path=/; HttpOnly; SameSite=Lax, uden Domain-attribut. En browser kasserer en __Host--cookie med Domain, så en cookie, der stadig vises på søsterværter, er bevis for, at præfikset aldrig blev anvendt.
Hold derefter autorisationen på serveren, pr. anmodning, på hvert administrativt endepunkt, ikke kun ved login. En anmodning fra et tilladt netværk skal stadig autentificeres og autoriseres til den handling, den beder om; værtsnavnet er ikke en aktør. Hvis den offentlige og den administrative applikation deler et loginflow eller et sessionslager, så skriv det forhold ned, fordi det er den korteste vej fra en fejl på den offentlige side til en administrativ handling.
Kontrollér grænsen igen efter opdelingen
Kør de negative tests, ikke kun den glade vej: en cross-site-formular uden token skal afvises, et token fra en anden session skal afvises, og ingen GET må ændre tilstand. Kontrollér cookieattributterne i udviklerværktøjerne, bekræft, at Origin-kontrollen udløses på en anmodning, der ikke matcher, og prøv admin-værten uden for VPN-intervallet for at se filteret virke.
Intet af dette fjerner en XSS-fejl inde i selve den administrative applikation. Et separat værtsnavn er en isolationsgrænse på browsersiden med reel værdi, og det er ikke en erstatning for at forhindre usikker kodeudførelse eller for at beskytte anmodninger på serversiden. Efter opdelingen er tjeklisten kortere, end den ser ud: en særskilt origin, cookies kun for værten, et token ved hver ændring, et indgangsfilter, du ikke stoler på som identitet, og autorisation afgjort pr. anmodning.