Introduktion till Cross-Site Scripting (XSS) och JavaScript Defenses
Cross-site scripting (XSS) är en av de mest utbredda webbsäkerhetsproblemen, konsekvent ranking i OWASP Top 10. En XSS-attack tillåter en angripare att injicera skadliga klient-side skript till webbsidor som ses av andra användare. Dessa skript kan stjäla sessionstokens, omdirigera användare till phishing webbplatser, förtalsidor eller installera skadlig kod. Medan server-side sanitization är avgörande, spelar JavaScript en avgörande roll på klientsidan för att upptäcka och förhindra dessa attacker.
Förstå de tre typerna av XSS
Innan dykning i förebyggande är det viktigt att förstå de tre primära kategorierna av XSS: lagras, reflekteras och DOM-baserade. Varje kräver en något annorlunda detektering och förebyggande tillvägagångssätt.
Förvaringsvis XSS
Lagrad (persistent) XSS inträffar när skadlig inmatning lagras permanent på servern (t.ex. i en databas, forumpost eller kommentar) och senare serveras till användare utan korrekt sanitet. Attack payload körs i webbläsaren för alla som tittar på det lagrade innehållet.
Reflekterad XSS
Reflekterade XSS händer när skadliga skript återspeglas av en webbserver, vanligtvis via en URL-parameter eller formulärinlämning. Angriparen lurar ett offer för att klicka på en utformad länk, och den injicerade koden körs omedelbart. Till skillnad från lagrad XSS, kvarstår inte nyttolast.
DOM-Based XSS
DOM-baserade XSS är en rent klient-side sårbarhet. Attack payload ändrar DOM-miljön i offrets webbläsare. Den skadliga koden rör aldrig servern; den härrör från klientsidan JavaScript som osäkert hanterar användarinmatning (t.ex., läsning från ], eller ]).
Upptäck XSS-attacker med JavaScript
Detektion handlar om att identifiera misstänkt aktivitet innan skada inträffar. JavaScript kan övervaka användarinmatningar, spåra DOM-mutationer och validera data vid ingångspunkter. Medan klient-side detektering inte kan fånga alla attacker (särskilt om angriparens hantverk begär direkt till servern), ger det en värdefull första försvarslinje.
Input Validation och Sanitization
Alltid validera och sanera användarinmatningar på klientsidan innan bearbetning. Använd ] istället för ] för att förhindra skript utförande. Följande funktion remsor farliga tecken från en sträng:
function sanitizeInput(input) {
const div = document.createElement('div');
div.textContent = input;
return div.innerHTML;
}
Detta fungerar eftersom inställning inte tolkar HTML-taggar; det behandlar allt som vanligt text. Den resulterande innehåller rymda versioner av några HTML-specialkaraktärer (t.ex. ], , ]).
Övervaka DOM Mutations för misstänkta element
Attackers injicerar ofta ] taggar eller händelsehanterare (]], ]]) i DOM. Med hjälp av ]]] API kan du titta på oväntade elementinsatser. Ett grundläggande exempel:
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 });
]Kaution: ] Blockering av skript via ]] kan kringgås av smarta angripare och kan bryta legitim funktionalitet. Använd detta som ett övervakningsverktyg snarare än en primär förebyggande mekanism.
Validera URL och Hash Parametrar
För DOM-baserade XSS, läs URL-komponenter säkert med ] och undvik att direkt infoga värden i HTML. Detektera försök att passera körbar kod:
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
}
Förhindra XSS-attacker med JavaScript
Förebyggande kräver ett flerskiktat tillvägagångssätt. JavaScript ensam kan inte helt säkra en ansökan, men i kombination med korrekt backend sanitization och ] Content Security Policy (CSP) , det minskar dramatiskt risken.
Koda alla användarkontrollerade data innan du sätter in i DOM
Den gyllene regeln: aldrig infoga opålitliga data direkt i DOM. Använd säkra DOM-metoder istället för innerHTML.
] eller ]
const userInput = getUserInput();
const safeText = document.createTextNode(userInput);
document.getElementById('output').appendChild(safeText);
När du måste använda , Sanitize med ett bibliotek
Om du absolut behöver göra HTML (t.ex. från en rik textredigerare), lita på ett betrodd sanitetsbibliotek som ]] DOMPurify ]]. DOMPurify är ett allmänt använt, stridstämt bibliotek som tar bort skadlig kod samtidigt som du bevarar säker 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 fungerar genom att parsera ingången, strippa farliga taggar och attribut, och returnera endast tillåtna element. Visa DOMPurify på GitHub
Undvik farliga JavaScript-funktioner
Vissa JavaScript-metoder och egenskaper är ökända för att aktivera XSS. Undvik eller strikt kontroll:
- []][]] -- använda eller rätta sanitera.
- []]]]] - samma regel.
- []]] – Använd aldrig med användarinmatning.
- []][]]]] kan utnyttjas om någon ingång är försonad.
- []]/ ]]] med stringkod[[] - undvik; använd istället funktionsreferenser.
- []]] konstruktion - analogt med ].
Genomföra innehållssäkerhetspolicy (CSP) via JavaScript?
CSP är en webbläsare mekanism som begränsar vilka skript kan köra. Det är vanligtvis inställd via HTTP rubriker, men du kan också ställa in det med en taggen eller via JavaScript genom att dynamiskt skapa en ] element. Men inställningen av CSP i JavaScript är mindre säker eftersom en angripare som redan har viss kontroll kan inaktivera det. Föredrar alltid HTTP rubrik. Om du måste använda JavaScript för att genomdriva CSP (t.
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);
För produktion, konfigurera CSP i din webbserver eller omvänd proxy. ]] MDN CSP-dokumentation] ger omfattande vägledning.
Ytterligare säkerhetsåtgärder
Utöver JavaScript-specifik taktik ingår en komplett XSS-förebyggande strategi dessa kritiska åtgärder:
- Alltid validera på serversidan. Kund-side validering kan kringgås. Lita aldrig på kunddata.
- ] Använd lämpliga HTTP-svarsrubriker. ]], ]]] och särskilt ]].
- Output kodar varje gång du gör användardata. Kontextfrågor: kod för HTML-enheter, URL-kodning, JavaScript-strängkodning etc.
- ]] Behålla beroenden uppdaterade. Sårbara JavaScript-bibliotek (t.ex. äldre versioner av jQuery) är en vanlig XSS-vektor. Använd npm-revision eller liknande verktyg.
- Använd ramar med inbyggt XSS-skydd. Reagera, vinkel och Vue undgår automatiskt utgång som standard. Fortfarande, var försiktig med eller ]]]
- ]] Genomföra en strikt CSP. Undvik ]] och ]]] om möjligt. Använd icke-er eller hash för inline-skript.
Real-World Exempel: Säker kommentar
Tänk på ett bloggkommentarsystem där användare skickar meddelanden som visas för andra. En angripare kan försöka infoga ]. Här är en JavaScript-strategi som integreras med backend:
- ] Frontend submission: Sanitize med ] innan du skickar till servern (men servern måste fortfarande sanitera).
- ]Server returnerar data:] backenden ska HTML-koda kommentartexten.
- Kundrendering: Använd eller en säker mallmotor. Använd aldrig ]] med råa användardata.
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);
}
Testa dina försvar
Efter att ha genomfört förebyggande, testa din ansökan med hjälp av automatiserade skannnrar och manuella nyttolast. Vanliga testvektorer inkluderar:
- ]
- ]
Använd verktyg för webbläsarutvecklare för att undersöka DOM och säkerställa att nyttolast undkommits. Testa också CSP-bekämpning genom att kontrollera konsolen för brottsrapporter.
Slutsats
Kors-site scripting är fortfarande ett allvarligt hot, men JavaScript erbjuder kraftfulla verktyg för både upptäckt och förebyggande. Genom att validera ingångar, övervaka DOM-förändringar, fly utgång och integrera med robusta bibliotek som DOMPurify, kan du avsevärt härda din klient-sida säkerhet. Kom ihåg att klient-sida åtgärder är inte en silverkula; de kompletterar en försvar-in-depth strategi som inkluderar server-side sanitization, CSP-headers och regelbundna säkerhetsgranskningar.
För vidare läsning, rådfråga ]OWASP XSS-sidan ] och ]]]OWASP XSS Prevention Cheat Sheet ].