2009-03-14 12 views
18

Una richiesta Ajax mi restituisce un array JSON standard riempito con gli input del mio utente. L'input è stato disinfettato e, utilizzando la funzione eval(), posso facilmente creare il mio oggetto javascript e aggiornare la mia pagina ...Eval è il male ... Allora cosa dovrei usare invece?

Quindi, ecco il problema. Non importa quanto io provi a disinfettare gli input, preferisco non usare la funzione eval(). Ho controllato su google come utilizzare "JSON in AJAX senza eval" e ho utilizzato diversi metodi diversi ...

Quale dovrei usare? Esiste un modo standard, di provata sicurezza per farlo?

+0

Dai un'occhiata alla: http://stackoverflow.com/questions/86513/why-is-using-javascript-eval-function-a-bad -idea –

+0

Penso che in questo caso la valutazione non sia malvagia ... Forse dovresti dare un'occhiata a questa domanda: [Quando l'eval() di JavaScript non è il male?] (http://stackoverflow.com/questions/197769/ when-is-javascripts-eval-not-evil) –

risposta

20

json.org ha una bella javascript library

semplice utilizzo:

JSON.parse('[{"some":"json"}]'); 
JSON.stringify([{some:'json'}]); 

Edit: Come sottolineato nei commenti, questo utilizza eval se si guarda attraverso la sua fonte (anche se sembra di essere sterilizzata prima)

per evitare del tutto, un'occhiata a json_parse o json-sans-eval

json2.js è insicuro, json_parse.js è lento, JSON-sans-eval.js è non-validante

+7

Utilizza anche eval. –

+2

Utilizza eval solo come fallback per i browser che non supportano nativamente l'oggetto JSON e se questo non ha la funzione "parse". –

+0

_json2.js è insicuro_ ** da dove si trova? ha 1mb di regex che sintetizza la stringa prima di utilizzare eval ** –

8

Direi che, una volta che l'input è stato disinfettato, eval è il modo migliore per andare. Se il tuo server viene compromesso, le persone saranno in grado di inviare comunque gli script che vogliono al client. Quindi mettere una valutazione non è un grosso rischio per la sicurezza. Se sei preoccupato per le persone che manipolano i pacchetti prima che raggiungano il client, di nuovo, gli stessi script possono essere modificati.

Non preoccuparti di valutazione. Ma assicurati di avvolgerlo in una prova ... cattura blocco in modo che gli utenti non ottengano errori JS se il tuo JSON viene manomesso.

:)

0

confronta con il modello di progettazione comando: http://en.wikipedia.org/wiki/Command_pattern. Detto questo, puoi definire con precisione le operazioni che un cliente può eseguire e la tua applicazione sarà sicura quanto l'interpretazione sottostante.

0

Dipende da ciò che stai cercando di ottenere con i servizi igienico-sanitari. Ho avuto un grande successo con il supporto del framework prototype per JSON e una valutazione sicura.

10

Esiste uno standard, modo collaudato e sicuro di fare questo?

C'è un modo standard proposto per farlo, nella prossima versione di JavaScript ECMAScript 3.1: JSON.parse.

Sarà supportato in IE8, Firefox 3.1/3.5 e molto probabilmente gli altri browser più diffusi in futuro. Nel frattempo, puoi ricorrere a, o usare esclusivamente, eval(). Il male può o non può essere; certamente sarà più lento di JSON.parse. Ma questo è il solito modo di analizzare JSON oggi.

Se un utente malintenzionato è in grado di iniettare JavaScript malcious nel contenuto che si sta diffondendo tramite JSON, si hanno maggiori problemi di cui preoccuparsi rispetto a eval-is-evil.

2

Per convertire in modo sicuro JSON in un oggetto JS, è necessario utilizzare un parser JSON come la funzione JSON.parse() fornita da this library.

0

Se si è certi che non c'è rischio di iniezione e non si è eval()ing in un ciclo, quindi utilizzare eval(). Comparerà favorevolmente ad altre opzioni che saranno certamente più lente, potrebbero rompersi e richiederanno al client di scaricare ulteriore codice.

0

"rubato" da jQuery

// Try to use the native JSON parser first 
return window.JSON && window.JSON.parse ? 
    window.JSON.parse(data) : 
    (new Function("return " + data))(); 
0

Problema: Il problema eval pone è che si esegue in ambito globale

eval.call(document, "console.log(this)") 
eval.call(navigator, "console.log(this)") 
eval.call(window, "console.log(this)") 
(function(){eval.call(document, "console.log(this)")})() 
>Window 

Scenario:

utente si assume stanno usando singoli attributi nel codice di markup di vari docum ent-elementi come un attributo onvisible

<img src="" onvisible="src='http://www.example.com/myimg.png';"> 

Desiderate ottenere tutti gli elementi con questo attributo, ruotare il onvisible-content-stringa in una chiusura e metterlo in una coda EventHandler. È qui che entra in gioco il costruttore della funzione JS.

Function === 0..constructor.constructor 
>true 

Function('return [this, arguments]').call(window, 1,2,3) 
>Window, Arguments[3]] 
Function('return [this, arguments]').call(document, 1,2,3) 
>Document, Arguments[3]] 
Function('return [this, arguments]').call(navigator, 1,2,3) 
>Navigator, Arguments[3]]  

Mettere tutto insieme:

var eventQueue = []; 
var els = document.querySelectorAll('[onvisible]'); 

for (var el in els) { 
    var jscode = els[el].getAttribute('onvisible'); 
    eventQueue.push({el:els[el], cb:Function(jscode)}) 
} 

//eventQueue[0].cb.call(scope, args); 
Problemi correlati