← Tilbake til TSD3060

1️⃣ Uke 33: Demonisering, port 80 & chroot

Intro, repetisjon, UNIX daemon-prosesser og sikkerhet

📌 Kapitteloppsummering

  • Demonisering: Prosessen med å lage bakgrunnsprosesser (daemons) som kjører uten terminal
  • Port 80: HTTP-port som krever root-rettigheter, løst med privilegie-separasjon
  • chroot: Sikkerhetsteknikk for å begrense filsystemtilgang ved å endre rotkatalog
  • Jobber & Sesjoner: Prosessgrupper og sesjonsledelse i UNIX/Linux
  • Sikkerhet: setuid/setgid for privilegie-dropp, busybox for minimal fotavtrykk

1.1 Demonisering - Bakgrunnsprosesser

💡 Hva er en daemon?

En daemon er en bakgrunnsprosess som:

  • Kjører kontinuerlig uten brukerinteraksjon
  • Ikke er tilknyttet en terminal
  • Starter ved oppstart eller on-demand
  • Eksempler: webservere (httpd), database-servere, systemloggere

Viktige begreper

Jobber:

  • Flere prosesser i en gruppe
  • En prosess er leder av gruppa
  • Eksempel: cat | rev er én jobb med to prosesser

Sesjoner:

  • En sesjon betegner et sett av relaterte aktiviteter
  • Alle jobber i et skall tilhører samme sesjon
  • En prosess er sesjonsleder
  • Man kan være logget inn flere ganger samtidig (hver = en sesjon)

Demoniseringsoppskrift (fra Stevens)

  1. fork() og opphav gjør exit() - for å kjøre i bakgrunnen og ikke være prosessgruppeleder
  2. setsid() - blir sesjonsleder og prosessgruppeleder for ny sesjon, fri fra kontrollterminal
  3. signal(SIGHUP, SIG_IGN) - ignorerer SIGHUP som sendes når sesjonsleder terminerer
  4. fork() igjen og opphav gjør exit() - hindrer at prosessen kan knytte til seg en kontrollterminal
  5. close() alle unødvendige filer
/* Eksempel demonisering */ #include <unistd.h> #include <sys/stat.h> #include <signal.h> void daemonize() { pid_t pid; /* Fork #1 */ if ((pid = fork()) < 0) exit(1); if (pid > 0) exit(0); /* Parent exits */ /* Create new session */ setsid(); /* Ignore SIGHUP */ signal(SIGHUP, SIG_IGN); /* Fork #2 */ if ((pid = fork()) < 0) exit(1); if (pid > 0) exit(0); /* Parent exits */ /* Change working directory */ chdir("/"); /* Close file descriptors */ close(0); close(1); close(2); }

⚠️ Hvorfor to fork()?

Første fork(): Sikrer at prosessen ikke er prosessgruppeleder (påkrevd for setsid)

Andre fork(): Sikrer at prosessen ikke er sesjonsleder, slik at den ikke kan åpne en kontrollterminal

1.2 Port 80 og Privilegie-separasjon

💡 Problemet

Av sikkerhetsgrunner bør man IKKE kjøre webserveren som root, men kun root kan binde til porter under 1024 (privilegerte porter).

Løsning: Privilegie-separasjon

  1. Start som root
  2. Bind til port 80
  3. Dropp privilegier med setuid() og setgid()
  4. Kjør server som uprivilegert bruker
/* Privilegie-dropp eksempel */ #include <unistd.h> #include <sys/types.h> int server_fd = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in addr = { .sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY, .sin_port = htons(80) /* Port 80 krever root */ }; /* Må være root her */ bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)); listen(server_fd, 10); /* Dropp privilegier */ setgid(1000); /* Sett gruppe-ID til vanlig bruker */ setuid(1000); /* Sett bruker-ID til vanlig bruker */ /* Nå kjører vi som uprivilegert bruker */ while(1) { int client = accept(server_fd, NULL, NULL); /* Handle client ... */ }

Viktige systemkall:

  • setuid(uid) - Setter bruker-ID for prosessen
  • setgid(gid) - Setter gruppe-ID for prosessen
  • getuid() - Henter nåværende bruker-ID
  • geteuid() - Henter effektiv bruker-ID

1.3 chroot - Endre rotkatalog

💡 Konsept

chroot endrer rotkatalogen for en prosess og alle dens barn, og begrenser dermed tilgang til filsystemet.

Bruksområder:

  • Isolere tjenester fra resten av filsystemet
  • Sikkerhet - begrense skade ved kompromittering
  • Testing - isolert miljø
  • Byggesystemer - ren miljø

Systemkall:

  • chroot(2) - Change root directory (C-funksjon)
  • chroot(8) - Run command with special root directory (kommandolinjeverktøy)

Busybox chroot-eksempel

#!/bin/sh # Lag ny rotkatalog mkdir chroot-eksempel/ mkdir chroot-eksempel/bin cd chroot-eksempel/bin # Kopier busybox (statisk lenket) cp /bin/busybox . # Lag symlenker til alle busybox-kommandoer PRGS=$(./busybox --list) for P in $PRGS; do ln -s busybox $P done # Kjør shell i chroot-miljø (krever root) sudo PATH=/bin chroot ../chroot-eksempel/ /bin/sh

⚠️ Begrensninger

  • Krever root-rettigheter for å opprette chroot
  • Ikke perfekt sikkerhet - root inne i chroot kan bryte ut
  • Må kopiere alle nødvendige filer inn i chroot
  • Modernere alternativer: containere med namespaces

Inspeksjon av prosesser i chroot:

# Inne i chroot-miljøet mkdir /proc mount -t proc none /proc ls /proc # Se prosesser

1.4 Eksamensrelevante konsepter

🎯 Viktig for eksamen

  • Forstå hvorfor vi demoniserer (bakgrunn, ingen terminal)
  • Kjenne til stegene i demonisering (fork → setsid → fork)
  • Forklare privilegie-separasjon (start som root → bind → dropp)
  • Vite når setuid/setgid brukes
  • Forklare chroot og dets sikkerhetsbegrensninger
  • Forstå jobber vs sesjoner vs prosessgrupper

Typiske eksamensspørsmål:

  1. "Forklar hvordan en prosess blir til en daemon"
  2. "Hvorfor trenger vi to fork() i demonisering?"
  3. "Hvordan kan en webserver binde til port 80 uten å kjøre som root?"
  4. "Hva er forskjellen mellom chroot og containere?"
  5. "Forklar setuid/setgid og deres sikkerhetsmessige implikasjoner"

2️⃣ Uke 34: Operativsystemnivå-virtualisering (Containere)

Namespaces, cgroups, og grunnlaget for moderne containere

📌 Kapitteloppsummering

  • OS-nivå virtualisering: Én kjerne, flere isolerte brukerområder (containere)
  • Namespaces: Isolerer systemressurser (PID, network, mount, UTS, IPC, user)
  • Cgroups: Begrenser og måler ressursbruk (CPU, minne, I/O)
  • Unshare: Verktøy for å opprette nye namespaces
  • Fordeler: Lav overhead, rask oppstart, effektiv ressursbruk

2.1 Hva er OS-nivå virtualisering?

💡 Grunnkonsept

OS-nivå virtualisering lar én OS-kjerne kjøre flere isolerte brukerområder (containere). Hver container tror den er alene på systemet.

Sammenligning med andre virtualiseringstyper:

Type Eksempel Overhead Isolasjon
Full virtualisering VirtualBox, VMware Høy Meget sterk
Paravirtualisering Xen, KVM Middels Sterk
OS-nivå Docker, LXC Lav Moderat

Fordeler med OS-nivå virtualisering:

  • Liten ekstrabelastning (systemkall går direkte til kjernen)
  • Rask oppstart (ingen OS-boot)
  • Effektiv ressursbruk (delt kjerne)
  • Copy-on-Write filsystemer (delte lag)

🔑 Nøkkelbegrep

En kjerne - flere brukerområder (userspace)

Dette er kjernen i OS-nivå virtualisering. Alle containere deler samme OS-kjerne, men har hver sine isolerte prosesstrær, filsystemer, nettverkstack etc.

2.2 Linux Namespaces

💡 Hva er namespaces?

Namespaces isolerer systemressurser slik at prosesser i forskjellige namespaces ser forskjellige versjoner av systemet.

