Quali sono i problemi di sicurezza con "eval ()" in JavaScript?

19

Ogni volta che qualcuno menziona eval (), tutti dicono che ci sono "problemi di sicurezza" con esso, ma nessuno mai entra nei dettagli di quello che sono. La maggior parte dei browser moderni sembra essere in grado di eseguire il debug di eval () così come del codice normale, e le affermazioni delle persone relative a una riduzione delle prestazioni sono discutibili / dipendenti dal browser.

Quindi, quali sono gli eventuali problemi associati a eval ()? Non sono stato in grado di trovare nulla che possa essere sfruttato con eval () in JavaScript. (Vedo problemi con il codice eval () sul server, ma eval () sul lato client sembra essere sicuro.)

    
posta Stack Tracer 15.07.2015 - 17:50
fonte

4 risposte

29

eval() esegue una stringa di caratteri come codice. Si utilizza eval() precisamente perché il contenuto della stringa non è noto in anticipo, o anche generato lato server; in sostanza, hai bisogno di eval() perché lo stesso JavaScript genererà la stringa da dati che sono disponibili solo dinamicamente, nel client.

Pertanto, eval() ha senso nelle situazioni in cui il codice JavaScript genera codice. Questo non è intrinsecamente evil , ma è difficile da fare in modo sicuro. I linguaggi di programmazione sono progettati per consentire all'essere umano di scrivere istruzioni che un computer comprende; a tal fine, qualsiasi linguaggio è pieno di piccole stranezze e comportamenti speciali che dovrebbero aiutare il programmatore umano (ad esempio l'aggiunta automatica di ";" alla fine di alcune istruzioni in JavaScript). Questo è tutto bello e dandy per la programmazione "normale"; ma quando generi codice da un altro programma, basato su dati che potrebbero essere potenzialmente ostili (ad es. estratto di stringa da altri utenti del sito), allora devi, come sviluppatore del generatore di codice, sapere < em> tutti queste stranezze e impedisci ai dati ostili di sfruttarli in modi dannosi.

In questo senso, i generatori di codice (e quindi eval() ) sostengono gli stessi problemi concettuali di SQL grezzo e la sua conseguenza, Attacchi SQL injection . Assemblando in fase di esecuzione una richiesta SQL da parametri forniti dall'esterno può essere eseguita in modo sicuro, ma ciò richiede un sacco di dettagli, quindi il solito consiglio è di non farlo. Ciò si riferisce al solito enigma di sicurezza, cioè che non è testabile: è possibile verificare se una parte di codice funziona correttamente su dati corretti, ma non che non funzioni mai in modo improprio su dati errati. Allo stesso modo, è possibile utilizzare eval() in modo sicuro, ma è così difficile nella pratica che è scoraggiato.

Tutto questo è detto in tutta la generalità. Nel tuo contesto specifico, eval() potrebbe essere sicuro. Tuttavia, ci vuole un certo sforzo per avere un contesto sicuro per l'uso di eval() , che in realtà ha bisogno di eval() .

    
risposta data 15.07.2015 - 18:03
fonte
12

eval () è un vettore possibile per lo scripting cross-site.
In circostanze normali, un utente malintenzionato che tenta l'XSS potrebbe voler ottenere script <script></script> tag dopo qualsiasi codifica, filtri o firewall potrebbero essere presenti. Se eval () è in funzione sull'input dell'utente, elimina la necessità di tag di script.

Eval è presente in molti script dannosi perché aiuta a offuscare codice e / o intrufolarsi di personaggi non autorizzati oltre i filtri. Per questo motivo, eval () viene spesso controllato per l'input dell'utente. Quindi, quando usi eval (), sei potenzialmente in grado di fornire all'aggressore uno dei loro strumenti necessari. Sto derubando una banca e so che non devo infilare una pistola oltre i metal detector perché ci sono un mucchio nel portaombrelli all'interno dell'edificio.

    
risposta data 15.07.2015 - 18:23
fonte
2

Come spiegato da altri, si può usare eval per creare dinamicamente codice che rende più difficile capire il flusso di controllo del programma. Ma, non considero la valutazione molto più malvagia di tutti gli altri modi per generare codice in fase di esecuzione, come document.write(...) , object.innerHTML(...) e altri. Sebbene questi siano principalmente usati per cambiare il DOM del programma, vengono anche utilizzati per inserire un nuovo codice (ad esempio aggiungere un'istruzione di script al codice o un nuovo elemento con un gestore onXXXX ecc.)

E anche se Eval è spesso usato negli attacchi (XSS, malvertisement ...) per aggirare i filtri o nascondere il vero scopo del codice, è spesso usato in una forma offuscata, cioè come z='ev'; z+='al'; v=window; v[z]("alert(1)") . Ciò significa che non sei dalla parte della sicurezza se cerchi semplicemente di filtrare il codice con chiamate esplicite di eval, perché o la chiamata viene offuscata o le funzioni "buone" come innerHTML vengono utilizzate per scopi non corretti.

    
risposta data 15.07.2015 - 19:10
fonte
2

Oltre ai grandi punti fatti qui, vorrei chiarire: ciò a cui si sta essenzialmente occupando ogni volta che si usa eval () è la risposta alle seguenti domande:

  • Vale la pena assicurarsi?
  • Quanto accuratamente posso proteggerlo ed è accettabile quel livello?
  • Quanto posso essere sicuro che rimarrà sicuro per le future evoluzioni del codebase e del team di sviluppo?
  • In che modo il rischio e la quantità di sforzi richiesti da quanto sopra sono paragonabili allo sforzo di costruire il codice in modo tale da non richiedere l'esecuzione di codice generato dinamicamente e possibilmente sconosciuto?

Se hai pensato a queste domande in modo più completo di quanto farebbe un utente malintenzionato e stai ancora considerando l'utilizzo di eval (), prova a farlo. Potresti scoprire di sentirti stanco di pensarlo durante il corso della tua carriera di sviluppo e iniziare a evitare il suo utilizzo semplicemente per principio.

    
risposta data 15.07.2015 - 19:50
fonte