CodeIgniter: rimuovere il tag iframe dal filtro xss

ATTENZIONE! Il post ha più di 2 anni e le informazioni contenute potrebbero essere obsolete (ad esempio a causa di un aggiornamento di versione rispetto agli elementi descritti o links modificati da siti esterni).

CodeIgniter integra un filtro per la protezione di attacchi xss (http://it.wikipedia.org/wiki/Cross-site_scripting). Questa funzione è attivabile manualmente in fase di validazione dei form oppure è possibile attivarla per l'intero sistema impostando nel file di configurazione:

$config['global_xss_filtering'] = TRUE;

In questo modo, oltre ad altri controlli, vengono disabilitati una serie di tags potenzialmente dannosi:

$naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|isindex|layer|link|meta|object|plaintext|style|script|textarea|title|video|xml|xss';

Per abilitare il tag iframe ci sono 3 soluzioni: 1) Il modo più veloce (e meno sicuro) per abilitare il tag iframe sarebbe modificare la stringa dei tags nel file Security.php (all'interno della cartella core di CodeIgniter) rimuovendo il testo "|iframe". 2) Se non si vuole modificare il file originale è possibile estendere la classe riscrivendo la funzione xss_clean con la variabile $naughty modificata. 3) Per mantenere un buon livello di sicurezza è poi possibile estendere la classe Security modificando la funzione clean_xss in modo meno drastico (questo è il metodo consigliato), controllando l'url degli iframe in modo da abilitare solo quelli desiderati (ad esempio per youtube, vimeo o altri portali sicuri) rimuovendo tutti quelli potenzialmente dannosi. Nella funzione si sostituisce:

 $str = preg_replace_callback('#<(/*\s*)(' . $naughty . ')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str); 

Con questo codice:

// START MOD - ALLOW IFRAME
// BY Emanuele Fantin
// Allow iframe tags
$re_replace = array();
if (defined('ALLOWED_IFRAME_URL_XSS'))
{
    preg_match_all('/<iframe.*src=\"(.*)\".*><\/iframe>/isU', $str, $matches, PREG_SET_ORDER);
    $allowed_url_sources = unserialize(ALLOWED_IFRAME_URL_XSS);
    // if there are iframes in string
    if (!empty($matches))
    {
        foreach ($matches as $k => $iframe)
        {
            $iframe_code = $iframe[0];
            $iframe_url = trim(strtolower($iframe[1]));
 
            foreach ($allowed_url_sources as $allowed_url)
            {
                //check if the iframe url is allowed
                if (strncmp($iframe_url, $allowed_url, strlen($allowed_url)) == 0)
                {
                    //create a temporary placeholder
                    $tmp_placeholder = '##' . time() . '_' . rand() . '##';
                    $str = str_replace($iframe_code, $tmp_placeholder, $str);
                    //add an item for reverse replace (used later)
                    $re_replace[] = array(
                         'placeholder' => $tmp_placeholder,
                         'original_tag' => $iframe_code
                    );
                }
            }
        }
    }
}
 
$str = preg_replace_callback('#<(/*\s*)(' . $naughty . ')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str);
 
//reverse replace of each placeholder
foreach ($re_replace as $item)
{
    $str = str_replace($item['placeholder'], $item['original_tag'], $str);
}
//END MOD

Il codice funziona in questo modo:

 

  1. controlla se nella stringa ci sono tags di tipo iframe
  2. se l'url dell'iframe è tra quelli permessi (definiti in una costante globale) sostituisce ogni tag iframe e il suo contenuto con una stringa temporanea (placeholder) prima che venga richiamata la funzione_sanitize_naughty_html()
  3. dopo la pulizia della stringa da parte di codeigniter i placeholder vengono sostituiti con il codice iframe originale che in questo modo non viene modificato

Nella costante globale si definiscono gli url in questo modo:

 define('ALLOWED_IFRAME_URL_XSS', serialize(array( 'http://player.vimeo.com', 'https://player.vimeo.com', '//www.youtube.com',//youtube utilizza anche questa notazione senza http: 'http://www.youtube.com', 'https://www.youtube.com', ))); 

Con lo stesso metodo (tag -> placeholder temporaneo -> tag originale) si possono abilitare anche altri tipi di tag (ad esempio object o embed) scrivendo il codice apposito per gestirli in base alle proprie esigenze. Anche il controllo degli url permessi può essere migliorato utilizzando le espressioni regolari.

 

 

Downloads

Condividi questo post


Commenti