7 typer namespaces i Linux:

  1. PID namespace: Isolerer prosess-IDer
    • PID 1 inne i namespace er faktisk en annen PID utenfor
    • Prosesser kan ikke se prosesser utenfor sitt namespace
  2. Network namespace: Isolerer nettverksstack
    • Egne nettverksgrensesnitt, IP-adresser, rutingtabeller
    • Containere kan ha private nettverk
  3. Mount namespace: Isolerer mountpoints
    • Hvert namespace ser sitt eget filsystem-hierarki
    • Gjør chroot mer robust
  4. UTS namespace: Isolerer hostname og domenenavn
    • Hver container kan ha sitt eget hostname
  5. IPC namespace: Isolerer inter-process communication
    • Message queues, semaforer, shared memory
  6. User namespace: Isolerer bruker- og gruppe-IDer
    • Root inne i container er ikke root utenfor
    • Viktig for sikkerhet
  7. Cgroup namespace: Isolerer cgroup-visning
/* Lage ny PID namespace med unshare */ #include <sched.h> #include <unistd.h> /* CLONE_NEWPID - nytt PID namespace */ unshare(CLONE_NEWPID); if (fork() == 0) { /* Barn er PID 1 i nytt namespace */ printf("Min PID: %d\n", getpid()); /* Skriver ut 1 */ }

2.3 Linux Cgroups (Control Groups)

💡 Hva er cgroups?

Cgroups begrenser, måler og isolerer ressursbruk (CPU, minne, disk I/O, nettverk) for grupper av prosesser.

Hva kan cgroups begrense?

  • CPU: Prosent CPU-tid, CPU-kerner
  • Minne: Max RAM, swap-bruk
  • Disk I/O: Read/write hastighet og IOPS
  • Nettverk: Båndbredde (via andre verktøy)
  • Antall prosesser: Max antall prosesser

Eksempel: Begrens minne for en prosess

# Lag en cgroup sudo cgcreate -g memory:/mygroup # Sett minnegrense til 100MB sudo cgset -r memory.limit_in_bytes=104857600 mygroup # Kjør en prosess i cgroppen sudo cgexec -g memory:mygroup ./my-program # Slett cgroup sudo cgdelete memory:/mygroup

⚡ Cgroups v1 vs v2

v1: Hver ressurstype har sitt eget hierarki

v2: Unified hierarchy - ett tre for alle ressurser (moderne standard)

2.4 Unshare - Manuell Container

unshare er et Linux-verktøy som lar deg opprette nye namespaces og kjøre et program i dem.

Eksempel: Lag en enkel container fra bunnen

#!/bin/bash # Sett opp rotfilsystem ROTFS=$PWD/min-container mkdir -p $ROTFS/{bin,proc} cd $ROTFS/bin/ cp /bin/busybox . for P in $(./busybox --list); do ln busybox $P done # Kjør i nye namespaces sudo unshare --fork --pid --mount --uts --ipc \ chroot $ROTFS /bin/sh # Inne i containeren: mount -t proc none /proc hostname min-container ps aux # Ser kun prosesser i containeren

Forklaring av flagg:

  • --fork - Fork før unshare (nødvendig for PID namespace)
  • --pid - Nytt PID namespace
  • --mount - Nytt mount namespace
  • --uts - Nytt UTS namespace (hostname)
  • --ipc - Nytt IPC namespace

2.5 Fra chroot til Containere

Evolusjon av isolasjonsteknikker:

  1. chroot (1979):
    • Endrer rotkatalog
    • Ingen prosess- eller nettverksisolasjon
    • Kan brytes ut av root
  2. FreeBSD Jails (2000):
    • Legger til nettverks- og prosessisolasjon
    • Mer robust enn chroot
  3. Linux Namespaces (2002-2013):
    • Finkornet isolasjon av mange ressurser
    • Grunnlag for moderne containere
  4. LXC (2008):
    • Sys-admin verktøy for containere
    • Bruker namespaces + cgroups
  5. Docker (2013):
    • Developer-friendly
    • Image-format og registry
    • Populære containere idag

🎯 Viktig for eksamen

  • Forklare forskjellen mellom chroot og namespaces
  • Liste opp de 7 typene namespaces og hva de isolerer
  • Forklare hva cgroups brukes til (ressursbegrensning)
  • Forstå at containere = namespaces + cgroups + filsystem
  • Vite at systemkall i container går direkte til vertskjernen (lav overhead)

3️⃣ Uke 35-36: Docker/Podman

Container orchestration, images, Dockerfile, docker-compose

📌 Kapitteloppsummering

Docker er plattformen for containerisering - den pakker applikasjoner med alle avhengigheter i isolerte containere. Docker bruker OS-nivå virtualisering med namespaces, cgroups og capabilities for sikkerhet og ressurskontroll. Images er statiske templates, containere er kjørende instanser. Dockerfile/Containerfile definerer lagvis bygging av images.

🐳 Om Docker

💡 Viktige begreper

  • Image (bilde): Statisk, read-only template - kan sammenlignes med git-repository
  • Container: Dynamisk, kjørende instans av et image
  • Dockerfile/Containerfile: Oppskrift for å bygge images lagvis
  • Docker Hub: Registry med offisielle og bruker-images
  • Docker Daemon: Bakgrunnstjeneste som håndterer containere
  • Docker Client: CLI som kommuniserer med daemon via HTTP

Containere vs. Virtuelle Maskiner:

  • Containere deler OS-kjerne med verten (VM-er har egen kjerne)
  • Containere er lettere i størrelse
  • Containere starter raskere
  • Containere bruker ressurser mer effektivt
# Grunnleggende Docker-kommandoer docker pull alpine # Hent image fra Docker Hub docker images # List alle lokale images docker run -it alpine sh # Kjør interaktiv container docker run -d nginx # Kjør i bakgrunnen (detached) docker ps # List kjørende containere docker ps -a # List alle containere docker stop CONTAINER # Stopp container (SIGTERM) docker rm CONTAINER # Fjern container docker inspect IMAGE/CONTAINER # Vis detaljert info

🎯 Eksamensrelevant

  • Forklare forskjellen mellom image og container
  • Beskrive Docker-arkitekturen med daemon og klient
  • Forstå hvordan Docker bruker namespaces og cgroups

🏗️ Dockerfile/Containerfile

En Dockerfile (nå ofte kalt Containerfile) er en tekstfil med instruksjoner for å bygge et Docker image lagvis.

⚠️ Viktig: Maksimum 127 lag i et image! Hver instruksjon (som RUN, COPY, ADD) danner et nytt lag.

💡 Viktige Dockerfile-instruksjoner

  • FROM: Definerer grunnlagsbildet (må være først i filen)
  • COPY: Kopierer filer fra build context til bildets filsystem
  • ADD: Som COPY, men støtter URL'er og automatisk utpakking av arkiver
  • RUN: Kjører kommando i shell (/bin/sh) og danner nytt lag
  • CMD: Standard kommando når container startes (kun siste CMD kjøres)
  • ENTRYPOINT: Kommando som alltid kjøres ved containerstart
  • EXPOSE: Dokumenterer porter containeren lytter på
  • WORKDIR: Setter arbeidskatalogen for RUN/CMD/ENTRYPOINT
  • USER: Setter bruker (navn eller UID) for påfølgende instruksjoner
  • VOLUME: Oppretter mount point for volumer
# Eksempel Dockerfile FROM alpine COPY hallotjener /bin/ EXPOSE 8080 CMD ["/bin/hallotjener"] # Bygge og kjøre docker build -t minapp . docker run -p 8080:8080 minapp # Med navn og tag docker build -t minapp:v1.0 . docker run -p 8080:8080 minapp:v1.0

Build Context

Build context er mengden filer som kan refereres til med ADD/COPY. Pakkes og sendes fra klient til daemon.

  • Normalt en katalog oppgitt med filsti
  • Kan være URL til git-repository
  • Kan være tom mengde
  • Bruk .dockerignore for å ekskludere filer (unngå å sende unødvendige filer)

Kommandolinje-argumenter: exec- vs shell-format

# Exec-format (anbefalt - ingen shell-prosessering) CMD ["kommando", "arg1", "arg2"] ENTRYPOINT ["/bin/hallotjener"] # Shell-format (kjører via /bin/sh -c) CMD kommando arg1 arg2 ENTRYPOINT /bin/hallotjener

🎯 Eksamensrelevant

  • Kunne skrive en enkel Dockerfile
  • Forstå hvordan bildelag bygges opp
  • Forklare forskjellen mellom CMD og ENTRYPOINT
  • Vite at base images (scratch, alpine, debian) ikke har foreldre

🔒 Sikkerhetsbegrensninger

1. Cgroups (Control Groups)

Brukes til å begrense og måle ressursbruk for containere.

# Begrens minne til 4MB docker run -it --rm -m 4m busybox # Begrens CPU-kjerner (bruk kjerne 0 og 2) docker run --cpuset-cpus 0,2 busybox nproc # Begrens CPU-andel (0-1024, hvor 1024 = 100%) docker run --cpu-shares 512 myapp

2. Capabilities

