thomascube
2008-09-12 1c499ae930907ecb37ba31997ffcb71827d524f9
Allow (sanitized) style elements in HTML messages

2 files modified
34 ■■■■ changed files
program/include/main.inc 19 ●●●●● patch | view | raw | blame | history
program/steps/mail/func.inc 15 ●●●● patch | view | raw | blame | history
program/include/main.inc
@@ -597,7 +597,8 @@
  $last_pos = 0;
  
  // ignore the whole block if evil styles are detected
  if (stristr($source, 'expression') || stristr($source, 'behavior'))
  $stripped = preg_replace('/[^a-z\(:]/', '', rcmail_xss_entitiy_decode($source));
  if (preg_match('/expression|behavior|url\(|import/', $stripped))
    return '';
  // cut out all contents between { and }
@@ -633,6 +634,22 @@
/**
 * Decode escaped entities used by known XSS exploits.
 * See http://downloads.securityfocus.com/vulnerabilities/exploits/26800.eml for examples
 *
 * @param string CSS content to decode
 * @return string Decoded string
 */
function rcmail_xss_entitiy_decode($content)
{
  $out = html_entity_decode(html_entity_decode($content));
  $out = preg_replace('/\\\00([a-z0-9]{2})/ie', "chr(hexdec('\\1'))", $out);
  $out = preg_replace('#/\*.+\*/#Um', '', $out);
  return $out;
}
/**
 * Compose a valid attribute string for HTML tags
 *
 * @param array Named tag attributes
program/steps/mail/func.inc
@@ -602,15 +602,14 @@
      $wash_opts['html_elements'] = array('html','head','title','body');
    }
    
    /* CSS styles need to be sanitized!
    // allow CSS styles, will be sanitized by rcmail_washtml_callback()
    if ($p['safe']) {
      $wash_opts['html_elements'][] = 'style';
      $wash_opts['html_attribs'] = array('type');
    }
    */
    
    $washer = new washtml($wash_opts);
    $washer->add_callback('form', 'rcmail_washtml_callback');
    $washer->add_callback('style', 'rcmail_washtml_callback');
    $body = $washer->wash($html);
    $REMOTE_OBJECTS = $washer->extlinks;
@@ -698,6 +697,16 @@
      $out = html::div('form', $content);
      break;
      
    case 'style':
      // decode all escaped entities and reduce to ascii strings
      $stripped = preg_replace('/[^a-zA-Z\(:]/', '', rcmail_xss_entitiy_decode($source));
      // now check for evli strings like expression, behavior or url()
      if (!preg_match('/expression|behavior|url\(|import/', $css)) {
        $out = html::tag('style', array('type' => 'text/css'), $content);
        break;
      }
    default:
      $out = '';
  }