Domanda

Voglio prevenire attacchi XSS nella mia applicazione web.Ho scoperto che la codifica HTML dell'output può davvero prevenire gli attacchi XSS.Ora il problema è: come posso codificare in HTML ogni singolo output nella mia applicazione?C'è un modo per automatizzare questo?

Apprezzo le risposte per JSP, ASP.net e PHP.

È stato utile?

Soluzione

Non vuoi codificare tutto il codice HTML, vuoi solo codificare in HTML qualsiasi input dell'utente che stai generando.

Per PHP: htmlentities E htmlspecialchars

Altri suggerimenti

Una cosa che tu non dovrebbe fare è filtrare i dati di input man mano che arrivano.Le persone spesso lo suggeriscono perché è la soluzione più semplice, ma porta a problemi.

I dati di input possono essere inviati a più posti, oltre ad essere emessi come HTML.Potrebbe essere archiviato in un database, ad esempio.Le regole per filtrare i dati inviati a un database sono molto diverse dalle regole per filtrare l'output HTML.Se codifichi tutto in HTML in input, ti ritroverai con HTML nel tuo database.(Questo è anche il motivo per cui la funzione "virgolette magiche" di PHP è una cattiva idea.)

Non è possibile prevedere tutti i luoghi in cui viaggeranno i dati di input.L'approccio sicuro è preparare i dati appena prima è stato inviato da qualche parte.Se lo stai inviando a un database, evita le virgolette singole.Se stai emettendo HTML, esegui l'escape delle entità HTML.E una volta inviato da qualche parte, se hai ancora bisogno di lavorare con i dati, usa la versione originale senza escape.

Questo richiede più lavoro, ma puoi ridurlo utilizzando motori di modelli o librerie.

Per i JSP, puoi avere la tua torta e anche mangiarla, con il tag c:out, che sfugge all'XML per impostazione predefinita.Ciò significa che puoi associarti alle tue proprietà come elementi grezzi:

<input name="someName.someProperty" value="<c:out value='${someName.someProperty}' />" />

Quando associato a una stringa, someName.someProperty conterrà l'input XML, ma quando viene inviato alla pagina, verrà automaticamente eseguito l'escape per fornire le entità XML.Ciò è particolarmente utile per i collegamenti per la convalida della pagina.

Un modo carino che ho usato per sfuggire a tutti gli input dell'utente è scrivere un modificatore per smarty che sfugga a tutte le variabili passate al modello;ad eccezione di quelli a cui è collegato |unescape.In questo modo fornisci accesso HTML solo agli elementi a cui dai esplicitamente accesso.

Non ho più quel modificatore;ma circa la stessa versione può essere trovata qui:

http://www.madcat.nl/martijn/archives/16-Using-smarty-to-prevent-HTML-injection..html

Nella nuova versione di Django 1.0 funziona esattamente allo stesso modo, jay :)

La mia preferenza personale è codificare diligentemente nulla proveniente dal database, dal livello aziendale o dall'utente.

In ASP.Net questo viene fatto utilizzando Server.HtmlEncode(string) .

Il motivo per cui codificare qualsiasi cosa è che anche le proprietà che potresti presupporre siano booleane o numeriche potrebbero contenere codice dannoso (ad esempio, i valori delle caselle di controllo, se eseguiti in modo improprio, potrebbero tornare come stringhe.Se non li codifichi prima di inviare l'output all'utente, allora hai una vulnerabilità).

Potresti avvolgere eco/stampa ecc.nei tuoi metodi che puoi quindi utilizzare per sfuggire all'output.cioè.invece di

echo "blah";

utilizzo

myecho('blah');

potresti anche avere un secondo parametro che disattiva l'escape se ne hai bisogno.

In un progetto avevamo una modalità di debug nelle nostre funzioni di output che rendeva invisibile tutto il testo di output che passava attraverso il nostro metodo.Allora sapevamo che qualsiasi cosa rimasta sullo schermo NON era sfuggita!È stato molto utile rintracciare quei pezzi cattivi senza fuga :)

Se effettivamente codifichi in HTML ogni singolo output, l'utente vedrà il testo semplice di <html>invece di un'app Web funzionante.

MODIFICARE:Se codifichi HTML ogni singolo input, avrai problemi ad accettare password esterne contenenti < ecc..

L'unico modo per proteggerti veramente da questo tipo di attacco è filtrare rigorosamente tutti gli input che accetti, specificamente (ma non esclusivamente) dalle aree pubbliche della tua applicazione.Ti consiglierei di dare un'occhiata a Daniel Morris Classe di filtraggio PHP (una soluzione completa) e anche il Zend_Filter pacchetto (una raccolta di classi che puoi utilizzare per creare il tuo filtro).

PHP è il mio linguaggio preferito quando si tratta di sviluppo web, quindi mi scuso per il pregiudizio nella mia risposta.

Kieran.

OWASP ha una bella API per codificare l'output HTML, sia da utilizzare come testo HTML (ad es.paragrafo o <textarea> contenuto) o come valore di un attributo (ad es.per <input> tag dopo aver rifiutato un modulo):

encodeForHTML($input) // Encode data for use in HTML using HTML entity encoding
encodeForHTMLAttribute($input) // Encode data for use in HTML attributes.

Il progetto (la versione PHP) è ospitato sotto http://code.google.com/p/owasp-esapi-php/ ed è disponibile anche per alcune altre lingue, ad es..NETTO.

Ricorda che dovresti codificare qualunque cosa (non solo input dell'utente) e il più tardi possibile (non durante l'archiviazione nel DB ma durante l'emissione della risposta HTTP).

La codifica dell'output è di gran lunga la migliore difesa.La convalida dell'input è utile per molte ragioni, ma non è una difesa al 100%.Se un database viene infettato da XSS tramite attacco (ad es.ASPROX), la convalida dell'input di errori o contenuti dannosi non fa nulla.La codifica dell'output continuerà a funzionare.

c'era un buon saggio di Joel sul software (credo che il codice sbagliato sembri sbagliato, sono sul telefono altrimenti avrei un URL per te) che trattava l'uso corretto della notazione ungherese.La versione breve sarebbe qualcosa del tipo:

Var dsFirstName, uhsFirstName : String;

Begin

uhsFirstName := request.queryfields.value['firstname'];

dsFirstName := dsHtmlToDB(uhsFirstName);

Fondamentalmente prefiggi le tue variabili con qualcosa del tipo "noi" per stringa non sicura, "ds" per la sicurezza del database, "hs" per la sicurezza HTML.Vuoi solo codificare e decodificare dove ne hai effettivamente bisogno, non tutto.Ma usando i prefissi che deducono un significato utile guardando il tuo codice vedrai molto velocemente se qualcosa non va.E avrai comunque bisogno di funzioni di codifica/decodifica diverse.

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