Domanda

Abbiamo un'applicazione ad alta sicurezza e vogliamo consentire agli utenti di inserire gli URL che altri utenti vedranno.

Questo introduce un alto rischio di hack XSS: un utente potrebbe potenzialmente inserire javascript che un altro utente finisce per eseguire. Poiché conserviamo dati sensibili, è essenziale che ciò non accada mai.

Quali sono le migliori pratiche per affrontare questo? Qualche whitelist di sicurezza o modello di escape da solo è abbastanza buono?

Qualche consiglio su come gestire i reindirizzamenti (" questo link non rientra nel nostro sito " messaggio in una pagina di avviso prima di seguire il link, ad esempio)

Esiste un argomento per non supportare affatto i link inseriti dall'utente?


Chiarimento:

Fondamentalmente i nostri utenti vogliono inserire:

  

stackoverflow.com

E fallo inviare a un altro utente:

<a href="http://stackoverflow.com">stackoverflow.com</a>

Quello di cui mi preoccupo davvero è che li usano in un hack XSS. Cioè essi inseriscono:

  

alert ( 'hacked!');

Quindi altri utenti ottengono questo link:

<a href="alert('hacked!');">stackoverflow.com</a>

Il mio esempio è solo quello di spiegare il rischio: sono ben consapevole del fatto che javascript e URL sono cose diverse, ma consentendo loro di inserire il secondo potrebbero essere in grado di eseguire il primo.

Rimarrai stupito da quanti siti puoi rompere con questo trucco - HTML è anche peggio. Se sanno gestire i collegamenti, sanno anche disinfettare <iframe>, <img> e riferimenti CSS intelligenti?

Sto lavorando in un ambiente ad alta sicurezza: un singolo hack XSS potrebbe comportare perdite molto elevate per noi. Sono felice di poter produrre un Regex (o utilizzare uno degli eccellenti suggerimenti finora) che potrebbe escludere tutto ciò che mi viene in mente, ma sarebbe sufficiente?

È stato utile?

Soluzione

Se pensi che gli URL non possano contenere codice, ripensaci!

https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet

Leggi e piangi.

Ecco come lo facciamo su Stack Overflow:

/// <summary>
/// returns "safe" URL, stripping anything outside normal charsets for URL
/// </summary>
public static string SanitizeUrl(string url)
{
    return Regex.Replace(url, @"[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]", "");
}

Altri suggerimenti

