Json: PHP to JavaScript sicuro o no?

Comprendo che l'utilizzo di eval(json_str) sul client è vulnerabile al codice dannoso. La mia domanda è, se json_str fosse un arrays costruito dalla function PHP json_encode , sarei al sicuro?

Per esempio,

 json_str = json_encode(arrays(record1, record2, record3)); 

sarebbe del tutto sicuro utilizzare eval(json_str) all'interno del codice lato client?

Sì e no:

Sì: PHP produce JSON valido

No: PHP può anche restituire codice dannoso come in JSON.

Se puoi fidarti della fonte, o se hai persino il pieno controllo su di essa (perché è tua), non ci sono problemi.

In termini di puro JavaScript, sì, si è sicuri: l'output di json_encode non può mai contenere altro che valori statici che non avranno alcun effetto inaspettato quando vengono passati a eval . (Anche se in genere devi circondare la tua string JSON con () quando usi eval , per evitare di interpretare erroneamente un'espressione letterale dell'object come un block di istruzioni.)

A parte questo, questo non è necessariamente vero per tutti gli encoder JSON perché ci sono alcuni caratteri che sono validi per includere raw in una string JSON che non sono validi come raw in JavaScript. In particolare, U + 2028 e U + 2029 che non possono essere sfortunati in stringhe di stringhe JavaScript in quanto costituiscono una nuova row. Tuttavia, il codificatore di PHP codifica tutti i caratteri non ASCII (ad es. "\u2028" ), quindi nessun problema qui.

In termini di JavaScript incorporato in un'altra lingua (in genere: HTML) non sei necessariamente al sicuro. Per esempio:

 <script type="text/javascript"> var v= <?php echo json_encode($value); ?>; </script> 

In questo esempio, che cosa succede se il value contiene una string con la sequenza di caratteri </script ? Ciò consentirebbe al valore di terminare prematuramente il block di script e quindi di eseguire l'escape nel markup HTML, where potrebbe quindi iniettare altri script dannosi.

Per evitare questo problema, quando includi il contenuto JSON in HTML, codifica sempre il carattere < in stringhe letterali, come \x3C o, in termini compatibili con JSON, \u003C . Per compatibilità con i blocchi di script XHTML non-CDATA, fare & pure. Per compatibilità con JS all'interno degli attributi del gestore di events, fare anche quotazioni.

PHP lo farà per te con le giuste opzioni per json_encode() :

 var v= <?php echo json_encode($value, JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS); ?>; 

(Si consiglia di definire una function di scelta rapida per rendere più veloce la scrittura).

Se si desidera utilizzare Content Security Policy (CSP) , viene impedito l'esecuzione di tag di script incorporati. Ciò renderebbe quindi imansible la risposta altrimenti sorprendente di Bobince poiché CSP richiede che tutto il JavaScript sia in file separati.

Come get il tuo JavaScript in un file separato:

Un modo per aggirare questo è quello di codificare in html il JSON con PHP (che dovrebbe prevenire XSS) e quindi farlo eco ad un elemento nascosto e quindi usare JavaScript per get il contenuto di quel tag (adattato da OWASP ):

Metti questo in linea (nota, non verrà effettivamente eseguito):

 <script id="jsonString" type="application/json"> <?php // OWASP uses a <script> tag with an invalid "type" attribute, but // you can just as easily use a <span style="display:none"> or other // hidden tag. // // Note, this probably won't actually be valid JSON because we are using // htmlspecialcharacters() on the JSON data. That doesn't matter because // this is never actually executed by the browser due to the incorrect // script type. We will decode it later into valid JSON. echo htmlspecialchars(json_encode($object), ENT_NOQUOTES); ?> </script> 

Quindi nel tuo file JavaScript:

 var dataElement = document.getElementById('jsonString'); // Get innerText, which also has the side effect of html decoding // the string returned, which is just what we want var jsonString = dataElement.textContent || dataElement.innerText; // Now you can parse the JSON string var jsonObj = JSON.parse(jsonString); 

Non utilizzare eval per l'analisi JSON

Non farlo

È molto probabile che il tuo server non venga mai compromesso e che la tua applicazione sia per lo più sicura, bla bla bla, non è questo il punto. È ansible che un server diventi parzialmente compromesso (troppi vettori di attacco, e se la function php json_encode compromise sul server?).

La soluzione semplice è non fidarsi di nulla inviato da nessuno . I browser moderni hanno parser JSON nativi e http://www.json.org fornisce una lunga list di parser JSON per varie lingue. Le versioni JS ricadranno sull'implementazione nativa per la velocità.

Ciò che tutto questo significa è che non c'è una buona ragione per usare eval per l'analisi di JSON.

Dovrebbe essere sicuro, ma sul client, non è garantito che json_str non sia stato iniettato da un'altra fonte.