Admin-underdomenet stoppar ikkje CSRF: fire kontrollar før lansering
Eit nytt vertsnamn er ein ny origin, ofte same nettstad, så same-site-informasjonskapslar og enkle skjema kryssar det. Kontroller tokena, porten og autorisasjonen.
Å flytte administrasjonsgrensesnittet til admin.example.com er ei reell betring: det held admin-informasjonskapslar borte frå offentlege sider, gjev dei to applikasjonane kvar sin hurtigbuffer og lèt deg rette ein strengare nettverkspolitikk mot eitt vertsnamn. Men det er ikkje ein CSRF-kontroll, og det gjer ikkje koden på den offentlege nettstaden trygg å halde open framfor ein innlogga administrator. Oppdelinga endrar kva nettlesaren ser på som ei grense, ikkje kva tenaren kontrollerer, så gjer desse fire kontrollane før du seier det er ferdig.
Les origin og nettstad som to ulike ord
Ein origin er skjema, vert og port, så https://www.example.com og https://admin.example.com er ulike originar. Ein nettstad, i SameSite-forstand, er skjema pluss registrerbart domene, så dei to vertsnamna er vanlegvis same nettstad. Den skilnaden er heile fella: SameSite-attributtet hjelper deg ikkje mellom systerunderdomene, fordi nettlesaren ikkje reknar førespurnaden som kryssnettstad i det heile. Rett administrasjonsgrensesnittet mot eit verkeleg anna registrerbart domene, til dømes admin-example.net, og førespurnaden blir faktisk kryssnettstad, og det er der SameSite=Lax eller Strict byrjar gjere arbeid du kan stole på.
Test det i nettlesaren i staden for å resonnere om det.
Last inn den offentlege nettstaden, opne utviklarverktøya og sjå kva informasjonskapslar nettlesaren festar til ein førespurnad mot admin-verten. Har kapselen ikkje Domain-attributt, er han berre for verten og blir på sitt eige namn; ber han Domain=example.com, reiser han til kvar syster, og det nye underdomenet gav deg ingenting for den kapselen.
Skil lesing av svaret frå sending av førespurnaden
Same-origin-policyen avgrensar lesing av svar på tvers av originar. Han stoppar ikkje ein førespurnad frå å bli send, og han hindrar ikkje eit skjema i å bere påloggingsdata nettlesaren alt har. Ein enkel førespurnad, med skjemaets innhaldstype eller ein vanleg GET, blir levert utan førehandskontroll; CORS avgjer deretter om skriptet som kallar får lese svaret. CSRF lever heilt på sendesida.
Difor treng tenaren ein eksplisitt kontroll for tilstandsendrande operasjonar. Eit synkroniseringstoken bunde til økta, eller ein informasjonskapsel med dobbel innsending samanlikna på tenaren, dekkjer tilfellet; ein Origin- eller Referer-samanlikning er verd å leggje til som ein andre port, men ikkje som den einaste, fordi ikkje kvar førespurnad ber headeren og ikkje kvar proxy tek vare på han. OWASPs rettleiding for å hindre CSRF ser på SameSite som eitt lag blant fleire nettopp av denne grunnen.
Avgjer kva nettverksporten eigentleg provar
Ei tillaten-liste over VPN-utgangar framfor admin-verten er god kontroll og ein svak identitetspåstand. Ho provar at førespurnaden kom frå ei adresse VPN deler ut, som kan delast av alle på den utgangen, og ho seier ingenting om kva person eller eining som står bak. Handsame henne som eit inngangsfilter, ikkje som autentisering.
Hald henne uavhengig av kontrollane på førespurnadsnivå. Om lista er det einaste mellom ein åtakar og eit tilstandsendrande endepunkt, fjernar éin feilkonfigurert rute, éin split-tunnel-klient eller éin lånt berbar PC kontrollen heilt.
Logg òg avvisingar utanfor dei venta områda. Ei byge av dei er det mest nyttige signalet om at nokon granskar grensa du nettopp bygde, og stille er signalet om at filteret ikkje blir nådd i det heile.
Hald informasjonskapslar, innlogging og autorisasjon eksplisitte
Omfanget av kapselen avgjer det meste av resultatet. Ein kapsel for foreldredomenet blir send til admin-verten, så ein skriptinjeksjon på den offentlege nettstaden kan handle med økta til ein administrator; ein kapsel berre for verten kan ikkje. Føretrekk forma berre for verten, legg til Secure-attributtet og bruk prefikset __Host- der plattforma støttar det, fordi prefikset krev Secure, Path=/ og ingen Domain-attributt. Les svarheaderen i staden for kapselglasset: Set-Cookie: __Host-admin_session=...; Secure; Path=/; HttpOnly; SameSite=Lax, utan Domain-attributt. Ein nettlesar kastar ein __Host--kapsel med Domain, så ein kapsel som framleis blir sett på systervertar er prov på at prefikset aldri vart brukt.
Hald deretter autorisasjonen på tenaren, per førespurnad, på kvart administrativt endepunkt, ikkje berre ved innlogging. Ein førespurnad frå eit tillate nettverk må framleis autentiserast og autoriserast for operasjonen han ber om; vertsnamnet er ikkje ein aktør. Om den offentlege og den administrative applikasjonen deler ein innloggingsflyt eller eit øktlager, skriv ned det tilhøvet, fordi det er den kortaste vegen frå ein feil på den offentlege nettstaden til ei administrativ handling.
Kontroller grensa på nytt etter oppdelinga
Køyr dei negative testane, ikkje berre den lukkelege vegen: eit kryssnettstadsskjema utan token skal avvisast, eit token frå ei anna økt skal avvisast, og ingen GET skal endre tilstand. Kontroller kapselattributta i utviklarverktøya, stadfest at Origin-kontrollen slår ut på ein førespurnad som ikkje stemmer, og prøv admin-verten utanfor VPN-området for å sjå filteret verke.
Ingenting av dette fjernar ein XSS-feil inne i sjølve administrasjonsapplikasjonen. Eit separat vertsnamn er ei isolasjonsgrense på nettlesarsida med reell verdi, og det er ikkje ei erstatning for å hindre utrygg køyreing av kode eller for å verne førespurnader på tenarsida. Etter oppdelinga er lista kortare enn ho ser ut: eigen origin, kapslar berre for verten, eit token ved kvar endring, eit inngangsfilter du ikkje stolar på som identitet, og autorisasjon avgjord per førespurnad.