Thinkphp模板开放给第三方编辑权限时,如何禁止模板使用php代码

Posted 鱼塘总裁

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Thinkphp模板开放给第三方编辑权限时,如何禁止模板使用php代码相关的知识,希望对你有一定的参考价值。

首先我要吐槽一个问题:为什么在博客园发布的文章总是被其他网站采集过去,而他们采集过去后,排名比博客园还好,比如这篇文章,我把标题复制到百度搜索,结果第一页的搜索结果全部都是采集我的,而我在博客园发布的这篇文章竟然直接没有收录,大哥们啊,搞清楚好吗,我这是原创文章。

如题,在有些项目中,我们需要把模板开放给第三方用户编辑,那么此时模板里面能使用php代码,将会是很重大的安全隐患。

那么如何禁止模板里面使用php代码呢?官方没有给出一个配置项,这是很遗憾的一件事情,没办法,那么我们只能自己修改代码禁止模板使用php了。

 

1、禁止模板使用<?php ?>标签,通过以下配置项完成

\'TMPL_DENY_PHP\'    =>    true,    //禁用原生php

 

2、禁止模板使用<php></php>标签

打开文件:ThinkPHP/Library/Think/Template/TagLib/Cx.class.php

注释大概21行的代码,意思就是注释php的解析标签,这样这个标签就会被原样输出,不会被解析:

 

3、禁止模板使用<if> 和 <elseif> 标签

由于if 标签和 elseif 标签里面可以使用函数,所以他们两个同样很危险。需要禁止

打开文件:ThinkPHP/Library/Think/Template/TagLib/Cx.class.php

注释大概24、25行代码:

 

4、禁止模板对变量使用函数,例如{:$addtime|date="Y-m-d",###}

像这样的函数用法,虽然方便,但是我们同样要禁止,否则还是存在安全隐患,因为可以把需要执行的函数写在|后面啊。

打开文件:ThinkPHP/Library/Think/Template.class.php

找到 parseVarFunction 函数,大概566行。按照我下面的图片一样注释

 

5、禁止语法 {:函数名或变量}

如{:phpinfo()}、等  在冒号后面可以写,任意变量,和任意函数,这个也很危险。同样需要屏蔽

①先自定义一个全局config \'TEMP_SAFE\' => \'1\',

\'TEMP_SAFE\' => \'1\',    //不解析{:} 与 {$Think}

②打开文件:ThinkPHP\\Library\\Think\\Template.class.php

来到大概479行,把如下代码:

if(\'$\' == $flag && \'.\' != $flag2 && \'(\' != $flag2){ //解析模板变量 格式 {$varName}
            return $this->parseVar($name);
        }elseif(\'-\' == $flag || \'+\'== $flag){ // 输出计算
            return  \'<?php echo \'.$flag.$name.\';?>\';
        }elseif(\':\' == $flag){ // 输出某个函数的结果
            return  \'<?php echo \'.$name.\';?>\';
        }elseif(\'~\' == $flag){ // 执行某个函数
            return  \'<?php \'.$name.\';?>\';
        }elseif(substr($tagStr,0,2)==\'//\' || (substr($tagStr,0,2)==\'/*\' && substr(rtrim($tagStr),-2)==\'*/\')){
            //注释标签
            return \'\';
        }

替换成:

    $safe    = C(\'TEMP_SAFE\');
            if(\'$\' == $flag && \'.\' != $flag2 && \'(\' != $flag2){ //解析模板变量 格式 {$varName}
                return $this->parseVar($name);
            }elseif(substr($tagStr,0,2)==\'//\' || (substr($tagStr,0,2)==\'/*\' && substr(rtrim($tagStr),-2)==\'*/\')){
                //注释标签
                return \'\';
            }elseif($safe !=\'1\'){
                if(\'-\' == $flag || \'+\'== $flag){ // 输出计算
                        return  \'<?php echo \'.$flag.$name.\';?>\';
                    }elseif(\':\' == $flag){ // 输出某个函数的结果
                         return  \'<?php echo \'.$name.\';?>\';
                    }elseif(\'~\' == $flag){ // 执行某个函数
                       return  \'<?php \'.$name.\';?>\';
                    }
            }

 

6、应对$Think和|函数被解析

打开文件:ThinkPHP\\Library\\Think\\Template.class.php

搜索代码:

if(\'Think.\' == substr($var,0,6)){

改成

$safe    = C(\'TEMP_SAFE\');
if(\'Think.\' == substr($var,0,6) and $safe!=\'1\'){

搜索:

if(count($varArray)>0)

改成:

if(count($varArray)>0 and $safe!=\'1\')

 

打开文件:ThinkPHP\\Library\\Think\\Template\\TagLib.class.php

搜索:

 

if(\'Think.\' == substr($name,0,6))

 

改成:

if(\'Think.\' == substr($name,0,6) and C(\'TEMP_SAFE\')!=\'1\')

完成

 

以上是关于Thinkphp模板开放给第三方编辑权限时,如何禁止模板使用php代码的主要内容,如果未能解决你的问题,请参考以下文章

thinkphp模板读取数据时怎么解析HTML代码

ThinkPHP5使用jwt进行会话验证

thinkphp5.0 编辑界面验证不合法后重定向到编辑界面时,给编辑界面重新分配数据

ThinkPHP如何给网页加公共的header文件和footer文件

UnionID和微信登陆

如何将CKeditor编辑器的上传和thinkphp结合