Introduksjon til Cross-Site Scripting (XSS) og JavaScript Defences

Cross-site scripting (XSS) er en av de mest utbredte websikkerhet sårbarheter, konsekvent rangering i OWASP Top 10. En XSS-angrep tillater en angriper å injisere skadelig klientside skript på nettsider som vises av andre brukere. Disse skriptene kan stjele sesjon tokens, omdirigere brukere til phishing-sider, deface sider eller installere malware. Mens serversiden sanitasjon er kritisk, JavaScript spiller en sentral rolle på klientsiden for å oppdage og forhindre disse angrepene. Denne artikkelen gir en omfattende, produksjonsklar guide til å bruke JavaScript for å beskytte applikasjonene dine fra XSS.

Forstå de tre typer XSS

Før du dykker i forebygging, er det viktig å forstå de tre primære kategoriene XSS: lagret, reflektert og DOM-basert. Hver krever en litt annen deteksjon og forebygging tilnærming.

Lagret XSS

Lagret (peristent) XSS oppstår når skadelig inndata lagres permanent på serveren (f.eks. i en database, foruminnlegg eller kommentar) og senere serveres til brukerne uten riktig sanisering. Angrepslasten utføres i nettleseren til alle som ser på det lagrede innholdet.

Reflektert XSS

Reflektert XSS skjer når det ondsinnede skriptet reflekteres fra en webserver, vanligvis via en URL-parameter eller skjemainnlevering. Angriperen trikser et offer til å klikke på en laget lenke, og den injiserte koden kjører umiddelbart. I motsetning til lagret XSS, vil nyttelasten ikke vare.

DOM-basert XSS

DOM-basert XSS er en ren klientside sårbarhet. Angreps payload endrer DOM-miljøet i offerets nettleser. Den ondsinnede koden berører aldri serveren; det stammer fra klientsiden JavaScript som utryggen håndterer brukerinngang (f.eks. lesing fra , eller ).

Oppdage XSS-angrep med JavaScript

Deteksjon handler om å identifisere mistenkelig aktivitet før skade oppstår. JavaScript kan overvåke brukerinndata, spore DOM-mutasjoner og validere data ved inngangspunkter. Selv om klientsiden deteksjon ikke kan fange alle angrep (spesielt hvis angriperhåndverket forespørsler direkte til serveren), gir det en verdifull første linje i forsvaret.

Inngangsvalidering og sanitisering

Valider alltid og sanitere brukerinnganger på klientsiden før behandling. Bruk [[FLT: 3]] i stedet for [[FLT: 4]] for å hindre skriptutføring. Følgende funksjonsstriper farlige tegn fra en streng:

function sanitizeInput(input) {
 const div = document.createElement('div');
 div.textContent = input;
 return div.innerHTML;
}

Dette fungerer fordi innstilling ikke tolker HTML-tagger; den behandler alt som vanlig tekst. Den resulterende inneholder rømte versjoner av alle HTML-spesialtegn (f.eks. , , ).

Overvåkning DOM Mutasjoner for supicious elements

Angripere ofte injiserer tags eller hendelseshåndteringer (], ]) i DOM. Ved å bruke API, kan du se på uventede elementinnsettinger. Et grunnleggende eksempel:

const observer = new MutationObserver((mutations) => {
 mutations.forEach((mutation) => {
 mutation.addedNodes.forEach((node) => {
 if (node.nodeType === 1) { // element node
 if (node.tagName === 'SCRIPT') {
 console.warn('Potential XSS: a script element was injected via DOM.');
 node.remove(); // or log and analyze
 }
 // Check for dangerous attributes
 if (node.hasAttribute('onerror') || node.hasAttribute('onload')) {
 console.warn('Suspicious event handler attribute detected.');
 }
 }
 });
 });
});
observer.observe(document.body, { childList: true, subtree: true });

Svakhet: Blokkeringsskripter via kan omgås av smarte angripere og kan bryte legitim funksjonalitet. Bruk dette som et overvåkingsverktøy i stedet for en primærforebyggingsmekanisme.

Validerer URL og hashparametere

For DOM-basert XSS, les URL-komponenter trygt ved hjelp av og unngå direkte innsettingsverdier i HTML. Oppdag forsøk på å passere kjørbar kode:

const params = new URLSearchParams(window.location.search);
const userParam = params.get('name');
if (userParam && /[<>"'\/]/.test(userParam)) {
 console.warn('Potential XSS in parameter: ' + userParam);
 // Do not use this value in the DOM without encoding
}

Forebygger XSS-angrep med JavaScript

Forebygging krever en flerlags tilnærming. JavaScript kan ikke sikre et program fullt ut, men når det kombineres med riktig backend sanitalisering og Kontent sikkerhetspolicy (CSP) reduserer det dramatisk risikoen.

Kod alle brukerkontrollerte data før du setter inn i DOM

Den gylne regelen: Legg aldri upålitelige data direkte inn i DOM. Bruk sikre DOM-metoder i stedet for indreHTML.

Bruk eller ]

const userInput = getUserInput();
const safeText = document.createTextNode(userInput);
document.getElementById('output').appendChild(safeText);

Når du må bruke , Sanitize med et bibliotek

