当前位置:首页 > 百科

thinkphp漏洞

ThinkPHP的漏洞漏洞,说白了,漏洞大多数时候不是漏洞框架本身有多脆弱,而是漏洞用的人太相信“官方文档”了。这话可能有点得罪人,漏洞但你看真实案例就明白了。漏洞

去年有个做电商后台的漏洞哥们儿,代码里直接用了`where('id',漏洞 input('get.id'))`。他以为框架的漏洞`input`方法已经过滤了SQL注入,结果ThinkPHP的漏洞查询构造器在拼接字符串时根本不做参数绑定。攻击者传个`id[0]=exp&id[1]=1) or 漏洞updatexml(1,concat(0x7e,user()),1)--`,数据库直接吐出版本信息。漏洞这种漏洞从5.0一直延续到5.1,漏洞官方文档里写的漏洞是“推荐使用参数绑定”,但多少人真看了?漏洞

更典型的是RCE漏洞。2018年底爆出的ThinkPHP 5.0.x远程代码执行,利用的是`Request::method()`方法里`filter[]`参数可被外部覆盖的特性。攻击者构造一个POST请求,把`filter[]`改成`system`,把`method`改成`whoami`,就能在服务器上执行任意命令。那次漏洞波及了至少几十万个站点,因为很多开发者习惯用`thinkphp`自带的`route`规则,没做任何过滤。你问为什么这么容易?因为框架的设计哲学是“灵活”,而灵活的另一面就是“默认信任用户输入”。

还有个容易忽略的坑是模板注入。ThinkPHP的模板引擎支持`{ php}`标签,虽然官方在5.1后默认禁用了,但如果你在配置里手动开启`'tpl_deny_php' => false`,那模板文件里的`{ php}phpinfo();{ /php}`就会直接执行。更隐蔽的是,有些开发者为了方便,把用户输入直接拼进模板路径,比如`$this->fetch('index_' . $_GET['style'])`,这时候攻击者用`../../../../etc/passwd`就能读取文件,用`php://filter`配合包含漏洞就能getshell。这已经不是框架的锅了,但你用ThinkPHP,就得知道它的模板解析机制不像Twig那样沙箱隔离。

说点实际的判断。ThinkPHP的漏洞修复速度其实不慢,但问题是很多中小公司用的还是老版本,5.0.x的最后一版修复补丁是2019年才出的,而5.1.x到2020年还在补安全漏洞。你要是用3.2.3,那更惨——这个版本连SQL注入的预处理都没有,全靠开发者手动转义。我见过不少外包项目,代码里全是`M('user')->where('username="' . $name . '"')`这种写法,框架自带的`I()`函数确实做了addslashes,但遇到宽字节注入就废了。

所以我的看法是:ThinkPHP的漏洞大多属于“框架给了你自由,但自由需要代价”。你要是用Laravel,Eloquent ORM强制参数绑定,你乱写SQL的机会少很多。但ThinkPHP的查询构造器允许你直接写原生字符串,这就像开车不系安全带——平时没事,出事就是大事。我建议用这个框架的团队,至少要做到:所有数据库查询必须用`where('id', ':id')`绑定参数,所有文件操作必须校验路径是否在白名单内,所有模板渲染的变量值必须经过`htmlspecialchars`过滤。做不到?那你就等着被扫描器天天问候吧。

分享到: