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

Server dedicato

Condividi questo post


Commenti