Passando il codice PHP direttamente in JavaScript in HTML5

5

Voglio passare una stringa PHP direttamente a una variabile JavaScript e mantenere il carico sul server al minimo. Ho il seguente codice JavaScript in un file PHP per fare questo:

<!DOCTYPE html>
<html>
...
<body>

<section id="section1"></section>

<script>
var example = <?php json_encode($string_var, JSON_HEX_TAG);?>;
example.replace(/[<>]/g, (m) => {return m == "<"? "&lt;" : "&gt;";});
document.getElementById('section1').innerHTML = example;
</script>

...
</body>
</html>

La variabile $string_var proveniente da PHP è un input utente che non è stato disinfettato in alcun modo (cioè, non ho nemmeno eseguito htmlspecialchars() su di esso).

Il mio esempio è sicuro? O devo usare tutti questi flag per json_encode , cioè JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS ? So che questo esempio non segue le best practice, ma c'è qualche rischio concreto o vulnerabilità in esso?

References:

  1. Perché utilizzare JSON_HEX_TAG ?
  2. Risposte che consigliano i flag JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS per il json_encode di PHP:
posta flen 16.12.2017 - 23:52
fonte

1 risposta

6

JSON_HEX_TAG

Se stai riecheggiando in JS all'interno di un documento HTML (come nel tuo esempio), questo è necesarry o rischi di aprire un'enorme vulnerabilità XSS. Senza questo, un utente malintenzionato può pubblicare qualcosa sulla falsariga di questo:

</script>alert("XSS");</script>

Da PHP 5.4 questo problema è stato corretto e le barre sono sfuggite di default, ma ancora, non sai mai quale versione di PHP verrà eseguita sul tuo codice. Meglio prevenire che curare.

Come OP sottolinea, anche nelle versioni mai in PHP puoi inserire <!-- per rovinare l'intera pagina, causando probabilmente un comportamento inaspettato. Quindi il flag è effettivamente necessario in tutte le versioni di PHP.

JSON_HEX_QUOT e JSON_HEX_APOS

Per capire che cosa fa, dai un'occhiata al seguente esempio:

$array = array(
    "a" => "'",
    "b" => '"',
);

// This will output {"a":"'","b":"\""}
echo json_encode($array);

// This will output {"a":"\u0027","b":"\u0022"}
echo json_encode($array, JSON_HEX_QUOT | JSON_HEX_APOS);

Quindi le virgolette attorno ai valori letterali delle stringhe non vengono mai codificate. Le virgolette all'interno di stringhe letterali saranno sfuggite senza i flag e codificate con esse.

Secondo i tuoi riferimenti, questo è usato per rendere sicuro l'output da usare all'interno dei gestori di eventi (ad esempio gli attributi HTML). È vero che non sono strettamente necessari all'interno dei tag di script, ma non è del tutto corretto che siano sicuri nei gestori di eventi.

Dai un'occhiata a questo esempio, ad esempio:

<?php $data = array(" onmouseenter=alert(1) " => "foo"); ?>
<a onclick="x = <?= json_encode($data, JSON_HEX_QUOT | JSON_HEX_APOS); ?>">test</a>

Risultato:

<a onclick="x = {" onmouseenter=alert(1) ": "foo"}">test</a>

Penso che tu sia sicuro se racchiudi sempre i valori degli attributi tra virgolette singole, ma comunque ti sembra un po 'rischioso.

JSON_HEX_AMP

Citando tuo riferimento qui:

For compatibility with XHTML non-CDATA script blocks, do & as well.

Quindi, dato che stai facendo HTML5, questo non si applica a te, e non penso che ci sia comunque una vulnerabilità di sicurezza. Tuttavia, non fa male a codificare.

Conclusione

  • Per il tuo utilizzo - all'interno di un tag script in HTML5 - è sufficiente usare JSON_HEX_TAG .
  • Fare questo all'interno degli attributi (gestori di eventi) è pericoloso, almeno a meno che non li racchiudi tra virgolette singole.
  • Se fossi in te, creerei una piccola funzione di aiuto chiamata safe_json_encode che usa tutti e quattro i flag, e quindi la uso solo nei tag di script. La codifica più che necesarry non ti ferisce.

Ulteriori note

  • Assicurati di pubblicare la pagina con un tipo di contenuto e una codifica di caratteri corretti. Messing up può portare a modi per aggirare la codifica.
  • Se in seguito generi i valori delle variabili in HTML, devi pensare di nuovo a XSS. Usando valori dal tuo JSON, ad es. innerHTML o document.write non saranno sicuri. (Vedo che ti occupi di questo nella tua seconda riga di script.)

Disclaimar: si basa sulla ricerca che ho fatto oggi. Non sono un guru PHP. Se ti affidi a questo per qualcosa di critico, probabilmente vorresti fare qualche ricerca in più per assicurarti che non mi manchi qualcosa qui.

    
risposta data 17.12.2017 - 00:30
fonte

Leggi altre domande sui tag