Esempio n. 1
0
/**
 * This function edits the style definition to make them friendly and
 * usable in SquirrelMail.
 *
 * @param  $message  the message object
 * @param  $id       the message id
 * @param  $content  a string with whatever is between <style> and </style>
 * @param  $mailbox  the message mailbox
 * @return           a string with edited content.
 */
function sq_fixstyle($body, $pos, $message, $id, $mailbox)
{
    global $view_unsafe_images;
    $me = 'sq_fixstyle';
    // workaround for </style> in between comments
    $iCurrentPos = $pos;
    $content = '';
    $sToken = '';
    $bSucces = false;
    $bEndTag = false;
    for ($i = $pos, $iCount = strlen($body); $i < $iCount; ++$i) {
        $char = $body[$i];
        switch ($char) {
            case '<':
                $sToken .= $char;
                break;
            case '/':
                if ($sToken == '<') {
                    $sToken .= $char;
                    $bEndTag = true;
                } else {
                    $content .= $char;
                }
                break;
            case '>':
                if ($bEndTag) {
                    $sToken .= $char;
                    if (preg_match('/\\<\\/\\s*style\\s*\\>/i', $sToken, $aMatch)) {
                        $newpos = $i + 1;
                        $bSucces = true;
                        break 2;
                    } else {
                        $content .= $sToken;
                    }
                    $bEndTag = false;
                } else {
                    $content .= $char;
                }
                break;
            case '!':
                if ($sToken == '<') {
                    // possible comment
                    if (isset($body[$i + 2]) && substr($body, $i, 3) == '!--') {
                        $i = strpos($body, '-->', $i + 3);
                        if ($i === false) {
                            // no end comment
                            $i = strlen($body);
                        }
                        $sToken = '';
                    }
                } else {
                    $content .= $char;
                }
                break;
            default:
                if ($bEndTag) {
                    $sToken .= $char;
                } else {
                    $content .= $char;
                }
                break;
        }
    }
    if ($bSucces == FALSE) {
        return array(FALSE, strlen($body));
    }
    /**
     * First look for general BODY style declaration, which would be
     * like so:
     * body {background: blah-blah}
     * and change it to .bodyclass so we can just assign it to a <div>
     */
    $content = preg_replace("|body(\\s*\\{.*?\\})|si", ".bodyclass\\1", $content);
    $secremoveimg = '../images/' . _("sec_remove_eng.png");
    // first check for 8bit sequences and disallowed control characters
    if (preg_match('/[\\16-\\37\\200-\\377]+/', $content)) {
        $content = '<!-- style block removed by html filter due to presence of 8bit characters -->';
        return array($content, $newpos);
    }
    // IE Sucks hard. We have a special function for it.
    sq_fixIE_idiocy($content);
    // remove @import line
    $content = preg_replace("/^\\s*(@import.*)\$/mi", "\n<!-- @import rules forbidden -->\n", $content);
    /**
     * Fix url('blah') declarations.
     */
    // translate ur\l and variations into url (IE parses that)
    // TODO check if the sq_fixIE_idiocy function already handles this.
    $content = preg_replace("/(\\\\)?u(\\\\)?r(\\\\)?l(\\\\)?/i", 'url', $content);
    preg_match_all("/url\\s*\\((.+)\\)/si", $content, $aMatch);
    if (count($aMatch)) {
        $aValue = $aReplace = array();
        foreach ($aMatch[1] as $sMatch) {
            // url value
            $urlvalue = $sMatch;
            sq_fix_url('style', $urlvalue, $message, $id, $mailbox, "'");
            $aValue[] = $sMatch;
            $aReplace[] = $urlvalue;
        }
        $content = str_replace($aValue, $aReplace, $content);
    }
    /**
     * Remove any backslashes, entities, and extraneous whitespace.
     */
    $contentTemp = $content;
    sq_defang($contentTemp);
    sq_unspace($contentTemp);
    /**
     * Fix stupid css declarations which lead to vulnerabilities
     * in IE.
     */
    $match = array('/\\/\\*.*\\*\\//', '/expression/i', '/behaviou*r/i', '/binding/i', '/include-source/i', '/javascript/i', '/script/i');
    $replace = array('', 'idiocy', 'idiocy', 'idiocy', 'idiocy', 'idiocy', 'idiocy');
    $contentNew = preg_replace($match, $replace, $contentTemp);
    if ($contentNew !== $contentTemp) {
        // insecure css declarations are used. From now on we don't care
        // anymore if the css is destroyed by sq_deent, sq_unspace or sq_unbackslash
        $content = $contentNew;
    }
    return array($content, $newpos);
}
Esempio n. 2
0
/**
 * This function runs various checks against the attributes.
 *
 * @param  $tagname         String with the name of the tag.
 * @param  $attary          Array with all tag attributes.
 * @param  $rm_attnames     See description for sq_sanitize
 * @param  $bad_attvals     See description for sq_sanitize
 * @param  $add_attr_to_tag See description for sq_sanitize
 * @param  $message         message object
 * @param  $id              message id
 * @return                  Array with modified attributes.
 */
function sq_fixatts($tagname, $attary, $rm_attnames, $bad_attvals, $add_attr_to_tag, $message, $id, $mailbox)
{
    $me = 'sq_fixatts';
    while (list($attname, $attvalue) = each($attary)) {
        /**
         * See if this attribute should be removed.
         */
        foreach ($rm_attnames as $matchtag => $matchattrs) {
            if (preg_match($matchtag, $tagname)) {
                foreach ($matchattrs as $matchattr) {
                    if (preg_match($matchattr, $attname)) {
                        unset($attary[$attname]);
                        continue;
                    }
                }
            }
        }
        /**
         * Remove any backslashes, entities, and extraneous whitespace.
         */
        $attvalue = sq_unbackslash($attvalue);
        $attvalue = sq_deent($attvalue);
        $attvalue = sq_unspace($attvalue);
        /**
         * Remove \r \n \t \0 " " "\\"
         */
        $attvalue = str_replace(array("\r", "\n", "\t", "", " ", "\\"), array('', '', '', '', '', ''), $attvalue);
        /**
         * Now let's run checks on the attvalues.
         * I don't expect anyone to comprehend this. If you do,
         * get in touch with me so I can drive to where you live and
         * shake your hand personally. :)
         */
        foreach ($bad_attvals as $matchtag => $matchattrs) {
            if (preg_match($matchtag, $tagname)) {
                foreach ($matchattrs as $matchattr => $valary) {
                    if (preg_match($matchattr, $attname)) {
                        /**
                         * There are two arrays in valary.
                         * First is matches.
                         * Second one is replacements
                         */
                        list($valmatch, $valrepl) = $valary;
                        $newvalue = preg_replace($valmatch, $valrepl, $attvalue);
                        if ($newvalue != $attvalue) {
                            $attary[$attname] = $newvalue;
                        }
                    }
                }
            }
        }
        /**
         * Turn cid: urls into http-friendly ones.
         */
        if (preg_match("/^[\\'\"]\\s*cid:/si", $attvalue)) {
            $attary[$attname] = sq_cid2http($message, $id, $attvalue, $mailbox);
        }
    }
    /**
     * See if we need to append any attributes to this tag.
     */
    foreach ($add_attr_to_tag as $matchtag => $addattary) {
        if (preg_match($matchtag, $tagname)) {
            $attary = array_merge($attary, $addattary);
        }
    }
    return $attary;
}