2009-11-09 9 views
5

Ho un campo di testo del modulo che accetta un url. Quando il modulo viene inviato, inserisco questo campo nel database con un'iniezione anti-sql appropriata. La mia domanda però riguarda xss.input is URL, come proteggerlo da xss

Questo campo di immissione è un URL e ho bisogno di visualizzarlo di nuovo sulla pagina. Come posso proteggerlo da xss durante il percorso nel database (penso che non sia necessario nulla visto che mi sono già occupato di sql injection) e nel modo in cui lo del database?

Facciamo finta di averlo così, lo sto semplificando, e per favore non preoccuparti di SQL injection. Dove vado da qui dopo?

$url = $_POST['url']; 

Grazie

+1

Assicurarsi di utilizzare istruzioni preparate per evitare l'iniezione SQL. http://php.net/manual/en/pdo.prepared-statements.php –

risposta

9

Supponendo che questo sta per essere messo in contenuto HTML (come ad esempio tra <body> e </body> o tra <div> e </div>), è necessario codificare i 5 caratteri XML speciali (&, <, >," '), e OWASP raccomanda di includere barra (/) e il comando incorporato PHP, htmlentities() farà la prima parte per voi, e un semplice str_replace() può fare la barra:.

function makeHTMLSafe($string) { 
    $string = htmlentities($string, ENT_QUOTES, 'UTF-8'); 
    $string = str_replace('/', '&#x2F;', $string); 
    return $string; 
} 

Se, tuttavia, inserirai il valore contaminato in un attributo HTML, come la clausola href= di un <a, dovrai codificare un diverso set di caratteri ([spazio]% * + , - /; < =>^e |) -e è necessario fare doppio citazione attributi vostro HTML:

function makeHTMLAttributeSafe($string) { 
    $scaryCharacters = array(32, 37, 42, 43, 44, 45, 47, 59, 60, 61, 62, 94, 124); 
    $translationTable = array(); 
    foreach ($scaryCharacters as $num) { 
     $hex = str_pad(dechex($num), 2, '0', STR_PAD_LEFT); 
     $translationTable[chr($num)] = '&#x' . $hex . ';'; 
    } 

    $string = strtr($string, $translationTable); 
    return $string; 
} 

La preoccupazione finale è illegale caratteri UTF-8, quando consegnato alcuni browser, un UTF-8 sequenza di byte mal formati può uscire da un'entità HTML. Per proteggersi da questo, è sufficiente assicurarsi che tutti i caratteri UTF-8 che si ottengono sono validi:

function assertValidUTF8($string) { 
    if (strlen($string) AND !preg_match('/^.{1}/us', $string)) { 
     die; 
    } 

    return $string; 
} 

La u modificatore su quella espressione regolare lo rende un Unicode corrispondenza regex. Accoppiando un singolo chararchter, ., siamo certi che l'intera stringa è Unicode valida.

Poiché questo è tutto dipendente dal contesto, è meglio eseguire una qualsiasi codifica all'ultimo momento possibile, appena prima di presentare l'output all'utente. Essere in questa pratica facilita anche la visione di tutti i posti che hai perso.

OWASP fornisce una grande quantità di informazioni sul loro XSS prevention cheat sheet.

+0

Non ho mai sentito parlare di alcuna precauzione speciale da adottare con attributi html, elementi di testo contra. Avete qualche riferimento/spiegazione per questo? – troelskn

+2

Ah .. Per rispondere alla mia domanda, OWASP consiglia questo perché è necessario * se gli attributi non sono quotati *. Suggerirei invece di citare gli attributi. – troelskn

+0

Come per i caratteri di codifica da includere negli attributi HTML, OWASP dice (enfasi mia) "Gli attributi non quotati possono essere scomposti con molti caratteri, ** incluso ** [spazio]% * +, - /; < = >^e |." . Quindi basta codificare questi non dovrebbe essere sufficiente, giusto? – Lode

1

Prima di visualizzare un utente, è necessario codificarlo con htmlspecialchars. Di solito questo è sufficiente quando si gestiscono dati al di fuori dello <script> tag e/o attributi di tag HTML.

1

Non rollate la vostra protezione XSS, ci sono troppi modi in cui qualcosa potrebbe scivolare via (non riesco più a trovare il collegamento a una certa demopage XSS, ma la quantità di possibilità è sbalorditiva: Broken IMG- tag, attributi bizzarri ecc.).

Utilizzare una libreria esistente come sseq-lib o estrarne uno da un framework stabilito.

Aggiornamento: Ecco the XSS-demopage.