Civiele & structurele engineering
Hoe Javascript te gebruiken om Cross-site Scripting (xss) Aanvallen te detecteren en te voorkomen
Table of Contents
Inleiding tot Cross-Site Scripting (XSS) en JavaScript Defenses
Cross-site scripting (XSS) is een van de meest voorkomende web security kwetsbaarheden, consequent rangschikken in de OWASP Top 10. Een XSS aanval maakt het mogelijk een aanvaller om kwaadaardige client-side scripts te injecteren in webpagina's bekeken door andere gebruikers. Deze scripts kunnen sessie tokens stelen, gebruikers omleiden naar phishing sites, deface pagina's, of malware installeren. Hoewel server-side sanitization is cruciaal, JavaScript speelt een cruciale rol aan de client kant om deze aanvallen te detecteren en te voorkomen. Dit artikel biedt een uitgebreide, productie-ready gids om JavaScript te gebruiken om uw toepassingen te beschermen tegen XSS.
De drie soorten XSS begrijpen
Voordat je in preventie gaat duiken, is het essentieel om de drie primaire categorieën van XSS te begrijpen: opgeslagen, gereflecteerd en DOM-gebaseerd. Elk vereist een iets andere detectie- en preventiebenadering.
Opgeslagen XSS
Opgeslagen (persistent) XSS treedt op wanneer kwaadaardige invoer permanent wordt opgeslagen op de server (bijvoorbeeld in een database, forumpost of commentaar) en later wordt geserveerd aan gebruikers zonder de juiste sanering. De aanval payload wordt uitgevoerd in de browser van iedereen die de opgeslagen inhoud bekijkt.
Reflected XSS
Reflected XSS gebeurt wanneer het kwaadaardige script wordt weerspiegeld van een webserver, meestal via een URL parameter of formulier indienen. De aanvaller trucs een slachtoffer in het klikken op een gemaakte link, en de geïnjecteerde code onmiddellijk uitvoert. In tegenstelling tot opgeslagen XSS, de lading niet blijven bestaan.
XSS op basis van DOM
DOM-gebaseerde XSS is een puur client-side kwetsbaarheid. De aanval lading wijzigt de DOM omgeving in de slachtoffer browser. De kwaadaardige code raakt nooit de server; het is afkomstig van client-side JavaScript die onveilig omgaan met de gebruiker invoer (bijv., lezen van , , of ).
XSS-aanvallen met JavaScript detecteren
Detectie gaat over het identificeren van verdachte activiteit voordat schade optreedt. JavaScript kan gebruikersinvoer monitoren, DOM-mutaties bijhouden en gegevens valideren bij ingangspunten. Hoewel client-side detectie niet alle aanvallen kan vangen (vooral als de aanvaller crafts verzoeken rechtstreeks naar de server), het biedt een waardevolle eerste lijn van verdediging.
Invoervalidatie en Sanitization
Altijd de gebruikersinvoer aan de clientzijde valideren en deactiveren voordat ze worden verwerkt. Gebruik in plaats van om scriptuitvoering te voorkomen. De volgende functie stript gevaarlijke tekens uit een string:
function sanitizeInput(input) {
const div = document.createElement('div');
div.textContent = input;
return div.innerHTML;
}
Dit werkt omdat instelling geen HTML-tags interpreteert; het behandelt alles als platte tekst. De resulterende bevat ontsnapte versies van enige speciale HTML-tekens (bv. , , ).
Monitoring van DOM-mutaties voor verdachte elementen
Aanvallers injecteren vaak tags of gebeurtenisverwerkers (], ]) in de DOM. Met behulp van de ] API kunt u kijken naar onverwachte elementeninbrengen. Een basisvoorbeeld:
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 });
Opgelet: Het blokkeren van scripts via kan worden omzeild door slimme aanvallers en kan legitieme functionaliteit breken. Gebruik dit als een monitoring instrument in plaats van een primair preventiemechanisme.
Valideren van URL- en Hashparameters
Lees voor DOM-gebaseerde XSS URL-componenten veilig met en vermijd direct invoegen van waarden in HTML. Probeert uitvoerbare code door te geven:
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
}
XSS aanvallen met JavaScript voorkomen
Preventie vereist een multi-layed aanpak. JavaScript alleen kan een toepassing niet volledig beveiligen, maar in combinatie met een goede backend sanering en Content Security Policy (CSP), vermindert het risico drastisch.
Codeer alle door de gebruiker gecontroleerde gegevens voordat u in DOM invoegt
De gouden regel: plaats nooit ongetrouwde gegevens direct in de DOM. Gebruik veilige DOM-methoden in plaats van innerHTML.
Gebruik of
const userInput = getUserInput();
const safeText = document.createTextNode(userInput);
document.getElementById('output').appendChild(safeText);
Wanneer u moet gebruiken, moet u zich met een bibliotheek reinigen
Als je absoluut HTML (bijv. van een rijke teksteditor) moet renderen, vertrouw dan op een vertrouwde sanitization library zoals DOMPurify[]. DOMPurify is een veelgebruikte, door de strijd geteste bibliotheek die kwaadaardige code verwijdert terwijl veilige HTML wordt bewaard.
// 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;
DOMpurFIVE werkt door de invoer te ontleden, gevaarlijke tags en attributen te strippen en alleen toegestane elementen terug te geven. Bekijk DOMPURIFICTIE op GitHub.
Voorkom gevaarlijke JavaScript-functies
Sommige JavaScript methoden en eigenschappen zijn berucht voor het inschakelen van XSS. Vermijd of strikt controle:
- , . Dezelfde regel.
- . . Gebruik nooit met gebruikersinvoer.
- / met stringcode .. Vermijden; gebruik functieverwijzingen in plaats daarvan.
- constructeur
Content Security Policy (CSP) implementeren via JavaScript? Niet aanbevolen
CSP is een browsermechanisme dat beperkt welke scripts kunnen draaien. Het wordt meestal ingesteld via HTTP-headers, maar je kunt het ook instellen met behulp van een tag of via JavaScript door dynamisch een element te creëren. Het instellen van CSP in JavaScript is echter minder veilig omdat een aanvaller die al enige controle heeft het kan uitschakelen. Altijd de voorkeur geven aan de HTTP-koptekst. Als je JavaScript moet gebruiken om CSP (bijv. tijdens de ontwikkeling) te handhaven, doe het dan heel vroeg in pagina laden:
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);
Voor productie, configureer CSP in uw webserver of reverse proxy. MDN CSP documentatie biedt uitgebreide begeleiding.
Aanvullende veiligheidsmaatregelen
Naast JavaScript-specifieke tactiek omvat een complete XSS preventiestrategie deze kritische maatregelen:
- Altijd valideren aan de serverkant. De validatie aan de clientzijde kan worden omzeild. Vertrouw nooit op clientgegevens.
- Gebruik passende HTTP-responskoppen. , , en vooral .
- Uitvoeren van codeer elke keer dat u gebruikersgegevens rendert. Context is belangrijk: coderen voor HTML entiteiten, URL-codering, JavaScript string codering, etc.
- Houd afhankelijkheden bijgewerkt. Kwetsbare JavaScript bibliotheken (bijv. oudere versies van jQuery) zijn een veel voorkomende XSS vector. Gebruik npm audit of soortgelijke tools.
- Gebruik kaders met ingebouwde XSS-bescherming. Reageer, hoek en Vue automatisch ontsnappen uitvoer standaard. Wees toch voorzichtig met of .
- Implementeer een strikte CSP. Vermijd en indien mogelijk. Gebruik nonces of hashes voor inline scripts.
Real-World Voorbeeld: Veilige reactie Rendering
Beschouw een blog commentaar systeem waar gebruikers berichten die worden weergegeven aan anderen. Een aanvaller zou kunnen proberen om in te voegen . Hier is een JavaScript aanpak die integreert met de backend:
- Vortend indienen: Reinigen met voordat u naar de server stuurt (maar de server moet nog steeds worden gereinigd).
- Server geeft gegevens terug: De backend moet de commentaartekst HTML-coderen.
- Client rendering: Gebruik of een veilige template engine. Gebruik nooit met ruwe gebruikersgegevens.
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);
}
Testen van uw verdediging
Na het implementeren van preventie, test uw toepassing met behulp van geautomatiseerde scanners en handmatige lading. Gemeenschappelijke test vectoren omvatten:
Gebruik browser developer tools om de DOM te onderzoeken en ervoor te zorgen dat de lading ontsnapt. Ook, testen CSP handhaving door het controleren van de console op schending rapporten.
Conclusie
Cross-site scripting blijft een ernstige bedreiging, maar JavaScript biedt krachtige tools voor zowel detectie als preventie. Door input te valideren, DOM-wijzigingen te monitoren, te ontsnappen aan uitvoer en te integreren met robuuste bibliotheken zoals DOMpurify, kunt u uw client-side beveiliging aanzienlijk verharden. Onthoud dat client-side maatregelen geen zilveren kogel zijn; ze vormen een aanvulling op een verdediging-diepe strategie die server-side sanitization, CSP-headers en regelmatige beveiligingsaudits omvat. Blijf waakzaam, test vaak, en houd uw bibliotheken up-to-date.
Voor meer informatie, raadpleeg OWASP XSS pagina en OWASP XSS Prevention Cheat Sheet.