Ejemplo n.º 1
0
 /**
  * 
  * check xss or auto fixed
  * @param string $value
  * @param string $type
  * @param object $instance
  */
 public function xss($token, $type, $instance = null)
 {
     if ($token === true) {
         $value = Fl_Static::fixPregReplaceQuote(trim($instance));
         $type = Fl_Static::fixPregReplaceQuote($type);
         if (!$this->checkHasOutput($type, $this->xssTmp['instance']) || $this->isSafeVar($value)) {
             return $type;
         }
         $escapeType = $this->getXssType($value);
         $escapeLevels = $this->xssTmp['instance']->escapeLevel;
         $level = $escapeLevels[$escapeType];
         foreach ($escapeLevels as $name => $l) {
             if ($l > $level) {
                 $typeModifier = $this->xssTmp['instance']->options[$name];
                 if (strpos($value, $typeModifier) !== false) {
                     return $type;
                 }
             }
         }
         $typeModifier = $this->xssTmp['instance']->options[$escapeType];
         if (strpos($value, $typeModifier) === 0) {
             return $type;
         }
         $token = $this->xssTmp['token'];
         $message = '`' . $type . '` must be use ' . $typeModifier . ' to escape at line:' . $token['line'] . ', col:' . $token['col'];
         $this->xssTmp['log'][] = $message;
         if ($value[0] === '{') {
             return $this->xssTmp['instance']->ld . '{' . $typeModifier . '(' . substr($value, 1) . ')' . $this->xssTmp['instance']->rd;
         }
         return $this->xssTmp['instance']->ld . $typeModifier . '(' . $value . ')' . $this->xssTmp['instance']->rd;
     } else {
         $this->xssTmp = array("token" => $token, "type" => $type, "instance" => $instance, 'log' => array());
         $value = $token['value'];
         $tplPattern = "/(" . preg_quote($instance->ld, "/") . "(.*?)" . preg_quote($instance->rd, "/") . ")/e";
         $value = preg_replace($tplPattern, "self::xss(true, '\\1', '\\2')", $value);
         $log = $this->xssTmp['log'];
         $this->xssTmp = array();
         return array("value" => $value, "log" => $log);
     }
 }
Ejemplo n.º 2
0
 public function xss($token, $type, $instance = null)
 {
     if ($token === true) {
         $value = Fl_Static::fixPregReplaceQuote(trim($instance));
         $type = Fl_Static::fixPregReplaceQuote($type);
         $tokens = token_get_all($type);
         $result = array();
         $tmp = array();
         $flag = false;
         foreach ($tokens as $token) {
             $tokenName = '';
             if (is_array($token)) {
                 $tokenValue = $token[1];
             } else {
                 $tokenValue = $token;
             }
             if (is_array($token)) {
                 $tokenName = $token[0];
             }
             if ($tokenValue == ';' || $tokenName == T_CLOSE_TAG) {
                 $string = trim(join(" ", $tmp));
                 if (empty($string)) {
                     $result[] = $tokenValue;
                     continue;
                 }
                 if ($this->isSafeVar($string)) {
                     return $type;
                 }
                 $escapeType = $this->getXssType($value);
                 $escapeLevels = $this->xssTmp['instance']->escapeLevel;
                 $level = $escapeLevels[$escapeType];
                 foreach ($escapeLevels as $name => $l) {
                     if ($l > $level) {
                         $typeModifier = $this->xssTmp['instance']->options[$name];
                         if (strpos($value, $typeModifier) !== false) {
                             return $type;
                         }
                     }
                 }
                 $typeModifier = $this->xssTmp['instance']->options[$escapeType];
                 if (strpos($value, $typeModifier) !== false) {
                     return $type;
                 }
                 $tmpToken = $this->xssTmp['token'];
                 $message = '`' . $type . '` must be use ' . $typeModifier . ' to escape at line:' . $tmpToken['line'] . ', col:' . $token['col'];
                 $this->xssTmp['log'][] = $message;
                 $string = $typeModifier . '(' . $string . ')';
                 $result[] = $string;
                 $result[] = $tokenValue;
                 $tmp = array();
                 $flag = false;
                 continue;
             }
             if ($tokenName == T_ECHO) {
                 $result[] = $tokenValue;
                 $flag = true;
                 continue;
             }
             if ($flag) {
                 $tmp[] = $tokenValue;
             } else {
                 $result[] = $tokenValue;
             }
         }
         return join(" ", $result);
     } else {
         $this->xssTmp = array("token" => $token, "type" => $type, "instance" => $instance, 'log' => array());
         $value = $token['value'];
         $tplPattern = "/(" . preg_quote($instance->ld, "/") . "(.*?)" . preg_quote($instance->rd, "/") . ")/ise";
         $value = preg_replace($tplPattern, "self::xss(true, '\\1', '\\2')", $value);
         $log = $this->xssTmp['log'];
         $this->xssTmp = array();
         return array("value" => $value, "log" => $log);
     }
 }
