Domanda

Ho configurato PHP in modo che le virgolette magiche siano attive e i registri globali siano disattivati.

Faccio del mio meglio per chiamare sempre htmlentities() per tutto ciò che sto emettendo derivato dall'input dell'utente.

Occasionalmente cerco anche nel mio database elementi comuni utilizzati in xss allegati come...

<script

Cos'altro dovrei fare e come posso assicurarmi che le cose che sto cercando di fare lo siano Sempre Fatto.

È stato utile?

Soluzione

Evitare l'input non è la soluzione migliore per prevenire efficacemente gli XSS.Anche l'output deve essere sottoposto a escape.Se utilizzi il motore di modelli Smarty, puoi utilizzare |escape:'htmlall' modificatore per convertire tutti i caratteri sensibili in entità HTML (uso own |e modificatore che è l'alias di quanto sopra).

Il mio approccio alla sicurezza input/output è:

  • memorizza l'input dell'utente non modificato (nessun escape HTML sull'input, solo escape compatibile con DB eseguito tramite istruzioni preparate PDO)
  • escape sull'output, a seconda del formato di output utilizzato (ad es.HTML e JSON necessitano di regole di escape diverse)

Altri suggerimenti

Sono dell'opinione che non si debba sfuggire nulla durante l'input, solo durante l'output.Poiché (la maggior parte delle volte) non puoi dare per scontato di sapere dove stanno andando i dati.Ad esempio, se disponi di un modulo che accetta dati che verranno visualizzati in seguito in un'e-mail inviata, è necessario un escape diverso (altrimenti un utente malintenzionato potrebbe riscrivere le intestazioni delle e-mail).

In altre parole, puoi sfuggire solo all'ultimo momento in cui i dati "lasciano" la tua applicazione:

  • Voce dell'elenco
  • Scrivi su file XML, esegui l'escape per XML
  • Scrivi su DB, esci (per quel particolare DBMS)
  • Scrivi e-mail, scappa per e-mail
  • eccetera

Per farla breve:

  1. Non sai dove vanno a finire i tuoi dati
  2. I dati potrebbero effettivamente finire in più di un posto, necessitando di meccanismi di fuga diversi MA NON ENTRAMBI
  3. I dati sfuggiti per il target sbagliato non sono davvero carini.(Per esempio.ricevere una email con oggetto "Vai al bar di Tommy".)

L'Esp n. 3 si verificherà se si eseguono l'escape dei dati nel livello di input (o è necessario eseguire nuovamente l'escape, ecc.).

PS:Seguirò il consiglio di non usare magic_quotes, quelle sono puro male!

Esistono molti modi per eseguire XSS (vedere http://ha.ckers.org/xss.html) ed è molto difficile da catturare.

Personalmente delego questo al framework attuale che sto utilizzando (Code Igniter per esempio).Sebbene non sia perfetto, potrebbe catturare più di quanto le mie routine fatte a mano abbiano mai fatto.

Questa è un'ottima domanda

Innanzitutto, non eseguire l'escape del testo durante l'input se non per renderlo sicuro per l'archiviazione (ad esempio per l'inserimento in un database).La ragione di ciò è che vuoi conservare ciò che è stato input in modo da poterlo presentare contestualmente in modi e luoghi diversi.Apportare modifiche qui può compromettere la presentazione successiva.

Quando vai a presentare i tuoi dati, filtra ciò che non dovrebbe esserci.Ad esempio, se non c'è motivo per cui javascript sia presente, cercalo e rimuovilo.Un modo semplice per farlo è utilizzare il file strip_tags funzione e presenta solo i tag html consentiti.

Successivamente, prendi quello che hai e passalo al pensiero htmlentities o htmlspecialchars per cambiare quello che c'è in caratteri ascii.Fallo in base al contesto e a ciò che vuoi ottenere.

Suggerirei inoltre di disattivare le virgolette magiche.È stato rimosso da PHP 6 ed è considerata una cattiva pratica utilizzarlo.Dettagli a http://us3.php.net/magic_quotes

Per maggiori dettagli controlla http://ha.ckers.org/xss.html

Questa non è una risposta completa ma, si spera, è sufficiente per aiutarti a iniziare.

rikh scrive:

Faccio del mio meglio per chiamare sempre htmlentities() per tutto ciò che sto emettendo derivato dall'input dell'utente.

Vedi il saggio di Joel su Far sembrare il codice sbagliato per aiuto con questo

mi affido a PHPTAL per quello.

A differenza di Smarty e del semplice PHP, per impostazione predefinita sfugge a tutto l'output.Questa è una grande vittoria per la sicurezza, perché il tuo sito non diventerà vulnerabile se lo dimentichi htmlspecialchars() O |escape in qualche luogo.

XSS è un attacco specifico dell'HTML, quindi l'output HTML è il posto giusto per prevenirlo.Non dovresti provare a prefiltrare i dati nel database, perché potresti dover inviare i dati su un altro supporto che non accetta HTML, ma presenta i suoi rischi.

Libreria di modelli. O almeno, questo è ciò che dovrebbero fare le librerie di modelli.Per prevenire XSS Tutto l'output dovrebbe essere codificato.Questo non è compito dell'applicazione/logica di controllo principale, dovrebbe essere gestito esclusivamente dai metodi di output.

Se cospargi htmlentities() in tutto il codice, il design complessivo è sbagliato.E come suggerisci, potresti perdere uno o due punti.Ecco perché l'unica soluzione è una rigorosa codifica HTML -> quando le variabili di output vengono scritte in un flusso html/xml.

Sfortunatamente, la maggior parte delle librerie di template php aggiungono solo la propria sintassi del template, ma non si preoccupano della codifica dell'output, della localizzazione, della validazione html o di qualsiasi cosa importante.Forse qualcun altro conosce una libreria di modelli adeguata per php?

Per la maggior parte dei siti è sufficiente sfuggire a tutti gli input dell'utente.Assicurati inoltre che gli ID di sessione non finiscano nell'URL in modo che non possano essere rubati dal file Referer collegamento ad un altro sito.Inoltre, se consenti ai tuoi utenti di inviare collegamenti, assicurati di no javascript: sono consentiti collegamenti di protocollo;questi eseguirebbero uno script non appena l'utente fa clic sul collegamento.

Se sei preoccupato per gli attacchi XSS, la soluzione è codificare le stringhe di output in HTML.Se ti ricordi di codificare ogni singolo carattere di output nel formato HTML, non c'è modo di eseguire un attacco XSS con successo.

Per saperne di più:Sanificazione dei dati utente:Come e dove farlo

Personalmente, disabiliterei magic_quotes.In PHP5+ è disabilitato per impostazione predefinita ed è meglio codificarlo come se non ci fosse affatto perché non sfugge a tutto e verrà rimosso da PHP6.

Successivamente, a seconda del tipo di dati utente che stai filtrando, determinerai cosa fare dopo, ad es.se è solo testo, ad es.un nome, quindi strip_tags(trim(stripslashes())); oppure per verificare gli intervalli utilizzare le espressioni regolari.

Se prevedi un determinato intervallo di valori, crea una matrice di valori validi e consenti solo tali valori attraverso (in_array($userData, array(...))).

Se stai controllando i numeri, usa is_numeric per imporre numeri interi o convertirli in un tipo specifico, ciò dovrebbe impedire alle persone di tentare di inviare stringhe.

Se hai PHP5.2+, considera di dare un'occhiata filtro() e facendo uso di quell'estensione che può filtrare vari tipi di dati inclusi gli indirizzi email.La documentazione non è particolarmente buona, ma sta migliorando.

Se devi gestire l'HTML, dovresti considerare qualcosa del genere Filtro di input PHP O Purificatore HTML.HTML Purifier convaliderà anche la conformità dell'HTML.Non sono sicuro che Input Filter sia ancora in fase di sviluppo.Entrambi ti permetteranno di definire una serie di tag che possono essere utilizzati e quali attributi sono consentiti.

Qualunque cosa tu decida, ricorda sempre, non fidarti mai di nulla che arrivi nel tuo script PHP da un utente (incluso te stesso!).

Tutte queste risposte sono ottime, ma fondamentalmente la soluzione a XSS sarà quella di smettere di generare documenti HTML mediante la manipolazione delle stringhe.

Filtrare l'input è sempre una buona idea per qualsiasi applicazione.

L'escape del tuo output utilizzando htmlentities() e amici dovrebbe funzionare purché venga utilizzato correttamente, ma questo è l'equivalente HTML della creazione di una query SQL concatenando stringhe con mysql_real_escape_string($var) - dovrebbe funzionare, ma meno cose possono convalidare il tuo lavoro , per così dire, rispetto a un approccio come l'utilizzo di query parametrizzate.

La soluzione a lungo termine dovrebbe essere che le applicazioni costruiscano la pagina internamente, magari utilizzando un'interfaccia standard come DOM, e quindi utilizzino una libreria (come libxml) per gestire la serializzazione su XHTML/HTML/ecc.Naturalmente, siamo molto lontani dal fatto che diventi popolare e abbastanza veloce, ma nel frattempo dobbiamo costruire i nostri documenti HTML tramite operazioni su stringhe, e questo è intrinsecamente più rischioso.

Trovo che l'utilizzo di questa funzione aiuti a eliminare molti possibili attacchi xss:http://www.codebelay.com/killxss.phps

Le "virgolette magiche" sono un rimedio palliativo per alcuni dei peggiori difetti XSS che funziona eludendo tutto in input, qualcosa che è sbagliato in base alla progettazione.L'unico caso in cui si vorrebbe usarlo è quando è assolutamente necessario utilizzare un'applicazione PHP esistente nota per essere scritta con noncuranza per quanto riguarda XSS.(In questo caso sei in guai seri anche con le “virgolette magiche”.) Quando sviluppi la tua applicazione, dovresti disabilitare le “virgolette magiche” e seguire invece pratiche sicure per XSS.

XSS, una vulnerabilità di cross-site scripting, si verifica quando un'applicazione include stringhe da fonti esterne (input dell'utente, recuperate da altri siti Web, ecc.) nel suo output [X]HTML, CSS, ECMAscript o altro output analizzato dal browser senza l'escape corretto, sperando che i caratteri speciali come il minore di (in [X]HTML), le virgolette singole o doppie (ECMAscript) non verranno mai visualizzati.La soluzione corretta è sempre l'escape delle stringhe secondo le regole del linguaggio di output:utilizzando entità in [X]HTML, barre rovesciate in ECMAscript ecc.

Poiché può essere difficile tenere traccia di ciò che non è attendibile e di cui è necessario eseguire l'escape, è una buona idea eseguire sempre l'escape di tutto ciò che è una "stringa di testo" anziché un "testo con markup" in un linguaggio come HTML.Alcuni ambienti di programmazione semplificano il compito introducendo diversi tipi di stringhe incompatibili:“stringa” (testo normale), “stringa HTML” (markup HTML) e così via.In questo modo, una conversione implicita diretta da "stringa" a "stringa HTML" sarebbe impossibile e l'unico modo in cui una stringa potrebbe diventare markup HTML è facendola passare attraverso una funzione di escape.

“Register globals”, anche se disabilitarlo è sicuramente una buona idea, affronta un problema completamente diverso da XSS.

Crea tutti i cookie di sessione (o tutti i cookie) che utilizzi HttpOnly.In questo caso, la maggior parte dei browser nasconderà il valore del cookie da JavaScript.L'utente può comunque copiare manualmente i cookie, ma ciò aiuta a impedire l'accesso diretto allo script.StackOverflow ha riscontrato questo problema durante la beta.

Questa non è una soluzione, solo un altro mattone nel muro

  • Non fidarti dell'input dell'utente
  • Escape tutto l'output di testo libero
  • Non usare magic_quotes;vedere se esiste una variante specifica per DBMS o utilizzare PDO
  • Considera l'utilizzo di cookie solo HTTP, ove possibile, per evitare che eventuali script dannosi possano dirottare una sessione

Dovresti almeno convalidare tutti i dati inseriti nel database.E prova a convalidare anche tutti i dati che lasciano il database.

mysql_real_escape_string è utile per prevenire l'SQL injection, ma XSS è più complicato.Dovresti preg_match, stip_tags o htmlentities ove possibile!

Il miglior metodo attuale per prevenire XSS in un'applicazione PHP è HTML Purifier (http://htmlpurifier.org/).Uno svantaggio minore è che si tratta di una libreria piuttosto grande e viene utilizzata al meglio con una cache del codice operativo come APC.Lo utilizzeresti in qualsiasi luogo in cui sullo schermo vengono visualizzati contenuti non attendibili.È molto più completo che htmlentities, htmlspecialchars, filter_input, filter_var, strip_tags, ecc.

Utilizzare una libreria di sanificazione esistente tramite input dell'utente per pulire Tutto input dell'utente.A meno che tu non metta a quantità di impegno, implementarlo tu stesso non funzionerà mai altrettanto bene.

Trovo che il modo migliore sia utilizzare una classe che ti consenta di associare il tuo codice in modo da non doverti mai preoccupare di eseguire l'escape manuale dei tuoi dati.

È difficile implementare una prevenzione approfondita dell'iniezione sql/xss su un sito che non causi falsi allarmi.In un CMS l'utente finale potrebbe voler utilizzare <script> O <object> che collega a elementi di un altro sito.

Consiglio a tutti gli utenti di installare FireFox con NoScript ;-)

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