Siden Linux 2.2: Finkornet privilegiekontroll. Tradisjonell UNIX har kun root/ikke-root, men capabilities lar oss gi spesifikke rettigheter.

💡 Eksempel på capabilities

  • CAP_NET_ADMIN: Rett til nettverksadministrasjon
  • CAP_SYS_TIME: Rett til å endre systemklokka
  • CAP_CHOWN: Rett til å endre eierskap på filer
# Fjern alle capabilities, legg kun til NET_ADMIN docker run -it --cap-drop ALL --cap-add NET_ADMIN busybox sh # Fjern spesifikk capability docker run -it --cap-drop SYS_TIME myapp

3. AppArmor

Enda mer finkornet kontroll - per filsti og operasjon (les, skriv, kjør).

# Bruk forhåndsdefinert profil docker run --security-opt apparmor=profilnavn myapp # Standard profil docker run --security-opt apparmor=docker-default myapp # Uten profil (usikkert!) docker run --security-opt apparmor=unconfined myapp

4. User Namespaces

Mapper brukere i container til upriviligerte brukere i vertssystem. Root i container kan være vanlig bruker på verten.

# Aktivere user namespaces ved oppstart av docker daemon sudo systemctl stop docker sudo dockerd --userns-remap=default & # Finn UID og GID mapping grep dockremap /etc/subuid grep dockremap /etc/subgid

🎯 Eksamensrelevant

  • Forstå hva cgroups brukes til (ressursbegrensning)
  • Forklare hvordan capabilities gir finkornet privilegiekontroll
  • Beskrive hvordan user namespaces forbedrer sikkerhet

🌐 Docker Nettverk

💡 Nettverkstyper

  • bridge: Standard nettverk - isolerer containere fra verten, forbinder containere på samme vert
  • host: Deler nettverk med verten (ingen isolasjon)
  • none: Kun localhost, ingen ekstern kommunikasjon

Scope (gyldighetsområder)

  • local: Nettverket eksisterer kun på maskinen containeren kjører på
  • global: Nettverket spenner over alle containere i cluster (ingen ruting satt opp)
  • swarm: Nettverket omfatter hele Docker swarm
# Inspiser nettverk docker network ls docker network inspect bridge # Opprett eget nettverk docker network create minnettverk # Kjør container med egendefinert nettverk docker run --network=minnettverk myapp # Koble container til nettverk docker network connect minnettverk CONTAINER

Bridge-nettverk arkitektur

Docker oppretter virtuelle ethernet-par: en ende i containeren, en i docker0-bridge på verten. Containere kan kommunisere via IP-adresser.

🎯 Eksamensrelevant

  • Forstå bridge-nettverk og hvordan containere kommuniserer
  • Forklare forskjellen mellom bridge, host og none

💾 Docker Volumer

Volumer brukes til å persistere data utenfor containerens livssyklus. Data i containere forsvinner når de slettes!

💡 Tre måter å opprette volumer

  • Automatisk sti: Docker velger sti på verten
  • VOLUME i Dockerfile: Definert i image
  • Bind mount: Monterer spesifikk katalog fra vert til container
# Metode 1: Automatisk sti docker run -v /sti/i/container busybox # Finn volum-sti på vert docker inspect -f {{.Mounts}} CONTAINER docker inspect CONTAINER | jq '.[] | {Mounts}' # Metode 2: VOLUME i Dockerfile FROM busybox VOLUME /sti/i/container # Metode 3: Bind mount til spesifikk katalog docker run -v /absolutt/sti/på/vert:/sti/i/container busybox
⚠️ Viktig: Data i volumer kopieres første gang de opprettes. Endringer etterpå deles mellom vert og container.

🔧 Docker Verktøy

  • Docker Swarm: Dockers innebygde clustering-løsning
  • Docker Compose: Definerer og kjører multi-container applikasjoner (YAML-fil)
  • Docker Machine: Installerer/konfigurerer Docker på fjern-verter

Container-orkestrering (alternativer)

  • Kubernetes (mest populær)
  • Docker Swarm
  • Apache Mesos Marathon
  • Amazon ECS
  • Azure Container Service

4️⃣ Uke 37: HTML, XML, CSS

Webteknologier og markup-språk

📌 Kapitteloppsummering

HTML (HyperText Markup Language) er oppmerkingsspråk for web-dokumenter, utviklet på CERN. HTML5 erstatter HTML 4.01 og er ikke lenger basert på SGML. XML (eXtensible Markup Language) er egnet for semistrukturerte data med irregulær struktur. CSS (Cascading Style Sheets) styrer utseende til HTML/XML-dokumenter uten å endre strukturen.

📄 HTML - HyperText Markup Language

💡 Om HTML

  • Oppmerkings-språk for web-dokumenter
  • Utviklet på CERN av Berners-Lee et.al.
  • Tidlige versjoner (< 5) basert på SGML (ISO-standard)
  • Utviklet med tanke på plattformuavhengighet
  • Standarisert av IETF i 1995 (RFC 1866)
  • HTML5 kom i 2014, vedlikeholdes nå av WHATWG

HTML5 Nyheter

  • Ikke lenger basert på SGML
  • Inkluderer DOM (Document Object Model) med API
  • Egne tagger for lyd og video: <audio>, <video>
  • <canvas> for tegning
  • Semantiske tagger: <section>, <article>, <header>, <nav>
  • SVG (vektorgrafikk) og MathML (matematisk notasjon)
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Tittel</title> </head> <body> <h1>Overskrift</h1> <p>Vanlig tekst.</p> <a href="http://www.usn.no">Hyperlink</a> <audio controls> <source type="audio/ogg" src="lyd.ogg" /> </audio> </body> </html>

Seks typer HTML5-elementer

  1. Void elements: (area, br, hr, img, input, link, meta) - uten innhold, uten slutt-tag
  2. Template element: <template>
  3. Raw text elements: <script>, <style>
  4. Escapable raw text elements: <textarea>, <title>
  5. Foreign elements: MathML og SVG
  6. Normal elements: Alle andre

🎯 Eksamensrelevant

  • Forstå forskjellen mellom HTML 4.01 og HTML5
  • Vite at HTML5 ikke er basert på SGML
  • Kjenne til nye HTML5-elementer (audio, video, canvas, semantiske tagger)

🔖 XML - eXtensible Markup Language

💡 XML og semistrukturerte data

Mye data har ikke fast tabularisk struktur som i relasjonsdatabaser, men har likevel en viss struktur.

Semistrukturerte data:

  • Irregulære og ufullstendige data
  • Struktur som endres hyppig
  • Kan være skjemaløs, kun med begrensninger på data
  • Skjema oppdages underveis, ikke på forhånd

Oppbygning av XML

  • Valgfri XML-deklarasjon: <?xml version="1.0"?>
  • Elementer: Start-tag, innhold, slutt-tag
  • Rot-element: Må være første element, inneholder alle andre
  • Elementer kan inneholde: andre elementer, attributter, tekst, entitetsreferanser

Velformet XML-dokument

Krav til velformethet:

  • Rot-elementet må inneholde alle resterende elementer
  • Elementer må være nøstet i trestruktur uten overlapping
  • Alle ikke-tomme elementer må ha både start- og slutt-tagg
<?xml version="1.0"?> <bokliste> <bok> <bokid>02</bokid> <tittel>Notater til DA-ODA2000</tittel> <forfatterId>12345</forfatterId> </bok> <bok> <bokid>01</bokid> <tittel>Notater til DA-NAN3000</tittel> <forfatterId>12345</forfatterId> </bok> </bokliste>

Navnerom (Namespaces) i XML

  • XML-dokumenter kan definere ulike navnerom
  • Unngår navnekollisjoner mellom elementer fra ulike kilder
  • URI'er brukes for globalt unike navn
  • Lokale navn (prefikser) brukes for korte referanser

Gyldig XML-dokument

DTD (Document Type Definition):

  • Definerer et XML-dokuments gyldige syntaks
  • Ikke påkrevd
  • Begrensninger: ikke XML-syntax, begrenset datatype-støtte, ikke støtte for navnerom

XML Schema:

  • Alternativ til DTD
  • Løser DTD's begrensninger
  • Skrevet i XML
  • Større uttrykksmuligheter
  • Støtter navnerom
  • Rike datatyper

XHTML (eXtensible HTML)

  • HTML 4.01 reformulert til XML 1.0
  • Strengere HTML-versjon
  • Tagger og attributter med små bokstaver
  • Obligatorisk slutt-tagg
  • Må følge XML-regler

XML-API

DOM (Document Object Model):

  • Laget av W3C
  • Plattform- og leverandør-uavhengig
  • Bygger tre-representasjon i minnet
  • Bra for å legge til, slette, reorganisere elementer

