Å legge administrasjonsgrensesnittet på admin.example.com er en reell forbedring: det holder administrasjonskapsler borte fra offentlige sider, gir begge applikasjonene separate hurtiglagre og lar deg målrettet styre en strengere nettverkspolicy mot ett vertsnavn. Det er likevel ingen CSRF-kontroll, og det gjør ikke koden på det offentlige nettstedet trygg å la stå åpen foran en administrator som er logget inn. Splitten flytter hva nettleseren oppfatter som en grense, ikke hva tjeneren sjekker, så gjør disse fire kontrollene før du erklærer det ferdig.

Behandle origin og nettsted som to forskjellige begreper

Origin betyr skjema, vert og port, så https://www.example.com og https://admin.example.com er to forskjellige opphav. Nettsted i SameSite-betydning er skjema pluss registrerbart domene, så de to vertsnavnene er som regel samme nettsted. Nettopp denne forskjellen er fellen: SameSite-attributtet hjelper deg ikke på tvers av søsterunderdomener, fordi nettleseren ikke regner forespørselen som kryssnettsted i det hele tatt. Pek administrasjonsgrensesnittet mot et virkelig annet registrerbart domene, for eksempel admin-example.net, og forespørselen blir faktisk kryssnettsted, og der begynner SameSite=Lax eller Strict å gjøre arbeid du kan regne med.

Prøv det i nettleseren framfor å tenke deg fram.

Åpne det offentlige nettstedet, slå på utviklerverktøyene og se hvilke kapsler nettleseren henger på en forespørsel mot administrasjonsverten. Mangler kapselen Domain-attributt, gjelder den bare verten og blir værende på sitt eget navn; har den Domain=example.com, reiser den til hver søster, og det nye underdomenet ga deg ingenting for den kapselen.

Skille det å lese svaret fra det å sende forespørselen

Samme-origin-policyen begrenser lesing av svar på tvers av opphav. Den stopper ikke at en forespørsel sendes, og den hindrer ikke at et skjema tar med påloggingsinformasjon nettleseren allerede sitter på. En enkel forespørsel, med skjemaets innholdstype eller en vanlig GET, leveres uten forhåndskontroll; deretter avgjør CORS om skriptet som kaller får lese svaret. CSRF lever utelukkende på sendesiden.

Derfor trenger tjeneren en uttrykkelig kontroll for operasjoner som endrer tilstand. Et synkroniseringstoken knyttet til økten, eller en kapsel med dobbel innsending som sammenlignes på tjeneren, dekker tilfellet; en Origin- eller Referer-sammenligning er verdt å ha som en andre port, men ikke som den eneste, fordi ikke hver forespørsel bærer headeren og ikke hver proxy bevarer den. OWASPs veiledning mot CSRF behandler SameSite som ett lag blant flere, nettopp av denne grunnen.

Avgjør hva nettverksporten faktisk beviser

En liste over tillatte VPN-utganger foran administrasjonsverten er god kontroll og en svak identitetspåstand. Den beviser at forespørselen kom fra en adresse VPN deler ut, som alle på den utgangen kan bruke samtidig, og den sier ingenting om hvilken person eller enhet som står bak. Behandle den som et inngangsfilter, ikke som autentisering.

Hold den uavhengig av kontrollene på forespørselsnivå. Er listen det eneste som står mellom en angriper og et tilstandsendrende endepunkt, fjerner én feilkonfigurert rute, én split-tunnel-klient eller én lånt maskin kontrollen fullstendig.

Logg også avvisninger utenfor de forventede intervallene. En bølge av dem er det nyttigste signalet om at noen undersøker grensen du nettopp bygde, og stillhet er signalet om at filteret ikke nås i det hele tatt.

Hold kapsler, innlogging og autorisasjon uttrykkelige

Kapselens omfang avgjør mesteparten av utfallet. En kapsel på foreldredomenet sendes til administrasjonsverten, så en skriptinjeksjon på det offentlige nettstedet kan handle med en administratorens økt; en kapsel som bare gjelder verten kan ikke det. Velg formen som bare gjelder verten, legg til Secure-attributtet og bruk prefikset __Host- der plattformen støtter det, fordi prefikset krever Secure, Path=/ og ingen Domain-attributt. Les svarheaderen i stedet for kapselglasset: Set-Cookie: __Host-admin_session=...; Secure; Path=/; HttpOnly; SameSite=Lax, uten Domain-attributt. Nettleseren forkaster en __Host--kapsel som har Domain, så en kapsel som fortsatt dukker opp på søsterverter er bevis for at prefikset aldri ble tatt i bruk.

Hold så autorisasjonen på tjeneren, per forespørsel, på hvert administrasjonsendepunkt, ikke bare ved innlogging. En forespørsel fra et tillatt nettverk må fortsatt autentiseres og autoriseres for operasjonen den ber om; vertsnavnet er ingen aktør. Deler den offentlige og den administrative applikasjonen innloggingsflyt eller øktlager, skriv ned dette forholdet, fordi det er den korteste veien fra en feil på det offentlige nettstedet til en administrativ handling.

Kontroller grensen på nytt etter splitten

Kjør de negative testene, ikke bare solskinnsveien: et kryssnettstedsskjema uten token skal avvises, et token fra en annen økt skal avvises, og ingen GET skal endre tilstand. Sjekk kapselattributtene i utviklerverktøyene, bekreft at Origin-kontrollen slår til på en forespørsel som ikke passer, og prøv administrasjonsverten utenfor VPN-området for å se filteret i arbeid.

Ingenting av dette fjerner en XSS-feil inne i selve administrasjonsapplikasjonen. Et eget vertsnavn er en isolasjonsgrense på nettlesersiden med reell verdi, og det erstatter ikke vern mot utrygg kodekjøring eller beskyttelse av forespørsler på tjeneren. Etter splitten er listen kortere enn den ser ut: egen origin, kapsler bare for verten, et token ved hver endring, et inngangsfilter du ikke stoler på som identitet, og autorisasjon avgjort per forespørsel.

Relaterte artikler