Security+ Academy · Lektion

Inputvalidering og outputkodning

Implementér inputvalidering på serversiden og kontekstafhængig outputkodning for at neutralisere injection- og XSS-sårbarheder, før de kan udnyttes.

Lektion 1 af 413 trin

Inputvalidering og outputkodning er en gratis Security+ Academy-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Security+ Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Security+ Academy-kurset indeholder 4 lektioner i alt.

Hvorfor input er farligt

Alle data, som en applikation modtager udefra — input fra brugerformularer, URL-parametre, HTTP-headere, brødtekster i API-anmodninger og uploadede filer — kan potentielt styres af en angriber. Uden validering kan angribere indsætte SQL-kommandoer, HTML-scripts, shell-kommandoer samt XML-/LDAP-direktiver i applikationens dataflows. Inputvalidering og outputkodning er de to centrale kontroller, der uskadeliggør injektionssårbarheder, før de kan forårsage skade.

Hvad er inputvalidering?

Inputvalidering kontrollerer, at modtagne data overholder den forventede type, det forventede format, den forventede længde og det forventede værdiinterval, før applikationen behandler dem. Valideringen bør være serverbaseret — validering på klientsiden i JavaScript er let at omgå for angribere, der opsnapper anmodninger med værktøjer som Burp Suite. Et brugernavn bør kun acceptere alfanumeriske tegn; et datofelt bør kun acceptere gyldige datoformater; et e-mailfelt bør matche syntaksen i RFC 5322.

# Server-side input validation examples:

# Validate username: allow only alphanumeric and underscore
# Pattern: ^[a-zA-Z0-9_]{3,20}$
# Reject: 'admin--', "' OR 1=1--", '<script>alert(1)</script>'

# Validate age: must be integer between 0 and 120
# Reject: -1, 999, 'abc', '18; DROP TABLE users'

# Validate email: match RFC 5322 pattern, max 254 chars
# Reject: 'a@b' (too short), attacker@evil.com<script>...

Validering med tilladelsesliste kontra afvisningsliste

Validering med tilladelsesliste (whitelist) angiver præcis, hvad der ER tilladt, og afviser alt andet. Validering med afvisningsliste (blacklist) angiver, hvad der IKKE er tilladt, og tillader alt andet. Validering med tilladelsesliste foretrækkes altid, fordi angribere hele tiden opdager nye metoder til at omgå afvisningslister. Afvisningslister mod SQL-injektion forsøger for eksempel at blokere SELECT, UNION og tegnene --, men kreative kodninger omgår ofte disse filtre. En tilladelsesliste, der kun tillader cifre i et numerisk felt, kan ikke omgås.

# Allowlist (GOOD): only allow expected characters
# username_pattern = '^[a-zA-Z0-9_]{3,20}$'
# If input does not match -> reject with 400 Bad Request

# Denylist (WEAK): try to block known-bad patterns
# reject_patterns = ["'", '--', 'UNION', 'SELECT', 'DROP']
# Problem: attacker uses: SE%00LECT, UNION%0aALL, encoded chars
# Denylist is incomplete by definition -> prefer allowlist

Parametriserede forespørgsler forhindrer SQL-injektion

Til databaseinteraktioner er parametriserede forespørgsler (forberedte statements) det definitive forsvar mod SQL-injektion. Forespørgslens struktur defineres separat fra brugerleverede data, så databasemotoren aldrig fortolker input som SQL-syntaks. Selv hvis en bruger indtaster ' OR '1'='1, behandles det som en bogstavelig strengparameter og ikke som SQL, der skal udføres. Parametriserede forespørgsler findes i alle større sprog og databasedrivere.

# VULNERABLE: string concatenation (SQL injection possible)
# query = 'SELECT * FROM users WHERE name = ' + user_input
# Attack: user_input = "' OR '1'='1" -> returns ALL users

# SAFE: parameterized query
# query = 'SELECT * FROM users WHERE name = ?'
# cursor.execute(query, (user_input,))
# The ? is a placeholder; user_input is passed separately
# The DB driver handles escaping automatically
# Attack input: "' OR '1'='1" -> treated as literal string

Hvad er outputkodning?

