PHP|Thinkphp最新版本漏洞分析( 三 )


       
       foreach ($this->hidden as $key => $val) {
           if (is_string($val)) {
               if (strpos($val '.')) {
                   [$relation $name
        = explode('.' $val);
                   $this->hidden[$relation
[
= $name;
                else {
                   $this->hidden[$val
= true;
               
               unset($this->hidden[$key
);
           
       

       // 合并关联数据
       $data = https://mparticle.uc.cn/api/array_merge($this->data $this->relation);

       foreach ($data as $key => $val) {
           if ($val instanceof Model || $val instanceof ModelCollection) {
               // 关联模型对象
               if (isset($this->visible[$key
) && is_array($this->visible[$key
)) {
                   $val->visible($this->visible[$key
);
                elseif (isset($this->hidden[$key
) && is_array($this->hidden[$key
)) {
                   $val->hidden($this->hidden[$key
);
               
               // 关联模型对象
               if (!isset($this->hidden[$key
) || true !== $this->hidden[$key
) {
                   $item[$key
= $val->toArray();
               
            elseif (isset($this->visible[$key
)) {
               $item[$key
= $this->getAttr($key);
            elseif (!isset($this->hidden[$key
) && !$hasVisible) {
               $item[$key
= $this->getAttr($key);

跟进getAttr方法 , 漏洞方法是getValue , 但传入getValue方法中的$value是由getData方法得到的 。

public function getAttr(string $name)
   {
       try {
           $relation = false;
           $value    = $this->getData($name);
        catch (InvalidArgumentException $e) {
           $relation = $this->isRelationAttr($name);
           $value    = null;
       

       return $this->getValue($name $value $relation);

跟进getData方法 , $this->data可控 , $fieldName来自getRealFieldName方法 。

跟进getRealFieldName方法 , 默认直接返回传入的参数 。 所以$fieldName也可控 , 也就是传入getValue$value参数可控 。


跟进getValue方法 , 在Thinkphp6.0.8触发的漏洞点在①处 , 但在Thinkphp6.0.12时已经对传入的$closure