Lo scenario semplicistico sarebbe provare a inviare --><?php phpinfo();?><!--
. Se il tag <?php
è sfuggito, questo risulterebbe in
<!-- -->
<?php phpinfo();
<!-- -->
(newlines aggiunti per chiarezza). Ma la presenza di <?php ...?>
nella pagina HTML potrebbe non essere sufficiente; il codice PHP deve essere interpretato lato server, non solo restituito al client.
Esaminando più da vicino l'inizio della stringa risultante:
<!--?
è chiaro che non è il tag PHP, ma solo il <
che attiva l'escape, e probabilmente è inteso come una difesa HTML / XML / XSS. Ciò significa che non puoi inviare contenuti attivi e farli eseguire, o renderizzati in forma eseguibile dal client.
Anche in questo caso potresti provare con "pre-unescaping", inviando
< --><hr><!-- >
e vedere se questo viene trasformato ingenuamente in
<!----><hr><!-- -->
che dovrebbe essere visualizzato come HTML, o che è più completamente definito in
<!-- -- --><!-- hr --><!-- !-- -->
che non rende nulla utile. Questo dipende completamente da come viene effettuato il rilevamento dei tag aperti HTML e da come funziona. A volte preg_replace
viene utilizzato con espressioni regolari non corrette, incomplete o non-golose, che possono defangare solo il primo o l'ultimo tag o deframmentare ciecamente la prima apertura con l'ultima chiusura, ignorando le bugie nel mezzo. In questo caso, la pagina è vulnerabile all'iniezione di Javascript e a una serie di attacchi correlati.
Il codice sanitizzante è disponibile per l'ispezione?
Esempio di convalida ingenua
Ad esempio, questo codice apparentemente sanifica l'output HTML.
preg_replace("/<(.*)>/", "<!-- \1 -->", $input);
ma (a parte essere una misura mal concepita) la mancanza dell'operatore ungreedy? lo rende vulnerabile a un semplice attacco pre-non inescusabile:
<?php
$params = array(
"<script>alert('FAIL');</script>",
"< --><script>alert('Success');</script><!-- >",
);
foreach($params as $param)
print preg_replace("/<(.*)>/", "<!-- \1 -->", $param) . "\n\n\n";
?>
provoca il fallimento del primo attacco naive, mentre il secondo ha esito positivo:
<!-- script>alert('FAIL');</script -->
<!-- --><script>alert('Success');</script><!-- -->
Sfortunatamente, questa opzione preg_replace
è spesso suggerita o implementata come una "soluzione rapida" per gli attacchi di HTML injection e, poiché la maggior parte delle "correzioni temporanee" sono solite fare, potrebbe diventare permanente .
Una strategia migliore sarebbe quella di filtrare out tutto ciò che non appartiene al parametro originale (ad es. sostituire [^A-Za-z0-9_]
con niente), o pensare che la presenza di caratteri proibiti significhi che qualcosa di malvagio in questo modo viene , e quindi la reazione più sicura è eliminare la richiesta (magari informando l'utente, in caso di casualità o incidente un problema, ad esempio un link sintatticamente scorretto, da qualche altra parte, per cui è altamente raccomandato il logging di HTTP_REFERER
.