Soluzione semplice per XSS

2

Ho un'idea su come sconfiggere XSS in modo così semplice che potrebbe funzionare e mi chiedevo se qualcuno avesse già fatto qualcosa di simile.

L'obiettivo qui non è l'efficienza ma la sicurezza. In altre parole, non mi interessa di scambiare bandwith per sicurezza. La mia idea sarebbe quella di servire ogni singolo personaggio all'interno di semplici tag HTML.

Sostanzialmente se il seguente, per qualsiasi motivo, sarebbe un exploit XSS funzionante: 0WNED!byXSS (che per qualsiasi ragione nessuno avrebbe rilevato), allora sarebbe servito come:

<i>0</i><i>W</i><i>N</i>E<i>D</i>!<i>by</i>X<i>S</i>S<i>

Fondamentalmente un ciclo si assicurerebbe di fare solo:

  • scrivi <i>
  • scrivi un singolo carattere
  • scrivi </i>

Qualcosa del genere potrebbe funzionare tecnicamente (problemi di performance e bandwith a parte) e qualcosa del genere è mai stato fatto?

Modifica

Ecco un esempio (semplificato) di ciò a cui sto pensando.

Invece di servire questo:

<html>
  <head>
    <title>Sample</title>
  </head>
  <body>
    <table>
      <tr>
        <td>Here goes user input</td>
        <td>potentially containing an XSS exploit</td>
      </tr>
    </table>
</table>
</body>
</html>

Mi servirebbe questo:

<html>
  <head>
    <title>Sample</title>
  </head>
  <body>
    <table>
      <tr>
        <td><i>H</i><i>e</i><i>r</i><i>e</i><i> </i><i>g</i><i>o</i><i>e</i><i>s</i><i> </i><i>u</i><i>s</i><i>e</i><i>r</i><i> </i><i>i</i><i>n</i><i>p</i><i>u</i><i>t</i></td>
        <td><i>p</i><i>o</i><i>t</i><i>e</i><i>n</i><i>t</i><i>i</i><i>a</i><i>l</i><i>l</i><i>y</i><i> </i><i>c</i><i>o</i><i>n</i><i>t</i><i>a</i><i>i</i><i>n</i><i>i</i><i>n</i><i>g</i><i> </i><i>a</i><i>n</i><i> </i><i>X</i><i>S</i><i>S</i><i> </i><i>e</i><i>x</i><i>p</i><i>l</i><i>o</i>it</td>
      </tr>
    </table>
</table>
</body>
</html>

Il tag <i> è stato scelto arbitrariamente, qualsiasi tag (preferibilmente a una sola lettera) farebbe.

Diverse funzionalità del sistema operativo / browser sembrano continuare a funzionare correttamente:

  • Posso ritagliare correttamente il menu negli appunti
  • Posso ancora cercare testo ( eg Posso cercare "goes" e nonostante ogni singola lettera di "vada" è racchiuso tra tag il browser lo trova ancora valido)

Considero che il motore di ricerca avrebbe comunque analizzato / indicizzato correttamente il contenuto (non troppo sicuro di quello che ha detto).

Per me sembra un modo abbastanza semplice ed efficace per prevenire molti exploit sulla base di cattivi input dell'utente.

    
posta Cedric Martin 10.03.2013 - 16:26
fonte

5 risposte

7

Sembra una soluzione sciocca a un problema già risolto:

  1. Utilizza una libreria di purificatore HTML per consentire solo un sottoinsieme sicuro, OR
  2. HTML sfugge caratteri di input discutibili come <>'"& ai loro equivalenti (ad esempio, < passa a &lt; ). Inoltre, se è necessario consentire alcune formattazioni (ad esempio, gli utenti possono inviare collegamenti, inserire testo in grassetto) utilizzare un sottoinsieme sicuro di un linguaggio di marcatura leggero in modo da convertire l'input dell'utente come [google link](http://www.google.com) in link di google .

Se il tuo schema era perfetto e inseriva ciascun carattere dell'utente non inserito in input carattere per carattere tra il proprio tag come <i>h</i><i>e</i><i>l</i><i>l</i><i>o</i> , personalmente non vedo comunque che un utente malintenzionato esegua facilmente un attacco XSS anche se qualcun altro potrebbe essere in grado pensare a qualcosa

Linee di attacco che potrebbero funzionare:

  • forse possono rovinare il DOM (inserendo i simboli di randagi < > ) e alcuni browser casuali proveranno a correggerli e risolverli in un modo non sicuro.
  • forse alcuni browser permetteranno a un utente malintenzionato di inserire backspace (unicode 08) e di scappare dai tag in qualche modo
  • o alcuni browser internamente ottimizzano i tag consecutivi, ad esempio li converte in <i>hello</i> .
  • o il tuo metodo di analisi del carattere di input dell'utente per carattere è imperfetto e superato.

Inoltre, con il tuo metodo non vedo come il tuo schema ti permetterebbe di fare qualcosa di stravagante che potresti voler fare; ad esempio, consentire agli utenti di formattare link di testo o post o qualsiasi altra cosa di fantasia. In questo caso, è più semplice mettere al bando i caratteri <>&'" che hanno un significato speciale in HTML.

    
risposta data 10.03.2013 - 18:54
fonte
5

Congratulazioni! ho riflettuto su questo e questo è in realtà un sistema di fuga piuttosto solido. Anche se può portare a errori, non credo che questo sia molto utile per un aggressore. Il motivo principale per cui una codifica della separazione dei caratteri è migliore di una codifica html tradizionale è che causa problemi con il payload di un utente malintenzionato.