Outputkodning konverterer specialtegn i data, før data indsættes i en outputkontekst (HTML, JavaScript, SQL, URL eller shell-kommandoer). Det sikrer, at data fra én kontekst ikke fortolkes som kode, der kan udføres, i en anden. Det vigtigste princip er kontekstafhængig kodning: Den anvendte kodning skal passe til outputkonteksten. HTML-kodning, URL-kodning, JavaScript-kodning og citering af shell-argumenter uskadeliggør hver især injektion i deres respektive kontekster.

HTML-outputkodning forhindrer XSS

Når brugerleverede data vises i HTML, skal specialtegn HTML-kodes for at forhindre Cross-Site Scripting (XSS). Tegnet < bliver til &lt;, > bliver til &gt;, og & bliver til &amp;. Hvis en angriber indtaster <script>alert('XSS')</script>, vises det som synlig tekst efter HTML-kodning i stedet for at udføre scriptet. Alle webframeworks har funktioner til HTML-kodning — brug dem konsekvent.

# Without encoding (VULNERABLE to XSS):
# html = '<p>Hello, ' + username + '</p>'
# If username = '<script>document.cookie</script>'
# -> script executes in victim browser

# With HTML encoding (SAFE):
# html = '<p>Hello, ' + html_encode(username) + '</p>'
# html_encode('<script>...') -> '&lt;script&gt;...&lt;/script&gt;'
# -> Displays as text, not executable script

Kontekstspecifikke kodningsregler

Forskellige outputkontekster kræver forskellige kodningsstrategier. HTML-brødtekst: kod < > & ' ". HTML-attributter: kod de samme tegn, og håndhæv desuden attributter omgivet af anførselstegn. JavaScript-kontekst: brug JSON-kodning eller escaping af JavaScript-strenge. URL-parametre: anvend procentkodning af specialtegn. Shell-kommandoer: undgå helt at konstruere shell-kommandoer ud fra brugerinput; brug i stedet sprogets API'er med argumenttabeller frem for strengsammenkædning med shellfortolkere.

# Context-aware encoding examples:

# HTML body context:
# safe_html = '&lt;script&gt;' (renders as text)

# URL parameter context:
# safe_url = 'search?q=hello%20world%26more'

# JavaScript string context (in JSON):
# safe_js = '{"name": "O\\u0027Reilly"}'

# Shell command (AVOID string concat - use array instead):
# UNSAFE: os.system('ping ' + user_input)
# SAFE:   subprocess.run(['ping', '-c', '1', user_input])

Validering på flere lag

Inputvalidering bør foregå på flere lag og ikke kun ved API-slutpunktet. Validering på klientsiden forbedrer brugeroplevelsen (øjeblikkelig feedback), men må aldrig betragtes som sikker. API-/controller-validering er det primære sikkerhedslag. Validering i tjenester og forretningslogik håndhæver domæneregler. Databasebegrænsninger (NOT NULL, CHECK, FOREIGN KEY) udgør det sidste forsvarslag. Forsvar i dybden betyder, at en omgåelse af ét lag ikke straks fører til udnyttelse.

Validering af filuploads

Input til filuploads er særligt farligt. Angribere uploader webshells (forklædt som billeder), ondsindede dokumenter (makroer) eller for store filer (DoS). Valideringen skal omfatte: kontrol af filtypen ud fra indholdet (magiske bytes) og ikke kun filendelsen; håndhævelse af maksimal filstørrelse; lagring af uploads uden for webroden; omdøbning af filer på serveren for at forhindre forudsigelige stier; scanning med antivirus/sandbox; og at uploadede filer aldrig udføres direkte.

# File upload validation steps:
# 1. Check Content-Type header (client-provided, not trusted alone)
# 2. Read first bytes (magic bytes):
#    JPEG: FF D8 FF | PNG: 89 50 4E 47 | PDF: 25 50 44 46
# 3. Reject if magic bytes don't match expected type
# 4. Enforce max size: reject > 10MB
# 5. Strip original filename, assign random UUID filename
# 6. Store in /var/uploads/ (NOT /var/www/html/)
# 7. Serve via CDN or application route (not direct URL)

Inputvalidering i API'er