Ejemplo n.º 3
0
 /**
  * 
  * 替换图片地址
  * @param string $url
  */
 public function replaceImg($url, $quote = '')
 {
     $quote = stripslashes($quote);
     $url = trim($url);
     if (strpos(strtolower($url), 'data:') === 0) {
         return 'url(' . $url . ')';
     }
     $url = Fl_Static::getFixedUrl($url, $this->url);
     if (empty($url)) {
         return '';
     }
     return 'url(' . $quote . $url . $quote . ')';
 }
Ejemplo n.º 4
0
 /**
  * 
  * 过滤开始标签
  * @param array $token
  */
 public function filterTag($token, $notCheckECss = false)
 {
     $value = $token['value'];
     if (!empty($value)) {
         $instance = $this->getInstance('Fl_Html_TagToken', $value);
         $result = $instance->run();
     } else {
         $result = $token;
     }
     $tag = strtolower($result['tag']);
     //外链的css
     if (!$notCheckECss && $this->isExternalCss($result)) {
         return $this->filterExternalCss($result);
     }
     if ($this->options['use_blank_tag_filter']) {
         if (!in_array($tag, $this->blankTagList)) {
             return false;
         }
     }
     $attrs = $result['attrs'];
     $attrResult = array();
     foreach ($attrs as $item) {
         $name = strtolower($item[0]);
         //过滤事件
         if ($this->options['remove_tag_event']) {
             if (strpos($name, 'on') === 0) {
                 continue;
             }
         }
         //标签属性白名单
         if ($this->options['use_blank_tag_property_filter']) {
             if (!in_array($name, $this->blankTagPropertyList)) {
                 //标签的特殊属性过滤
                 if ($this->options['use_special_tag_filter']) {
                     if (isset($this->allowSpecialTagProperty[$tag])) {
                         $propList = $this->allowSpecialTagProperty[$tag];
                         if (isset($propList[$name])) {
                             $value = $propList[$name];
                             $values = Fl_Html_Static::getUnquoteText($item[2]);
                             //正则
                             if (substr($value, 0, 1) === '/') {
                                 if (preg_match($value, $values['text'])) {
                                     $attrResult[] = $item;
                                 }
                             } else {
                                 if ($value === $values['text']) {
                                     $attrResult[] = $item;
                                 }
                             }
                         }
                     }
                 }
                 continue;
             }
         }
         //a链接修复和过滤
         if ($tag == 'a' && $this->options['filter_a_href_value'] && $name == 'href') {
             if (count($item) == 3 && $item[1] == '=') {
                 $values = Fl_Html_Static::getUnquoteText($item[2]);
                 $url = Fl_Static::getFixedUrl($values['text'], $this->url);
                 if ($this->options['url_max_length']) {
                     $url = substr($url, 0, $this->options['url_max_length']);
                 }
                 $item[2] = $values['quote'] . $url . $values['quote'];
             } else {
                 continue;
             }
         }
         //图片连接的修复和过滤
         if ($tag == 'img' && $this->options['filter_img_src_value'] && $name == 'src') {
             if (count($item) == 3 && $item[1] == '=') {
                 $values = Fl_Html_Static::getUnquoteText($item[2]);
                 $url = Fl_Static::getFixedUrl($values['text'], $this->url);
                 if ($this->options['url_max_length']) {
                     $url = substr($url, 0, $this->options['url_max_length']);
                 }
                 $item[2] = $values['quote'] . $url . $values['quote'];
             } else {
                 continue;
             }
         }
         //style value
         if ($this->options['filter_tag_style_value'] && $name == 'style') {
             if (count($item) == 3 && $item[1] == '=') {
                 $values = Fl_Html_Static::getUnquoteText($item[2]);
                 $text = 'a{' . $values['text'] . '}';
                 $instance = $this->getInstance("Fl_Css_Filter", $text);
                 $instance->url = $this->url;
                 $instance->getResourceContentFn = $this->getResourceContentFn;
                 $text = $instance->run($this->options);
                 $item[2] = $values['quote'] . substr($text, 2, strlen($text) - 3) . $values['quote'];
             } else {
                 continue;
             }
         }
         $attrResult[] = $item;
     }
     $attrsJoin = array();
     foreach ($attrResult as $item) {
         $attrsJoin[] = join("", $item);
     }
     if (empty($attrsJoin)) {
         return '<' . $tag . '>';
     }
     return '<' . $tag . ' ' . join(" ", $attrsJoin) . ">";
 }