Il processo di rendering di un link " sicuro " dovrebbe passare attraverso tre o quattro passaggi:

  • Annulla l'escape / ricodifica della stringa che ti è stata data (RSnake ha documentato una serie di trucchi su http://ha.ckers.org/xss.html che utilizzano escape e UTF codifiche).
  • Pulisci il collegamento: i regex sono un buon inizio - assicurati di troncare la stringa o di gettarla via se contiene un " (o qualunque cosa tu usi per chiudere gli attributi nel tuo output); Se stai facendo i collegamenti solo come riferimento ad altre informazioni, puoi anche forzare il protocollo alla fine di questo processo - se la parte che precede i primi due punti non è "http" o "https", aggiungi "http: //" all'inizio. Ciò ti consente di creare collegamenti utilizzabili da input incompleti mentre un utente digita in un browser e ti dà un'ultima possibilità di inciampare in qualsiasi malizia che qualcuno ha cercato di intrufolarsi.
  • Verifica che il risultato sia un URL ben formato (protocollo: //host.domain [: port] [/ path] [/ [file]] [? queryField = queryValue] [#anchor]).
  • Possibilmente controlla il risultato rispetto a una lista nera del sito o prova a recuperarlo attraverso una sorta di controllo malware.

Se la sicurezza è una priorità, spero che gli utenti perdonino un po 'di paranoia in questo processo, anche se finisce per buttare via alcuni collegamenti sicuri.

Utilizza una libreria, come l'API OWASP-ESAPI:

Leggi quanto segue:

Ad esempio:

$url = "http://stackoverflow.com"; // e.g., 

Utilizza una libreria, come l'API OWASP-ESAPI:

Leggi quanto segue:

Ad esempio:

$url = "http://stackoverflow.com"; // e.g., 

Utilizza una libreria, come l'API OWASP-ESAPI:

Leggi quanto segue:

Ad esempio:

$url = "http://stackoverflow.com"; // e.g., 

Utilizza una libreria, come l'API OWASP-ESAPI:

Leggi quanto segue:

Ad esempio:

<*>

Un altro esempio è l'uso di una funzione integrata. PHP filter_var la funzione è un esempio:

<*>

L'uso di filter_var consente chiamate javascript e filtra schemi che non sono né http https . Utilizzo del OWASP ESAPI Sanitizer è probabilmente l'opzione migliore.

Ancora un altro esempio è il codice di WordPress :

Inoltre, poiché non è possibile sapere dove si collegano gli URL (ovvero potrebbe essere un URL valido, ma il contenuto dell'URL potrebbe essere malizioso), Google ha un navigazione sicura API che puoi chiamare:

Rotolare la propria regex per servizi igienico-sanitari è problematico per diversi motivi:

  • A meno che tu non sia Jon Skeet, il codice avrà errori.
  • Le API esistenti hanno molte ore di revisione e test alle spalle.
  • Le API di convalida degli URL esistenti considerano l'internazionalizzazione.
  • Le API esistenti saranno mantenute aggiornate con gli standard emergenti.

Altre questioni da considerare:

  • Quali schemi autorizzi (sono file: /// e telnet: // accettabili)?
  • Quali restrizioni vuoi porre sul contenuto dell'URL (sono ammessi gli URL malware)?
GET["user-homepage"]; $esapi = new ESAPI( "/etc/php5/esapi/ESAPI.xml" ); // Modified copy of ESAPI.xml $sanitizer = ESAPI::getSanitizer(); $sanitized_url = $sanitizer->getSanitizedURL( "user-homepage", $url );

Un altro esempio è l'uso di una funzione integrata. PHP filter_var la funzione è un esempio:

<*>

L'uso di filter_var consente chiamate javascript e filtra schemi che non sono né http https . Utilizzo del OWASP ESAPI Sanitizer è probabilmente l'opzione migliore.

Ancora un altro esempio è il codice di WordPress :

Inoltre, poiché non è possibile sapere dove si collegano gli URL (ovvero potrebbe essere un URL valido, ma il contenuto dell'URL potrebbe essere malizioso), Google ha un navigazione sicura API che puoi chiamare:

Rotolare la propria regex per servizi igienico-sanitari è problematico per diversi motivi:

  • A meno che tu non sia Jon Skeet, il codice avrà errori.
  • Le API esistenti hanno molte ore di revisione e test alle spalle.
  • Le API di convalida degli URL esistenti considerano l'internazionalizzazione.
  • Le API esistenti saranno mantenute aggiornate con gli standard emergenti.

Altre questioni da considerare:

  • Quali schemi autorizzi (sono file: /// e telnet: // accettabili)?
  • Quali restrizioni vuoi porre sul contenuto dell'URL (sono ammessi gli URL malware)?
GET["user-homepage"]; $sanitized_url = filter_var($url, FILTER_SANITIZE_URL);

Un altro esempio è l'uso di una funzione integrata. PHP filter_var la funzione è un esempio:

<*>

L'uso di filter_var consente chiamate javascript e filtra schemi che non sono né http https . Utilizzo del OWASP ESAPI Sanitizer è probabilmente l'opzione migliore.

Ancora un altro esempio è il codice di WordPress :

Inoltre, poiché non è possibile sapere dove si collegano gli URL (ovvero potrebbe essere un URL valido, ma il contenuto dell'URL potrebbe essere malizioso), Google ha un navigazione sicura API che puoi chiamare:

Rotolare la propria regex per servizi igienico-sanitari è problematico per diversi motivi:

  • A meno che tu non sia Jon Skeet, il codice avrà errori.
  • Le API esistenti hanno molte ore di revisione e test alle spalle.
  • Le API di convalida degli URL esistenti considerano l'internazionalizzazione.
  • Le API esistenti saranno mantenute aggiornate con gli standard emergenti.

Altre questioni da considerare:

  • Quali schemi autorizzi (sono file: /// e telnet: // accettabili)?
  • Quali restrizioni vuoi porre sul contenuto dell'URL (sono ammessi gli URL malware)?
GET["user-homepage"]; $esapi = new ESAPI( "/etc/php5/esapi/ESAPI.xml" ); // Modified copy of ESAPI.xml $sanitizer = ESAPI::getSanitizer(); $sanitized_url = $sanitizer->getSanitizedURL( "user-homepage", $url );

Un altro esempio è l'uso di una funzione integrata. PHP filter_var la funzione è un esempio:

<*>

L'uso di filter_var consente chiamate javascript e filtra schemi che non sono né http https . Utilizzo del OWASP ESAPI Sanitizer è probabilmente l'opzione migliore.

Ancora un altro esempio è il codice di WordPress :

Inoltre, poiché non è possibile sapere dove si collegano gli URL (ovvero potrebbe essere un URL valido, ma il contenuto dell'URL potrebbe essere malizioso), Google ha un navigazione sicura API che puoi chiamare:

Rotolare la propria regex per servizi igienico-sanitari è problematico per diversi motivi:

  • A meno che tu non sia Jon Skeet, il codice avrà errori.
  • Le API esistenti hanno molte ore di revisione e test alle spalle.
  • Le API di convalida degli URL esistenti considerano l'internazionalizzazione.
  • Le API esistenti saranno mantenute aggiornate con gli standard emergenti.

Altre questioni da considerare:

  • Quali schemi autorizzi (sono file: /// e telnet: // accettabili)?
  • Quali restrizioni vuoi porre sul contenuto dell'URL (sono ammessi gli URL malware)?

Solo HTMLE codifica i collegamenti quando li emetti. Assicurati di non consentire i collegamenti javascript: . (È meglio avere una lista bianca di protocolli accettati, ad esempio http, https e mailto.)

Non specifichi la lingua della tua applicazione, presumo quindi ASP.NET, e per questo puoi usare Libreria di scripting Microsoft Anti-Cross Site

È molto facile da usare, tutto ciò che serve è un'inclusione e basta :)

Mentre sei sull'argomento, perché non dare una lettura su Design Linee guida per applicazioni Web sicure

Se qualsiasi altra lingua .... se esiste una libreria per ASP.NET, deve essere disponibile anche per altri tipi di linguaggio (PHP, Python, ROR, ecc.)

Che ne dici di non visualizzarli come link? Usa il testo.

Combinato con un avvertimento per procedere a proprio rischio e pericolo può essere sufficiente.

addizione - vedi anche Devo disinfettare l'HTML markup per un CMS ospitato? per una discussione sulla sanificazione dell'input dell'utente

Nel mio progetto scritto in JavaScript uso questo regex come white list:

 url.match(/^((https?|ftp):\/\/|\.{0,2}\/)/)

l'unica limitazione è che devi mettere ./ in primo piano per i file nella stessa directory ma penso di poter convivere con quello.

Per Pythonistas, prova w3lib di Scrapy.

OWASP ESAPI precede Python 2.7 ed è archiviato su Codice Google ormai defunto .

Puoi usare un codice esadecimale per convertire l'intero URL e inviarlo al tuo server. In questo modo il cliente non capirà il contenuto a prima vista. Dopo aver letto il contenuto, è possibile decodificare l'URL del contenuto =? e inviarlo al browser.

Consentire un URL e consentire JavaScript sono 2 cose diverse.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top