Ad esempio, i filtri XSS a volte non riescono a prevenire l'XSS a seconda di dove è scritto sulla pagina. Se un filtro XSS prende in considerazione il solito <> mentre ignora un doublequote, questo è un vettore xss che utilizza il payload ";alert(1)// :

<script>
var j="";alert(1)//";
document.write(j);
</script>

Tuttavia, l'uso di un metodo di codifica per la separazione dei caratteri causerà un errore di analisi java:

<script>
var j="<i>"</i><i>a</i><i>l/i><i>e</i><i>r</i><i>t</i><i>";
document.write(j);
</script>

La codifica Html non è una panacea! Il browser decodifica automaticamente i valori HTML all'interno di un tag HTML e questo può portare a xss negli eventi DOM:

<a href="" onclick="alert('hi&#39;);alert(/xss/)//'">click</a>

In questo caso verranno visualizzate due caselle di avviso perché &#39; verrà automaticamente decodificato in una singola quota ' prima di essere valutato come javascript. Tuttavia, se puoi inserire solo un singolo carattere, otterrai un'eccezione nel carico utile.

La codifica HTML è piacevole perché il browser decodifica valori HTML come <form value="o&#39;connel"> nel previsto o'connell prima di inviarlo come richiesta. Se si utilizza un altro metodo di codifica xss, tutti i valori in ingresso dovranno essere decodificati, il che potrebbe causare problemi di filtro o danneggiamento dei dati.

Non credo che il sovraccarico di questo metodo di fuga giustifichi la sicurezza fornita. È preferibile utilizzare una codifica HTML tradizionale. Un buon sistema di template rende facile difendersi da xss.

    
risposta data 10.03.2013 - 20:24
fonte
2

Se il tuo carattere speciale è <i> e </i> e i dati che stai cercando di codificare o visualizzare includono < , i o > , dovrai "scappare" quei caratteri. (o il trio di 3 caratteri) Dal momento che sono caratteri abbastanza comuni, penso che dovrai assicurarti che siano sempre codificati / decodificati correttamente.

Quindi ora quello che abbiamo è una soluzione che richiede allo sviluppatore di garantire una corretta escaping. Dovremmo anche notare che non tutto è sfuggito in tutte le istanze. Vale a dire il tag <title> .

In un caso, un titolo può contenere nomi utente, nomi di prodotti, ecc. Se questa funzione viene utilizzata, l'escape condizionale dell'input dell'utente è un'altra cosa che lo sviluppatore dovrà ricordare. La prossima cosa da considerare è JSON e Javascript. Le cose non sono così semplici ora.

La soluzione che stai proponendo sta creando lo stesso problema che stai tentando di risolvere, anche se in un'altra forma: Richiede allo sviluppatore di sfuggire condizionatamente ai caratteri in base al contesto del valore da visualizzare.

Ulteriore complicanza è che qualsiasi DHTML creato da javascript deve essere visualizzato anche nel browser o se l'input dell'utente viene utilizzato per scaricare un'immagine:

   <img src="http://example.com/hackedUserDisplayName.js">

Inquestocasolosviluppatorevolevautilizzarel'inputdell'utenteperincluderlonellapagina,manonlohapulitocorrettamente.L'approccioditaggingnonsarebbestatousatoquieavrebberottol'URLdell'immagineselofossestato.

Tilodoperilpensierosullemisuredisicurezzaproattive,ecercoditrovareunapproccioone-size-fits-all,ma dovresti testare le tue idee con gli esempi XSS elencati in questa pagina.

Continua a provare e facci sapere se sei in grado di inventare un approccio più coerente per correggere XSS. Il risultato più probabile è che diventerai esperto in XSS. È una vittoria / vittoria.

    
risposta data 10.03.2013 - 19:38
fonte
1

XSS è un problema risolto. Solo perché gli exploit XSS continuano a essere trovati, non significa che non sia stato risolto. Significa semplicemente qualcuno in modo errato o non ha implementato una soluzione.

Questa soluzione che proponi qui è interessante, ma non la userei.

Per uno, probabilmente dovresti usare gli elementi span invece degli elementi i. Questo è un <span> seguito da 1 carattere seguito da </span> . moltiplicato per molti caratteri di input che la tua applicazione web consente. Imo, si tratta di un inutile eccesso di dati che devono essere memorizzati. Inoltre, devi ancora considerare input errati come i caratteri NULL, & lt ;, & gt ;,;, "," e altri simboli.

Inoltre, è meglio disinfettare l'input prima di archiviarlo in un database e nuovamente dopo averlo recuperato da un database. La soluzione che hai qui non farebbe nulla per santificare i dati dopo il recupero da un database - lo dico perché sono sicuro che tu ed io siamo entrambi d'accordo che non estrarrai un carattere dal database e lo inserirai all'interno di un intervallo tag.

    
risposta data 10.03.2013 - 19:10
fonte
0

Se stai cercando di eliminare completamente le possibilità di essere vulnerabile agli attacchi XSS, aggiungi questo al tuo script PHP. Quando prendi l'input dell'utente e lo inserisci in una variabile, come questo: $input = $_POST['input']; , invece di quello (che è vulnerabile al 100%) vai: $input = htmlspecialchars($_POST['input']); . Oppure puoi anche andare: htmlentities($input = $_POST['input']); .

    
risposta data 08.04.2016 - 20:19
fonte

Leggi altre domande sui tag