Moderne applikationer bruger i vid udstrækning REST API'er og GraphQL, hvilket kræver validering af JSON-/XML-anmodningers brødtekster. Frameworks til API-validering som JSON Schema definerer obligatoriske felter, datatyper, strengmønstre og værdiintervaller. Begrænsning af GraphQL-dybde forhindrer, at dybt indlejrede forespørgsler forårsager DoS. Begrænsning af anmodningshastighed forhindrer automatiseret misbrug, selv når de enkelte input er gyldige. Skemavalidering bør udføres, før forretningslogikken behandler anmodningen.

# JSON Schema validation example:
# POST /api/register body schema:
# {
#   'type': 'object',
#   'required': ['username', 'email', 'password'],
#   'properties': {
#     'username': {'type': 'string', 'pattern': '^[a-zA-Z0-9_]{3,20}$'},
#     'email':    {'type': 'string', 'format': 'email', 'maxLength': 254},
#     'password': {'type': 'string', 'minLength': 12, 'maxLength': 128}
#   },
#   'additionalProperties': false
# }

Fejlmeddelelser og informationslækage

Fejlmeddelelser, der returneres til brugere, kan utilsigtet afsløre følsomme oplysninger, som hjælper angribere. Databasefejlmeddelelser kan afsløre tabelnavne, kolonnetyper eller SQL-syntaks. Stakspor afslører versioner af applikationsframeworks og filstier. Detaljerede fejl ved inputvalidering kan bekræfte over for en angriber, hvilke tegn der afvises, og hjælpe vedkommende med at udforme forsøg på at omgå valideringen. Bedste praksis er at returnere generiske, brugervenlige fejlmeddelelser til klienter (f.eks. 'Ugyldigt input'), mens detaljerede fejloplysninger logges på serversiden til fejlfinding for udviklere. Eksponér aldrig rå undtagelsesmeddelelser for slutbrugere.

# UNSAFE: returning detailed database error to user
# Error: 'You have an error in your SQL syntax near ... at line 1'
# Reveals: database type (MySQL), partial query structure

# UNSAFE: stack trace in API response
# Error: 'java.sql.SQLException at com.company.UserDAO.findByName:47'
# Reveals: framework (Java), class names, line numbers

# SAFE: generic error response to client
# HTTP 400 Bad Request: { 'error': 'Invalid request parameters' }
# Server log (internal only): full exception with stack trace
# Monitoring: alert on high error rates -> investigate internally

Hurtigt tjek

Test din forståelse af CompTIA Security+ (SY0-701)-begreberne fra denne lektion.

Opsamling af lektionen

I denne lektion har du lært, at serverbaseret inputvalidering med tilladelseslister sikrer, at kun forventede data behandles, at parametriserede forespørgsler forhindrer SQL-injektion ved at adskille data fra forespørgslens struktur, og at kontekstafhængig outputkodning forhindrer XSS og andre injektionsangreb ved at uskadeliggøre specialtegn, før de kommer ind i HTML-, JavaScript-, URL- eller shell-kontekster. Dernæst undersøger vi sikker håndtering af hemmeligheder og injektion af miljøvariabler.

Gratis at komme i gang

Lær Security+ Academy med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
30
Lektioner
120

Ofte stillede spørgsmål

Er lektionen “Inputvalidering og outputkodning” gratis?

Ja — alle 3 lektioner i læringssporet Security+ Academy, inklusive “Inputvalidering og outputkodning”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Security+ Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Inputvalidering og outputkodning”?

Implementér inputvalidering på serversiden og kontekstafhængig outputkodning for at neutralisere injection- og XSS-sårbarheder, før de kan udnyttes. Du øver dig i Security+ Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Security+ Academy?

Der kræves ingen tidligere erfaring. Security+ Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.

Hvor lang tid tager lektionen “Inputvalidering og outputkodning”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Security+ Academy-lektion?

Ja. Alle Security+ Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Inputvalidering og outputkodning
  2. Sikker håndtering af secrets og miljøvariabler
  3. Sikkerhed for afhængigheder og software composition analysis
  4. DevSecOps: Flyt sikkerheden til venstre i pipelines
← Tilbage til Security+ Academy