Perché utilizzare la funzione eval JavaScript è una cattiva idea?




12 Answers

la valutazione non è sempre cattiva. Ci sono momenti in cui è perfettamente appropriato.

Tuttavia, eval è attualmente e storicamente eccessivamente utilizzato da persone che non sanno cosa stanno facendo. Ciò include persone che scrivono tutorial JavaScript, sfortunatamente, e in alcuni casi questo può davvero avere conseguenze sulla sicurezza - o, più spesso, semplici bug. Quindi più possiamo fare per gettare un punto interrogativo su eval, meglio è. Ogni volta che usi eval hai bisogno di controllare il tuo operato, perché è probabile che tu possa farlo in un modo migliore, più sicuro e più pulito.

Per dare un esempio troppo tipico, per impostare il colore di un elemento con un ID memorizzato nella variabile "potato":

eval('document.' + potato + '.style.color = "red"');

Se gli autori del tipo di codice precedente avessero un indizio sulle basi del funzionamento degli oggetti JavaScript, si sarebbero resi conto che è possibile utilizzare parentesi quadre invece di nomi punto letterali, evitando la necessità di eval:

document[potato].style.color = 'red';

... che è molto più facile da leggere e meno potenzialmente buggy.

(Ma poi, qualcuno che / davvero / sapeva cosa stavano facendo avrebbe detto:

document.getElementById(potato).style.color = 'red';

che è più affidabile del vecchio trucco di accesso agli elementi DOM direttamente dall'oggetto del documento).

javascript security eval

La funzione eval è un modo semplice e potente per generare dinamicamente il codice, quindi quali sono gli avvertimenti?




Due punti vengono in mente:

  1. Sicurezza (ma fino a quando si genera la stringa da valutare da sé, questo potrebbe essere un non-problema)

  2. Prestazioni: fino a quando il codice da eseguire è sconosciuto, non può essere ottimizzato. (su javascript e performance, certamente la presentazione di Steve Yegge )




Solitamente è un problema solo se si passa l'input dell'utente eval.




Una cosa da tenere a mente è che spesso è possibile utilizzare eval () per eseguire il codice in un ambiente altrimenti limitato: i siti di social networking che bloccano specifiche funzioni JavaScript possono a volte essere ingannati rompendoli in un blocco eval -

eval('al' + 'er' + 't(\'' + 'hi there!' + '\')');

Quindi se stai cercando di eseguire qualche codice JavaScript dove altrimenti non potrebbe essere permesso ( Myspace , ti sto guardando ...) allora eval () può essere un trucco utile.

Tuttavia, per tutti i motivi sopra menzionati, non dovresti usarlo per il tuo codice, dove hai il controllo completo - non è solo necessario, e meglio è retrocesso allo scaffale degli "ingannevoli javascript JavaScript".




Insieme al resto delle risposte, non penso che le dichiarazioni di valutazione possano avere una minimizzazione avanzata.




A meno che tu non sia sicuro al 100% che il codice che viene valutato provenga da una fonte attendibile (solitamente la tua applicazione), allora è un modo sicuro per esporre il tuo sistema a un attacco di scripting cross-site.




Riduce notevolmente il tuo livello di sicurezza sulla sicurezza.




Non è necessariamente così male purché tu sappia in quale contesto lo stai utilizzando.

Se la tua applicazione utilizza eval() per creare un oggetto da qualche JSON che è tornato da un XMLHttpRequest al tuo sito, creato dal tuo codice lato server attendibile, probabilmente non è un problema.

Il codice JavaScript lato client non attendibile non può comunque fare altrettanto. A condizione che la cosa che stai eseguendo eval() sia venuta da una fonte ragionevole, stai bene.




Oltre ai possibili problemi di sicurezza se si sta eseguendo il codice inviato dall'utente, la maggior parte delle volte c'è un modo migliore che non comporta la ri-analisi del codice ogni volta che viene eseguito. Le funzioni anonime o le proprietà degli oggetti possono sostituire la maggior parte degli usi di eval e sono molto più sicuri e veloci.




Questo è uno dei buoni articoli che parlano di eval e di come non sia un male: http://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/

Non sto dicendo che dovresti andare a correre fuori e iniziare a usare eval () ovunque. In effetti, esistono pochissimi buoni casi d'uso per l'esecuzione di eval (). Sicuramente ci sono problemi con la chiarezza del codice, la debugabilità e certamente le prestazioni che non dovrebbero essere trascurate. Ma non dovresti aver paura di usarlo quando hai un caso in cui eval () ha senso. Prova a non usarlo per primo, ma non lasciare che nessuno ti spaventi a pensare che il tuo codice sia più fragile o meno sicuro quando eval () viene usato in modo appropriato.




Il motore JavaScript ha un numero di ottimizzazioni delle prestazioni che viene eseguito durante la fase di compilazione. Alcuni di questi si riducono ad essere in grado di analizzare essenzialmente in modo statico il codice mentre esegue il lex e predeterminare dove si trovano tutte le dichiarazioni di variabili e funzioni, in modo che sia necessario uno sforzo minore per risolvere gli identificatori durante l'esecuzione.

Ma se il Motore trova una valutazione (..) nel codice, in sostanza deve presumere che tutta la sua consapevolezza della posizione dell'identificatore potrebbe non essere valida, perché non può sapere esattamente al codice tempo che si può passare a eval (..) per modificare lo scope lessicale, o il contenuto dell'oggetto con cui si può passare, per creare un nuovo scope lessicale da consultare.

In altre parole, in senso pessimistico, la maggior parte di quelle ottimizzazioni che farebbe sono inutili se eval (..) è presente, quindi semplicemente non esegue affatto le ottimizzazioni.

Questo spiega tutto.

Riferimento:

https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/ch2.md#eval

https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/ch2.md#performance




Vorrei dire che non ha molta importanza se si utilizza eval() in javascript che viene eseguito nei browser. * (Avvertenza)

Tutti i browser moderni dispongono di una console per gli sviluppatori in cui è comunque possibile eseguire javascript arbitrari e qualsiasi sviluppatore semi-intelligente può guardare la sorgente JS e inserire tutti i bit di cui ha bisogno nella console di sviluppo per fare ciò che desidera.

* Finché gli endpoint del tuo server hanno la validazione e la sanificazione corrette dei valori forniti dall'utente, non dovrebbe importare ciò che viene analizzato e valutato nel javascript del tuo client.

Se dovessi chiedere se è adatto usare eval() in PHP, tuttavia, la risposta è NO , a meno che tu non autorizzi alcun valore che può essere passato alla tua dichiarazione di valutazione.




Related