Tilbake
7.2
Sikker programmering

7.2 Sikker programmering

OWASP Top 10, injeksjon, XSS og inputvalidering.

65 min
7 oppgaver
OWASPSQL-injeksjonXSSInputvalidering
Du leser den lesevennlige versjonen
Din fremgang i kapitlet
0 / 7 oppgaver

Aldri stol på brukerinput

Sikker programmering handler om å skrive kode som er motstandsdyktig mot angrep. Mange sikkerhetshull oppstår fordi utviklere stoler for mye på brukerinput eller glemmer grunnleggende tiltak. Det viktigste prinsippet kan derfor oppsummeres i én setning: aldri stol på brukerinput.

All data fra brukere – fra skjemaer, URL-parametere, cookies eller filer – må valideres og saniteres før den brukes. Validering kan skje i tre lag. Klientside-validering med JavaScript gir rask tilbakemelding, men kan enkelt omgås, så du må aldri stole på den alene. Serverside-validering med Python eller Node.js er obligatorisk – den kan ikke omgås av brukeren og er din siste forsvarslinje. Database-validering med constraints og fremmednøkler gir et ekstra lag.

To teknikker er særlig nyttige. Whitelist betyr at du bare tillater spesifikke, kjente verdier – vil du sortere etter et felt, sjekker du at feltet finnes i en liste av gyldige verdier før du bruker det. Type-sjekk betyr å bekrefte at input har riktig datatype, for eksempel at en alder faktisk er et tall. Begge bygger på samme idé: i stedet for å lete etter alt som er farlig, slipper du bare inn det du vet er trygt.

📝Oppgave Quiz 1

SQL injection og XSS

To av de farligste sårbarhetene fortjener særlig oppmerksomhet. Den første er SQL injection (A03 i OWASP Top 10), som oppstår når en angriper kan injisere SQL-kode gjennom input. Bygger du en spørring med f-strenger, og angriperen skriver ' OR '1'='1, blir spørringen sann for alle rader og returnerer hele tabellen. Med '; DROP TABLE brukere; -- kan angriperen slette tabellen. Løsningen er, som du har lært, parameteriserte spørringer: skriv ? (i SQLite) eller %s (i PostgreSQL) der verdiene skal inn, og la databasebiblioteket sette dem trygt:

cursor.execute("SELECT * FROM brukere WHERE brukernavn = ?", (brukernavn,))

Den andre er Cross-Site Scripting (XSS), som oppstår når en angriper kan injisere skadelig JavaScript i en webside som andre brukere ser. Det finnes tre typer: stored XSS, der koden lagres i databasen og vises til alle (som i et kommentarfelt); reflected XSS, der koden sendes som parameter og reflekteres tilbake (som på en søkeside); og DOM-based XSS, der svakheten ligger i klientsidens JavaScript. Skriver en angriper <script>alert(document.cookie)</script> som brukernavn, kjøres scriptet hos alle som ser siden – og kan stjele cookies, omdirigere til phishing eller kjøre keyloggere. Forsvaret er output encoding/escaping: tegn som < gjøres om til ufarlig tekst. Flask sin Jinja2 escaper automatisk, så {{ brukernavn }} er trygt – men du må unngå |safe uten god grunn, fordi det slår av beskyttelsen.

📝Oppgave Quiz 2

CSRF – når nettleseren blir lurt

Den tredje sårbarheten er mer lumsk. Cross-Site Request Forgery (CSRF, uttales «sea-surf») er et angrep der en ondsinnet side lurer nettleseren din til å sende forespørsler til en annen side der du er innlogget. Tenk deg at du er logget inn på bank.no. Så besøker du ondsinnet.com, som inneholder et skjult bilde:

<img src="https://bank.no/overforing?til=angriper&belop=10000">

Nettleseren laster «bildet», og sender automatisk med din innloggede sesjon-cookie til bank.no. Banken ser en gyldig, innlogget forespørsel og utfører overføringen. Det skremmende er at du ikke gjorde noe galt selv – nettleseren ble lurt på dine vegne.

Forsvaret er CSRF-tokens. Idéen er enkel: serveren legger en hemmelig, uforutsigbar verdi inn i hvert skjema, og krever at denne verdien sendes tilbake ved innsending. Den ondsinnede siden kjenner ikke tokenet og kan derfor ikke forfalske en gyldig forespørsel. I Flask gjør biblioteket Flask-WTF dette automatisk: når du bruker en FlaskForm, genereres og valideres CSRF-tokenet for deg. Dette, kombinert med at sensitive handlinger bruker POST i stedet for GET, gjør at angriperens skjulte bilde-triks ikke lenger fungerer. CSRF minner oss om en viktig sannhet: noen ganger er det ikke koden din som angripes direkte, men tilliten mellom nettleseren og serveren.

📝Oppgave Quiz 3

Oppsummering

Sikker programmering hviler på én gylden regel: aldri stol på brukerinput. All data må valideres, helst med whitelist og type-sjekk, og serverside-validering er obligatorisk siden klientside kan omgås. Vi så de tre store webangrepene og forsvaret mot dem. SQL injection stoppes med parameteriserte spørringer. XSS stoppes med output encoding/escaping, som Jinja2 gjør automatisk så lenge du unngår |safe. Og CSRF stoppes med CSRF-tokens, gjerne via Flask-WTF, og ved å bruke POST for sensitive handlinger.

Fellesnevneren er at angrep ofte utnytter tillit – tillit til input, til innhold, eller mellom nettleser og server. Ved å bygge inn forsvar i hvert lag gjør vi koden motstandsdyktig. I neste kapittel går vi videre til kryptering og autentisering i praksis.

Dette kapitlet er skrevet av Anthropics toppmodeller (Claude Opus og Claude Fable) og er foreløpig ikke manuelt gjennomgått — kvalitetskontrollen gjøres av uavhengige KI-agenter, og innmeldte feil rettes fortløpende. Funnet en feil? Meld fra, så retter vi den. Les mer om hvordan innholdet lages.