Hvis du absolutt trenger å gjøre HTML (f.eks. fra en rik tekstredigeringsredaktør), stole på et pålitelig saniseringsbibliotek som DOMPurify. DOMPurify er et mye brukt, kamptestet bibliotek som fjerner skadelig kode mens du bevarer sikker HTML.

// Example with DOMPurify (install via npm or CDN)
const dirty = '<img src=x onerror="alert(1)">';
const clean = DOMPurify.sanitize(dirty);
document.getElementById('content').innerHTML = clean;

DOMPurify fungerer ved å tolke inngangen, strippe farlige tagger og attributter, og returnere bare tillatte elementer. Vis DOMMPurify på GitHub.

Unngå farlige JavaScript-funksjoner

Noen JavaScript-metoder og egenskaper er bemerkelsesverdige for å aktivere XSS. Unngå eller strengt kontroller:

  • ]] - bruk eller riktig sanitize.
  • ], ]] ⁇ samme regel.
  • ]] - aldri bruk med brukerinngang.
  • ]] kan utnyttes dersom noe innspill er konkatert.
  • ] / med strengkode] - unngå; bruk funksjonsreferanser i stedet.
  • ] Konstruktøren ⁇ analog med ].

Implementer innholdssikkerhetspolicy (CSP) via JavaScript? Anbefales ikke

CSP er en nettlesermekanisme som begrenser hvilke skript som kan kjøres. Den er vanligvis satt via HTTP-overskrifter, men du kan også angi den ved hjelp av en [FLT: 34] tag eller via JavaScript ved dynamisk å opprette et [FLT: 35] element. Men innstilling av CSP i JavaScript er mindre sikker fordi en angriper som allerede har noen kontroll kan deaktivere den. Alltid foretrekker HTTP-overskrift. Hvis du må bruke JavaScript til å håndheve CSP (f.eks. under utvikling), gjør det svært tidlig i sidelast:

const meta = document.createElement('meta');
meta.httpEquiv = 'Content-Security-Policy';
meta.content = "default-src 'self'; script-src 'self' 'unsafe-inline'"; // Be very careful with 'unsafe-inline'
document.head.appendChild(meta);

For produksjon, konfigurer CSP i webserveren eller omvendt proxy. MDN CSP-dokumentasjon gir omfattende veiledning.

Ytterligere sikkerhetstiltak

Utover JavaScript-spesifikke taktikk, inkluderer en komplett XSS-forebyggingsstrategi disse kritiske tiltakene:

  • Valider alltid på serversiden. Kundesiden validering kan omgås. Aldri stole på klientdata.
  • Bruk passende HTTP-responsoverskrifter. ], og spesielt .
  • Utgangskode hver gang du gjengir brukerdata. Kontekstproblemer: Koding for HTML-enheter, URL-koding, JavaScript-strengkoding, etc.
  • Behold avhengigheter oppdatert. sårbare JavaScript-biblioteker (f.eks. eldre versjoner av jQuery) er en vanlig XSS-vektor. Bruk npm-revisjon eller lignende verktøy.
  • Bruk rammeverk med innebygd XSS-beskyttelse. React, Angular og Vue automatisk unnslippe utdata som standard. Fortsatt, vær forsiktig med eller .
  • Implementer en streng CSP. Unngå og om mulig. Bruk nons eller hashes for inline skript.

Ekte verden eksempel: Sikker kommentar gjengivelse

Tenk på et bloggkommentarsystem der brukerne sender meldinger som vises til andre. En angriper kan prøve å sette inn . Her er en JavaScript-tilnærming som integreres med bakstykket:

  1. Frontend-innsendelse: Sanitize using ] før du sender til server (men serveren må fortsatt rense).
  2. Server gir data: Bakstykket skal HTML-kode kommentarteksten.
  3. Klient gjengivelse: Bruk eller en sikker malmotor. Bruk aldri med rå brukerdata.
function renderComment(comment) {
 const item = document.createElement('div');
 item.className = 'comment';
 const body = document.createElement('p');
 body.textContent = comment.body; // escaped by browser
 item.appendChild(body);
 document.getElementById('comments').appendChild(item);
}

Tester dine forsvarsverk

Etter å ha implementert forebygging, test programmet ditt ved hjelp av automatiserte skannere og manuelle nyttelaster. Vanlige testvektorer inkluderer:

Bruk nettleserutviklerverktøy for å undersøke DOM og sikre at nyttelastene er rømt. Også test CSP håndhevelse ved å sjekke konsollen for bruddsrapporter.

Konklusjon

Cross-site scripting forblir en alvorlig trussel, men JavaScript tilbyr kraftige verktøy for både deteksjon og forebygging. Ved å validere innganger, overvåke DOM endringer, unnslippe utgang og integrere med robuste biblioteker som DOMPurify, kan du betydelig herde din klient-side sikkerhet. Husk at klient-siden tiltak ikke er en sølv kule; de supplerer en forsvars-i-dybde strategi som inkluderer server-side sanitalisering, CSP-hoder og regelmessige sikkerhetsrevisjoner. Hold deg årvåken, test ofte, og hold bibliotekene oppdatert.

For videre lesing, se OWASP XSS-siden og ]OWASP XSS Prevention Cheat Sheet].