SAX (Simple API for XML):

  • Hendelse-basert (event-driven)
  • Seriell tilgang
  • Hendelser for start-tag og slutt-tag
  • Bygger IKKE tre-representasjon (lavere minnebruk)

🎯 Eksamensrelevant

  • Forstå hva semistrukturerte data er
  • Kjenne til krav for velformet XML
  • Forklare forskjellen mellom DTD og XML Schema
  • Forstå forskjellen mellom DOM (tre-basert) og SAX (hendelse-basert)

🎨 CSS - Cascading Style Sheets

💡 Om CSS

  • Opphavsmann: Håkon Wium Lie fra Halden
  • Brukes for å angi utseende av HTML/XML
  • Kan styre opptegning, men ikke endre strukturen
  • Separerer innhold fra presentasjon

CSS Syntax

selector { navn: verdi; navn: verdi; ... navn: verdi }

Selector refererer til elementer i dokumentet.

Klasser

Elementer kan grupperes ved å tilordne dem til klasser:

.sitat { color: green; } .hypotese { color: blue; } <p class="hypotese">Dette blir et blått avsnitt</p> <p class="sitat">Dette blir et grønt avsnitt</p>

Pseudoklasser

  • :link
  • :visited
  • :active
  • :first-line
  • :first-letter

ID'er

Enkelt-elementer kan gis identifikatorer:

#viktigste { color: red; } <p id="viktigste">Dette blir et rødt avsnitt</p>

Fire måter å plassere CSS i HTML

  1. I <head>:
    <style media=screen> ... </style>
  2. Lenke til stilsett-fil:
    <link rel="stylesheet" type="text/css" href="..." />
  3. Import i stilsett:
    <style type="text/css"> @import url(http://...) i {color: red} </style>
  4. Inline som attributt:
    <i style="color: red">Kursiv og rødt</i>

CSS i XML

XML kan stilformes ved å referere til CSS-fil:

<?xml version="1.0"?> <?xml-stylesheet type="text/css" href="bok1.css"?> <bokliste> ... </bokliste>

🎯 Eksamensrelevant

  • Forstå CSS-syntax med selector og egenskaper
  • Kjenne til klasser og ID'er
  • Vite hvordan CSS kan inkluderes i HTML (4 måter)
  • Forstå at CSS kan brukes både på HTML og XML

5️⃣ Uke 38: SQLite Databaseprogrammering

Embedded database, SQL basics, transactions

📌 Kapitteloppsummering

Databaseprogrammering handler om hvordan applikasjoner kommuniserer med DBMS. Tre tilnærminger: Embedded SQL, API, og egne språk. Standardiserte API som ODBC og JDBC bruker drivere til å oversette mellom leverandørspesifikk og standard API. Typisk fremgangsmåte: opprette forbindelse, sende spørringer, motta resultater, stenge forbindelse. Forberedte kommandoer (prepared statements) beskytter mot SQL injection.

🗄️ SQL Repetisjon

💡 DML (Data Manipulation Language)

  • SELECT: Henter data fra tabeller
  • INSERT: Legger til nye rader
  • UPDATE: Oppdaterer eksisterende rader
  • DELETE: Sletter rader

💡 DDL (Data Definition Language)

  • CREATE: Oppretter tabeller, indekser, views
  • ALTER: Endrer struktur på eksisterende tabeller
  • DROP: Sletter tabeller, indekser, views
-- DML eksempler SELECT * FROM bok WHERE forfatter = 'Smith'; INSERT INTO bok (tittel, forfatter) VALUES ('Tittel', 'Smith'); UPDATE bok SET pris = 299 WHERE bokid = 5; DELETE FROM bok WHERE bokid = 5; -- DDL eksempler CREATE TABLE bok (bokid INT PRIMARY KEY, tittel TEXT); ALTER TABLE bok ADD COLUMN pris REAL; DROP TABLE bok;

🔌 Tilnærminger til databaseprogrammering

1. Embedded SQL

SQL-kommandoer er innebygd direkte i programmeringsspråket (f.eks. C, COBOL). Preprocessor oversetter SQL til API-kall.

2. API (Application Programming Interface)

Programmet kaller funksjoner/metoder i et API for å kommunisere med DBMS.

3. Egne språk

Spesialiserte språk designet for databaseinteraksjon (f.eks. PL/SQL i Oracle).

🎯 Eksamensrelevant

Forstå forskjellen mellom de tre tilnærmingene. API-tilnærmingen er mest brukt i moderne programmering.

🌐 Standardiserte API

💡 Hvorfor standardiserte API?

  • Uavhengighet av DBMS-leverandør
  • Drivere oversetter mellom standard og leverandørspesifikk API
  • Lettere å bytte database
  • Samme kode kan brukes mot ulike DBMS

ODBC (Open Database Connectivity)

  • Opprinnelig Microsoft-standard
  • Mest brukt i Windows-miljøer
  • API for C/C++

JDBC (Java Database Connectivity)

  • Java-standard for databasetilgang
  • Plattformuavhengig
  • Bruker JDBC-drivere for ulike DBMS
// JDBC eksempel - opprette forbindelse String url = "jdbc:mysql://localhost/bokbase"; String drv = "com.mysql.jdbc.Driver"; String usr = "bruker", pwd = "passord"; Class.forName(drv); Connection lnk = DriverManager.getConnection(url, usr, pwd); Statement stm = lnk.createStatement();

📋 Typisk fremgangsmåte

  1. Opprett forbindelse: Klient oppretter forbindelse til DBMS (tjener)
  2. Samhandling: Klient sender spørring og mottar resultat
  3. Gjenta: Eventuelt flere spørringer
  4. Steng: Steng forbindelsen når ferdig
// Java/JDBC eksempel - komplett flyt Connection conn = DriverManager.getConnection(url, usr, pwd); Statement stmt = conn.createStatement(); // Send spørring ResultSet rs = stmt.executeQuery("SELECT * FROM bok"); // Prosesser resultater while (rs.next()) { String tittel = rs.getString("tittel"); System.out.println(tittel); } // Rydde opp rs.close(); stmt.close(); conn.close();
⚠️ Viktig: Alltid steng ResultSet, Statement og Connection når ferdig! Bruk try-with-resources i moderne Java.

🛡️ Forberedte kommandoer (Prepared Statements)

💡 Hvorfor forberedte kommandoer?

  • Sikkerhet: Beskytter mot SQL injection
  • Ytelse: Query plan kan gjenbrukes
  • Lesbarhet: Tydeligere hva som er data vs SQL

SQL Injection - Problemet

// FARLIG - sårbar for SQL injection! String bruker = request.getParameter("bruker"); String sql = "SELECT * FROM bruker WHERE navn = '" + bruker + "'"; stmt.executeQuery(sql); // Angriper kan sende: admin' OR '1'='1 // Blir til: SELECT * FROM bruker WHERE navn = 'admin' OR '1'='1' // Dette returnerer ALLE brukere!

Løsning: Prepared Statements

// SIKKERT - bruker prepared statement String bruker = request.getParameter("bruker"); String sql = "SELECT * FROM bruker WHERE navn = ?"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, bruker); // Parameter 1 settes til bruker ResultSet rs = pstmt.executeQuery(); // Angriper kan sende: admin' OR '1'='1 // Men dette blir behandlet som en streng, ikke SQL-kode! // Spørringen blir: SELECT * FROM bruker WHERE navn = 'admin'' OR ''1''=''1'
⚠️ Kritisk for sikkerhet: ALLTID bruk prepared statements når du inkluderer brukerdata i SQL! Aldri konkatenere strenger for å bygge SQL-spørringer.

🎯 Eksamensrelevant

  • Forklare hva SQL injection er og hvordan det fungerer
  • Vite at prepared statements er løsningen
  • Kunne skrive eksempel med prepared statement
  • Forstå hvorfor parameterized queries er sikrere

💾 SQLite-spesifikt

💡 Om SQLite

  • Embedded database (ikke klient-tjener)
  • Hele databasen i én fil
  • Ingen separat server-prosess
  • ACID-compliant (Atomicity, Consistency, Isolation, Durability)
  • Selvinneholdt, zero-configuration
  • Mye brukt i mobile apper, nettlesere, embedded systemer

SQLite fra kommandolinjen

# Åpne/opprett database sqlite3 mindb.db # Nyttige kommandoer i sqlite3 .tables # Vis alle tabeller .schema tabellnavn # Vis CREATE-statement for tabell .mode column # Formatert output .headers on # Vis kolonnenavn .quit # Avslutt # SQL-kommandoer CREATE TABLE bok (bokid INTEGER PRIMARY KEY, tittel TEXT); INSERT INTO bok VALUES (1, 'Min bok'); SELECT * FROM bok;

SQLite i C

#include sqlite3 *db; sqlite3_stmt *stmt; int rc; // Åpne database rc = sqlite3_open("mindb.db", &db); // Prepared statement rc = sqlite3_prepare_v2(db, "SELECT * FROM bok WHERE bokid = ?", -1, &stmt, NULL); sqlite3_bind_int(stmt, 1, 5); // Bind parameter // Kjør og hent resultater while (sqlite3_step(stmt) == SQLITE_ROW) { const char *tittel = sqlite3_column_text(stmt, 1); printf("%s\n", tittel); } // Rydd opp sqlite3_finalize(stmt); sqlite3_close(db);

🎯 Eksamensrelevant

  • Forstå at SQLite er embedded (ikke klient-tjener)
  • Vite at hele databasen er i én fil
  • Kunne forklare fordeler og ulemper med embedded database

🔄 Transaksjoner

💡 ACID-egenskaper

  • Atomicity: Alt eller intet - transaksjonen fullfører helt eller rulles tilbake
  • Consistency: Databasen går fra én gyldig tilstand til en annen
  • Isolation: Transaksjoner kjører isolert fra hverandre
  • Durability: Når transaksjonen er committed, er endringene permanente
-- Transaksjon eksempel BEGIN TRANSACTION; UPDATE konto SET saldo = saldo - 1000 WHERE kontonr = 123; UPDATE konto SET saldo = saldo + 1000 WHERE kontonr = 456; COMMIT; -- Eller ROLLBACK hvis noe gikk galt
⚠️ Viktig: Bruk transaksjoner når flere operasjoner må utføres som én atomisk enhet (f.eks. pengeoverføring mellom kontoer).

6️⃣ Uke 39: CGI, HTML-skjema, REST

Common Gateway Interface og RESTful web services

📌 Kapitteloppsummering

CGI (Common Gateway Interface) definerer hvordan web-tjener og CGI-programmer kommuniserer. Web-tjeneren kjører CGI-programmet og sender dets output til klienten. Miljøvariabler og stdin brukes for input, stdout for output. HTML-skjema sender data til server via GET eller POST. REST (REpresentational State Transfer) er arkitekturstil for web services basert på HTTP-metoder (GET, POST, PUT, DELETE) og ressurs-orienterte URL'er.

🔧 Common Gateway Interface (CGI)

💡 Hva er CGI?

Spesifikasjon som definerer hvordan web-tjener og CGI-skript/programmer kommuniserer.

Slik fungerer det:

  1. URL refererer til fil som skal kjøres (CGI-programmet)
  2. Web-tjener kjører programmet
  3. Utskrift fra programmet sendes til klienten som HTTP-responsens kropp
  4. Web-tjeneren sender begynnelsen av HTTP-hodet
  5. CGI-programmet sender slutten av hodet (+ tom linje) og kroppen

CGI-transaksjon (Pseudokode)

// Tjener mottar POST-forespørsel if (fork() == 0) { // Ny prosess behandler forespørsel dup(); // Redirigerer socket til STDIN og STDOUT read(); // Mottatt hode til og med tom linje write(); // Skriver begynnelsen av respons-hodet setenv(); // Setter diverse miljøvariabler exec(CGI-program); } // CGI-programmet: write(slutten av respons-hodet + tom linje); write(respons-kroppen); exit();

🎯 Eksamensrelevant

  • Forstå CGI-flyten: tjener kjører program, output sendes til klient
  • Vite at CGI-program må skrive Content-Type og tom linje
  • Forstå at ny prosess startes for hver forespørsel (overhead!)

🌍 Miljøvariabler i CGI

💡 Viktige miljøvariabler

Web-tjeneren setter miljøvariabler som CGI-programmet arver:

Basert på HTTP-forespørsel

  • REQUEST_METHOD: GET, POST, PUT, DELETE, etc.
  • QUERY_STRING: Det som står etter ? i URL'en
  • CONTENT_TYPE: MIME-type av kroppen
  • CONTENT_LENGTH: Lengden av kroppen (i bytes)
  • SERVER_PROTOCOL: HTTP-versjon
  • SERVER_PORT: Port-nummer
  • PATH_INFO: Ekstra sti-informasjon
  • REMOTE_ADDR: Klientens IP-adresse
  • REMOTE_HOST: Klientens vertsnavn
  • HTTP_*: HTTP-header-felter (f.eks. HTTP_USER_AGENT)

Uavhengig av forespørsel

  • SERVER_SOFTWARE: Navn/versjon av web-tjener
  • SERVER_NAME: Vertsnavnet
  • GATEWAY_INTERFACE: CGI-versjon
#!/bin/sh # miljo.cgi - Viser alle miljøvariabler echo "Content-type:text/plain;charset=utf-8" echo "" # Tom linje! env | sort
⚠️ Viktig: CGI-programmet kan ikke regne med EOF når det leser HTTP-kroppen! Bruk CONTENT_LENGTH for å vite når du skal slutte å lese.

⚖️ CGI Fordeler og Ulemper

✅ Fordeler

  • Enkelhet: Lett å forstå og implementere
  • Språk-uavhengighet: Kan skrives i hvilket som helst språk
  • Web-tjener-uavhengighet: Fungerer med de fleste web-tjenere
  • Stor utbredelse: Tidligere 'de facto' standard

❌ Ulemper

  • Ytelse: Ny prosess for hver forespørsel (resursskrevende)
  • Flaskehals: All kommunikasjon må gå via web-tjeneren
  • Tilstandsløshet: Ingen transaksjonsstøtte, må logge inn/ut for hver forespørsel
  • Sikkerhet: Mange CGI-programmer starter shells - brukerinput kan inneholde farlig kode
  • Konkuranse: Mange prosesser konkurrerer om minne, disk, CPU

🎯 Eksamensrelevant

Kunne liste opp og forklare både fordeler og ulemper ved CGI. Spesielt viktig: ytelsesproblem med prosess per forespørsel og sikkerhetsproblemer med shell injection.

📝 HTML-skjema

💡 HTML Forms

HTML-skjema lar brukere sende data til server. Data sendes til URL spesifisert i action-attributt.

<form action="behandle.cgi" method="POST"> <label for="navn">Navn:</label> <input type="text" id="navn" name="navn"> <label for="epost">E-post:</label> <input type="email" id="epost" name="epost"> <input type="submit" value="Send"> </form>

GET vs POST

  • GET:
    • Data sendes i QUERY_STRING (synlig i URL)
    • Begrenset lengde
    • Idempotent (kan gjenta uten sideeffekter)
    • Brukes for søk og visning
  • POST:
    • Data sendes i HTTP-kroppen (via stdin i CGI)
    • Ingen lengdebegrensning
    • Ikke idempotent
    • Brukes for oppdateringer og sensitive data
# GET-eksempel (data i QUERY_STRING) <a href="hallo.cgi?navn=Arne">Arne</a> #!/bin/sh # hallo.cgi echo "Content-type:text/plain;charset=utf-8" echo "" echo "Hallo $QUERY_STRING"
⚠️ Sikkerhet: Aldri stol på brukerinput! Valider og sanitiser alltid data fra skjema. Bruk prepared statements ved database-spørringer.

🌐 Web Services og REST

💡 Om Web Services

Web Services er tjenester tilgjengelig over nettverk (typisk HTTP). To hovedtilnærminger:

  • SOAP: Simple Object Access Protocol - kompleks, XML-basert
  • REST: REpresentational State Transfer - enklere, fleksibel

SOAP (Simple Object Access Protocol)

  • XML-basert meldingsprotokoll
  • Formell kontrakt via WSDL (Web Services Description Language)
  • Tung og kompleks
  • UDDI for service discovery

REST (REpresentational State Transfer)

Arkitekturstil med følgende prinsipper:

  • Klient-tjener: Separasjon av bekymringer
  • Tilstandsløs: Hver forespørsel inneholder all nødvendig info
  • Cachebar: Responser kan caches
  • Uniform interface: Ressurs-identifikasjon via URL'er
  • Lagdelt system: Klient vet ikke om den snakker direkte med server

💡 REST HTTP-metoder

  • GET: Hent ressurs (idempotent, safe)
  • POST: Opprett ny ressurs
  • PUT: Oppdater/erstatt ressurs (idempotent)
  • DELETE: Slett ressurs (idempotent)
  • PATCH: Delvis oppdatering
# REST eksempler # Hent liste over bøker GET /api/books # Hent spesifikk bok GET /api/books/222 # Opprett ny bok POST /api/books Content-Type: application/json {"title": "Min bok", "author": "Forfatter"} # Oppdater bok PUT /api/books/222 Content-Type: application/json {"title": "Oppdatert tittel", "author": "Forfatter"} # Slett bok DELETE /api/books/222

HTTP Statuskoder

  • 200 OK: Suksess
  • 201 Created: Ressurs opprettet
  • 204 No Content: Suksess, ingen kropp
  • 400 Bad Request: Ugyldig forespørsel
  • 401 Unauthorized: Autentisering kreves
  • 403 Forbidden: Ingen tilgang
  • 404 Not Found: Ressurs finnes ikke
  • 500 Internal Server Error: Serverfeil

🎯 Eksamensrelevant

  • Forstå REST-prinsipper (ressurs-orientert, tilstandsløs, uniform interface)
  • Vite hva GET, POST, PUT, DELETE brukes til
  • Forstå idempotens (GET, PUT, DELETE er idempotente)
  • Kunne designe en enkel RESTful API
  • Kjenne til vanlige HTTP-statuskoder

🔍 REST vs SOAP

Aspekt REST SOAP
Protokoll Arkitekturstil (bruker HTTP) Protokoll (kan bruke HTTP, SMTP, etc.)
Format JSON, XML, HTML, tekst Kun XML
Kompleksitet Enkel Kompleks
Ytelse Raskere Tregere
Caching Støttes naturlig Vanskelig
Kontrakt Ingen formell kontrakt WSDL (streng kontrakt)

Når bruke hva?

  • REST: Offentlige API'er, mobile apps, moderne web services
  • SOAP: Enterprise-systemer som krever formelle kontrakter og transaksjoner

7️⃣ Uke 44: Informasjonskapsler & JavaScript

Cookies, sessions, JavaScript fundamentals

📌 Kapitteloppsummering

Informasjonskapsler (cookies) implementerer tilstand i den tilstandsløse HTTP ved at tjener instruerer klient til å lagre og sende tilbake navn-verdi-par. JavaScript er et dynamisk, objektorientert skriptspråk mye brukt på både klient- og tjenerside. JavaScript har dynamiske variabler (type bestemmes ved tilordning), tre primitive typer (boolean, number, string) og objekter for alt annet.

🍪 Informasjonskapsler (Cookies)

💡 Hvorfor cookies?

HTTP er tilstandsløs - hver forespørsel er uavhengig. Cookies lar oss implementere tilstand ved at:

  1. Tjener sender Set-Cookie: header
  2. Klient lagrer cookien
  3. Klient sender Cookie: header i etterfølgende forespørsler
#!/bin/sh # kaketest.cgi echo "Set-cookie:kake1=xyz" echo "Content-type:text/plain;charset=utf-8" echo "" echo HTTP_COOKIE: $HTTP_COOKIE

Cookie-attributter

  • Domain: Hvilke domener som får cookien
  • Path: Hvilke stier cookien gjelder for
  • Expires/Max-Age: Når cookien utløper
  • Secure: Kun sendt over HTTPS
  • HttpOnly: Ikke tilgjengelig via JavaScript (XSS-beskyttelse)
  • SameSite: CSRF-beskyttelse (Strict, Lax, None)
# Eksempel med attributter Set-Cookie: sessionid=abc123; Path=/; HttpOnly; Secure; SameSite=Strict
⚠️ Sikkerhet: Bruk alltid HttpOnly for session-cookies (beskyttelse mot XSS). Bruk Secure for å kreve HTTPS. Bruk SameSite for CSRF-beskyttelse.

🎯 Eksamensrelevant

  • Forklare hvorfor cookies trengs (tilstand i tilstandsløs HTTP)
  • Vite at tjener sender Set-Cookie, klient sender Cookie
  • Kjenne til sikkerhetsflagg: HttpOnly, Secure, SameSite

📜 JavaScript - Grunnspråket

💡 Om JavaScript

  • JavaScript/JScript/ActionScript implementerer ECMAScript (ES)
  • Mye brukt på web (klient- OG tjenerside)
  • Objektorientert (klasseløst opprinnelig, klasser i ES6)
  • Java-lignende syntax, men IKKE Java!
  • Dynamiske variabler (type bestemmes ved tilordning)
  • Skiller mellom store og små bokstaver

Dynamiske variabeltyper

var a, b; a = 1 + '2'; // a blir '12' (string) b = 1 + 2; // b blir 3 (number) console.log(a, b); // 12 3

Tre grunnleggende datatyper (primitiver)

  • boolean: true eller false
  • number: 64-bits flyttall (ingen int/float-skille)
  • string: Null eller flere Unicode-tegn

Alt annet er objekter!

// Boolean var sann = true; var usann = false; // Number var heltall = 42; var desimal = 3.14; var hex = 0xFF; var okt = 0o77; // String var tekst = "Hallo verden"; var enkelt = 'Med enkle fnutter'; var concat = "Hallo" + " " + "verden";

Spesielle verdier

  • null: Bevisst ingen verdi (ikke samme som 0)
  • undefined: Variabel som ikke eksisterer eller ikke er initialisert
  • NaN: Not a Number (resultat av ugyldig matematikk)
  • Infinity: Uendelig
undefined == null // true typeof(undefined) // "undefined" typeof(null) // "object" (kjent JavaScript-bug!) '5' * 'x' // NaN 5 / 0 // Infinity

🔤 Typekonverteringer

// Addisjon med string blir konkatenering '5' + 4 // '54' '5' + '4' // '54' // Multiplikasjon konverterer til tall '5' * '4' // 20 '5' * 4 // 20 // Subtraksjon konverterer til tall '5' - '4' // 1 '5' - 4 // 1 // Ugyldig konvertering gir NaN '5' * 'x' // NaN 5 * 'x' // NaN
⚠️ Viktig: Bruk === og !== for streng sammenligning (type og verdi). == og != konverterer typer automatisk.

📦 Objekter og Arrays

Objekter (hashtabeller/assosiative arrays)

// Objekt-literal var person = { navn: "Ola", alder: 25, epost: "ola@example.com" }; // Tilgang til properties console.log(person.navn); // "Ola" console.log(person['navn']); // "Ola" // Legge til property person.by = "Oslo"; // Slette property delete person.epost;

Arrays (tabeller)

// Array-literal var tall = [1, 2, 3, 4, 5]; var blandet = [1, "to", true, null]; // Tilgang console.log(tall[0]); // 1 console.log(tall.length); // 5 // Metoder tall.push(6); // Legg til på slutten tall.pop(); // Fjern fra slutten tall.shift(); // Fjern fra starten tall.unshift(0); // Legg til på starten // Iterasjon for (var i = 0; i < tall.length; i++) { console.log(tall[i]); } // Moderne iterasjon tall.forEach(function(element) { console.log(element); });

🎯 Eksamensrelevant

  • Forstå at JavaScript-objekter er hashtabeller
  • Vite at arrays kan inneholde forskjellige typer
  • Kjenne til vanlige array-metoder (push, pop, shift, unshift)

🔧 Funksjoner

// Funksjonserklæring function leggSammen(a, b) { return a + b; } // Funksjonsuttrykk var multipliser = function(a, b) { return a * b; }; // Arrow function (ES6) var divider = (a, b) => a / b; // Kall console.log(leggSammen(2, 3)); // 5 console.log(multipliser(4, 5)); // 20 console.log(divider(10, 2)); // 5

Variablers gyldighetsområde (scope)

  • var: Funksjons-scope (function scope)
  • let: Blokk-scope (block scope) - ES6
  • const: Blokk-scope, kan ikke reassignes - ES6
function test() { var x = 1; if (true) { var x = 2; // Samme variabel! console.log(x); // 2 } console.log(x); // 2 } function test2() { let x = 1; if (true) { let x = 2; // Ny variabel i blokk console.log(x); // 2 } console.log(x); // 1 }

Midlertidige objekter (Wrapper Objects)

Primitiver oppfører seg som objekter når nødvendig:

var tekst = "hallo"; typeof(tekst); // "string" tekst.toUpperCase(); // "HALLO" (midlertidig objekt!) typeof(tekst); // Fortsatt "string" var tall = 42; tall.toString(); // "42" tall.toString(16); // "2a" (hex)

🔄 Flytkontroll

// if-else if (x > 10) { console.log("Stor"); } else if (x > 5) { console.log("Middels"); } else { console.log("Liten"); } // switch switch (dag) { case "mandag": console.log("Uke start"); break; case "fredag": console.log("Uke slutt"); break; default: console.log("Midt i uka"); } // for-løkke for (var i = 0; i < 10; i++) { console.log(i); } // while-løkke while (x < 100) { x = x * 2; } // do-while do { x++; } while (x < 10);

Feilhåndtering

try { // Kode som kan feile throw new Error("Noe gikk galt!"); } catch (e) { console.error("Feil:", e.message); } finally { // Kjøres alltid console.log("Rydder opp"); }

🎯 Eksamensrelevant

  • Forstå dynamiske variabler i JavaScript
  • Kjenne til de tre primitive typene
  • Forstå typekonvertering (spesielt string + number)
  • Vite forskjellen mellom == og ===
  • Kjenne til null vs undefined
  • Forstå funksjoner som first-class citizens

8️⃣ Uke 44: Web-apper

JavaScript i nettleseren, DOM, events, AJAX

📌 Kapitteloppsummering

JavaScript i nettleseren har tilgang til DOM (Document Object Model) for å manipulere HTML. Event-drevet programmering lar oss reagere på brukerhandlinger. AJAX (Asynchronous JavaScript and XML) lar oss hente data uten å laste siden på nytt. Moderne web-apper bruker fetch API, Promises og async/await for asynkron kommunikasjon.

🌐 JavaScript i Nettleseren

💡 JavaScript i HTML

Tre måter å inkludere JavaScript:

  1. Inline: I HTML-attributter (ikke anbefalt)
  2. Internal: I <script>-tag
  3. External: Egen .js-fil (best practice)
<!-- Inline (unngå dette) --> <button onclick="alert('Klikket!')">Klikk</button> <!-- Internal --> <script> console.log('Hallo fra script-tag'); </script> <!-- External (anbefalt) --> <script src="script.js"></script>

Global objekt: window

I nettleseren er det globale objektet window:

  • window.alert() - Vis dialogboks
  • window.console.log() - Logg til konsoll
  • window.document - Tilgang til DOM
  • window.location - URL-informasjon
  • window.setTimeout() - Forsinket kjøring
  • window.setInterval() - Gjentatt kjøring
// window kan utelates alert('Hallo'); // Samme som window.alert('Hallo') console.log('Test'); // Samme som window.console.log('Test') // Timers setTimeout(function() { console.log('Etter 2 sekunder'); }, 2000); var intervall = setInterval(function() { console.log('Hvert sekund'); }, 1000); clearInterval(intervall); // Stopp interval

🌳 DOM (Document Object Model)

💡 Hva er DOM?

DOM er en tre-representasjon av HTML-dokumentet. JavaScript kan:

  • Finne elementer
  • Endre innhold og attributter
  • Legge til/fjerne elementer
  • Endre CSS-stiler
  • Reagere på events

Finne elementer

// Gamle metoder document.getElementById('minId'); document.getElementsByClassName('minKlasse'); document.getElementsByTagName('p'); // Moderne metoder (anbefalt) document.querySelector('#minId'); // Første match document.querySelectorAll('.minKlasse'); // Alle matches

Endre innhold

var element = document.querySelector('#demo'); // Endre tekst element.textContent = 'Ny tekst'; // Endre HTML element.innerHTML = '<strong>Fet tekst</strong>'; // Endre attributter element.setAttribute('class', 'aktiv'); element.id = 'nyttId'; // Endre stiler element.style.color = 'red'; element.style.backgroundColor = 'yellow';

Legge til/fjerne elementer

// Opprett nytt element var nyP = document.createElement('p'); nyP.textContent = 'Nytt avsnitt'; // Legg til i DOM document.body.appendChild(nyP); // Sett inn før annet element var forsteParagraf = document.querySelector('p'); document.body.insertBefore(nyP, forsteParagraf); // Fjern element var gammelt = document.querySelector('#gammel'); gammelt.parentNode.removeChild(gammelt); // Moderne måte (ikke støttet i IE) gammelt.remove();

🎯 Eksamensrelevant

  • Forstå at DOM er tre-representasjon av HTML
  • Kunne bruke querySelector/querySelectorAll
  • Vite hvordan endre innhold (textContent, innerHTML)
  • Kunne legge til/fjerne elementer dynamisk

⚡ Events (Hendelser)

💡 Event-drevet programmering

JavaScript reagerer på brukerhandlinger via events:

  • Klikk (click)
  • Tastaturinput (keydown, keyup, keypress)
  • Musebevegelse (mouseover, mouseout, mousemove)
  • Skjema (submit, change, focus, blur)
  • Vindus-events (load, resize, scroll)

Legge til event listeners

// Modern måte (anbefalt) var knapp = document.querySelector('#minKnapp'); knapp.addEventListener('click', function(event) { console.log('Knapp klikket!'); console.log('Event:', event); }); // Kan også bruke arrow function knapp.addEventListener('click', (e) => { console.log('Klikket på:', e.target); }); // Fjerne event listener function handleKlikk(e) { console.log('Klikk!'); } knapp.addEventListener('click', handleKlikk); knapp.removeEventListener('click', handleKlikk);

Event-objektet

element.addEventListener('click', function(e) { // Event properties console.log(e.type); // 'click' console.log(e.target); // Element som ble klikket console.log(e.currentTarget); // Element med listener // Forhindre default oppførsel e.preventDefault(); // Stopp event propagation e.stopPropagation(); });

Event bubbling og capturing

Events "bobbler" opp fra child til parent:

<div id="ytre"> <div id="indre"> <button id="knapp">Klikk</button> </div> </div> // Klikk på button trigger events i rekkefølge: // 1. button (target) // 2. div#indre (bubbling) // 3. div#ytre (bubbling) // Stopp bubbling button.addEventListener('click', function(e) { e.stopPropagation(); });
⚠️ Viktig: Bruk addEventListener, ikke onclick-attributter. Det lar deg legge til flere listeners og gir bedre separasjon.

🌐 AJAX og Asynkron Kommunikasjon

💡 Hva er AJAX?

AJAX (Asynchronous JavaScript And XML) lar oss:

  • Hente data fra server uten å laste siden på nytt
  • Sende data til server i bakgrunnen
  • Oppdatere deler av siden dynamisk

Gammel måte: XMLHttpRequest

var xhr = new XMLHttpRequest(); xhr.open('GET', '/api/data', true); xhr.onload = function() { if (xhr.status === 200) { var data = JSON.parse(xhr.responseText); console.log(data); } }; xhr.onerror = function() { console.error('Feil ved henting'); }; xhr.send();

Modern måte: fetch API

// GET request fetch('/api/data') .then(response => response.json()) .then(data => { console.log('Data:', data); }) .catch(error => { console.error('Feil:', error); }); // POST request fetch('/api/data', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ navn: 'Ola', alder: 25 }) }) .then(response => response.json()) .then(data => console.log('Respons:', data)) .catch(error => console.error('Feil:', error));

Async/Await (modern og enklere)

async function hentData() { try { const response = await fetch('/api/data'); const data = await response.json(); console.log('Data:', data); return data; } catch (error) { console.error('Feil:', error); } } // Kall funksjonen hentData();

Promises

Promise representerer en fremtidig verdi:

// Opprette Promise const minPromise = new Promise((resolve, reject) => { setTimeout(() => { const suksess = true; if (suksess) { resolve('Suksess!'); } else { reject('Feil!'); } }, 1000); }); // Bruke Promise minPromise .then(resultat => console.log(resultat)) .catch(feil => console.error(feil)) .finally(() => console.log('Ferdig'));

🎯 Eksamensrelevant

  • Forstå hva AJAX er og hvorfor det brukes
  • Vite at fetch returnerer en Promise
  • Kunne bruke async/await for asynkron kode
  • Forstå forskjellen mellom synkron og asynkron kode

🔒 Sikkerhet i Web-apper

XSS (Cross-Site Scripting)

⚠️ Problem: Angriper injiserer ondsinnet JavaScript som kjøres i offerets nettleser.
// FARLIG - sårbar for XSS var brukerInput = '<script>alert("XSS")</script>'; element.innerHTML = brukerInput; // Script kjører! // SIKKERT - bruk textContent element.textContent = brukerInput; // Script kjører IKKE // SIKKERT - escape HTML function escapeHTML(str) { return str.replace(/[&<>"']/g, function(match) { const escape = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; return escape[match]; }); }

CSRF (Cross-Site Request Forgery)

Beskyttelse:

  • CSRF-tokens i skjema
  • SameSite cookie-attributt
  • Sjekk Referer/Origin headers

Content Security Policy (CSP)

// HTTP header for å begrense hva som kan lastes Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.com; style-src 'self' 'unsafe-inline';

🎯 Eksamensrelevant

  • Forstå XSS og hvordan unngå det (bruk textContent, ikke innerHTML)
  • Vite hva CSRF er og at tokens beskytter mot det
  • Kjenne til CSP som sikkerhetslag

9️⃣ Uke 45: Oppsummering & Eksamenstips

Gjennomgang av alle temaer og eksamensforberedelse

📌 Overordnet oppsummering

TSD3060 dekker sikker utvikling av webtjenester fra bunnen opp: OS-nivå sikkerhet (demonisering, chroot, namespaces), containerisering (Docker), webteknologier (HTML/XML/CSS), databaseprogrammering (SQLite, SQL injection), web-grensesnitt (CGI, REST), og klientside-programmering (JavaScript, DOM, AJAX). Sikkerhetstråden går gjennom hele kurset: isolasjon, prinsippet om minste privilegium, input-validering, og beskyttelse mot vanlige angrep (SQL injection, XSS, CSRF).

🗺️ Temaer etter uke

💡 Uke 33: Demonisering, port 80, chroot

  • Demonisering: Bakgrunnsprosesser uten terminal
  • Port 80: Krever root, dropp privilegier etter binding
  • chroot: Endrer rotkatalog for isolasjon (begrenset)

💡 Uke 34: OS-nivå virtualisering

  • Namespaces: 7 typer isolasjon (PID, NET, MNT, UTS, IPC, USER, CGROUP)
  • Cgroups: Ressursbegrensning og måling
  • Containere = namespaces + cgroups + filsystem

💡 Uke 35-36: Docker/Podman

  • Images (statisk) vs Containere (dynamisk)
  • Dockerfile: Lagvis bygging (maks 127 lag)
  • Sikkerhet: Capabilities, AppArmor, user namespaces
  • Nettverk: bridge, host, none
  • Volumer: Persistering av data

💡 Uke 37: HTML, XML, CSS

  • HTML5: Ikke lenger SGML, nye elementer (audio, video, canvas)
  • XML: Semistrukturerte data, velformet vs gyldig
  • DOM vs SAX: Tre-basert vs hendelse-basert parsing
  • CSS: Separerer innhold fra presentasjon

💡 Uke 38: SQLite

  • Embedded database (ingen server)
  • ODBC/JDBC: Standardiserte API
  • Prepared statements: Beskyttelse mot SQL injection
  • ACID-transaksjoner

💡 Uke 39: CGI og REST

  • CGI: Miljøvariabler, stdin/stdout, ny prosess per forespørsel
  • HTML-skjema: GET vs POST
  • REST: Ressurs-orientert, HTTP-metoder (GET, POST, PUT, DELETE)
  • REST vs SOAP: Enkelhet vs kompleksitet

💡 Uke 44: Cookies og JavaScript

  • Cookies: Tilstand i tilstandsløs HTTP
  • Cookie-sikkerhet: HttpOnly, Secure, SameSite
  • JavaScript: Dynamiske typer, 3 primitiver + objekter
  • DOM: Manipulere HTML fra JavaScript
  • AJAX: Asynkron kommunikasjon (fetch, async/await)

🔐 Gjennomgående sikkerhetstema

Prinsippet om minste privilegium

  • Dropp root-privilegier etter behov (port 80)
  • Bruk chroot for filsystemisolasjon
  • Begrens capabilities i containere
  • Kjør prosesser som upriviligerte brukere

Isolasjon

  • chroot: Rotkatalog-isolasjon
  • Namespaces: Prosess-, nettverks-, filsystem-isolasjon
  • Containere: Kombinert isolasjon

Input-validering

  • SQL injection: Bruk prepared statements
  • XSS: Escape HTML, bruk textContent
  • Shell injection: Unngå shell-kall med brukerinput
  • CSRF: Bruk tokens og SameSite cookies
⚠️ Gylden regel: ALDRI stol på brukerinput! Valider, sanitiser, og escape alt.

📝 Eksamenstips

🎯 Viktige begreper å kunne forklare

  • Demonisering: Fork twice, setsid, chdir, umask, close fds
  • Namespace-typer: PID, NET, MNT, UTS, IPC, USER, CGROUP
  • Image vs Container: Statisk template vs kjørende instans
  • Prepared statements: Beskyttelse mot SQL injection
  • REST-prinsipper: Ressurs-orientert, tilstandsløs, uniform interface
  • Cookies: Set-Cookie (tjener) vs Cookie (klient)
  • DOM: Tre-representasjon av HTML

🎯 Vanlige eksamensspørsmål

  1. Forklar forskjellen mellom chroot og namespaces

    chroot endrer kun rotkatalog, ingen prosess-/nettverksisolasjon. Namespaces gir finkornet isolasjon av mange ressurser (PID, NET, etc.).

  2. Hvordan beskytte mot SQL injection?

    Bruk prepared statements / parameterized queries. ALDRI konkatenere brukerinput direkte inn i SQL.

  3. Hva er forskjellen mellom GET og POST?

    GET: Data i URL (QUERY_STRING), begrenset lengde, idempotent. POST: Data i kropp, ingen lengdebegrensning, ikke idempotent.

  4. Forklar hvordan Docker bruker cgroups

    Cgroups begrenser og måler ressursbruk (CPU, minne, I/O) for containere. Eksempel: docker run -m 4m begrenser minne.

  5. Hva er XSS og hvordan unngå det?

    Cross-Site Scripting: Angriper injiserer ondsinnet JavaScript. Unngå: Bruk textContent i stedet for innerHTML, escape HTML-tegn.

🎯 Kommandoer å kunne

# Docker docker build -t navn . docker run -it --rm alpine docker ps / docker ps -a docker exec -it CONTAINER /bin/sh # Namespaces unshare --pid --fork --mount-proc /bin/bash nsenter --target PID --pid --mount # SQLite sqlite3 database.db .tables .schema tablename # CGI miljøvariabler echo $REQUEST_METHOD echo $QUERY_STRING echo $CONTENT_LENGTH

🎯 Kodeeksempler å kunne skrive

  • Enkel Dockerfile (FROM, COPY, CMD, EXPOSE)
  • CGI-script som leser QUERY_STRING
  • SQL med prepared statement (Java/C)
  • HTML-skjema med POST
  • JavaScript med DOM-manipulering
  • Fetch API med async/await

📚 Studietips

Effektiv læring

  1. Aktiv repetisjon: Test deg selv uten å se i notater først
  2. Forklar til andre: Hvis du kan forklare det, forstår du det
  3. Lag sammenhenger: Koble temaer sammen (f.eks. sikkerhet går gjennom alt)
  4. Øv på koding: Skriv eksempler selv, ikke bare les
  5. Gammel eksamener: Øv på tidligere eksamensoppgaver

Prioritering siste uke før eksamen

  1. Høy prioritet:
    • Sikkerhet (SQL injection, XSS, CSRF)
    • Docker (images, containers, Dockerfile, sikkerhet)
    • REST API design
    • JavaScript grunnleggende + DOM
  2. Middels prioritet:
    • Namespaces og cgroups
    • CGI og miljøvariabler
    • HTML/XML/CSS grunnleggende
    • Cookies og sessions
  3. Lav prioritet (men les gjennom):
    • Demonisering (detaljer)
    • XML schemas og DTD
    • SOAP vs REST (vet hovedforskjeller)
⚠️ Eksamensdagen: Les oppgavene NØYE! Svar på det som spørres om, ikke alt du vet. Bruk tid på strukturering før du begynner å skrive.

✅ Sjekkliste før eksamen

Kan du forklare...

  • ☐ Demoniseringsprosessen (fork, setsid, etc.)?
  • ☐ Alle 7 namespace-typer?
  • ☐ Forskjellen mellom image og container?
  • ☐ Hvordan Dockerfile bygger images lagvis?
  • ☐ Hva cgroups, capabilities og AppArmor brukes til?
  • ☐ Forskjellen mellom DOM og SAX?
  • ☐ Hvordan prepared statements beskytter mot SQL injection?
  • ☐ CGI-flyten (miljøvariabler, stdin/stdout)?
  • ☐ REST-prinsipper og HTTP-metoder?
  • ☐ Hvordan cookies implementerer tilstand?
  • ☐ JavaScript: Datatyper, objekter, funksjoner?
  • ☐ DOM-manipulering og event handling?
  • ☐ XSS, CSRF og hvordan beskytte mot dem?

Kan du skrive kode for...

  • ☐ En enkel Dockerfile?
  • ☐ Et CGI-script som leser miljøvariabler?
  • ☐ SQL med prepared statement?
  • ☐ Et HTML-skjema?
  • ☐ JavaScript som endrer DOM?
  • ☐ Event listener i JavaScript?
  • ☐ Fetch API med async/await?

💡 Siste råd

Du har jobbet hardt, du er godt forberedt! Husk:

  • Ta deg god tid til å lese oppgavene
  • Svar på det som spørres om
  • Bruk eksempler for å illustrere
  • Strukturer svarene (punktlister, nummerering)
  • La koden få puste (kommentarer, mellomrom)

🎓 Lykke til på eksamen! 🚀

🎮 Quiz-spill

Test kunnskapene dine på en morsom måte!

Poeng 0
Spørsmål 1/30
Streak 0🔥
Nivå Nybegynner
Demonisering

Klikk "Start Quiz" for å begynne!