商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > ThinkPHP如何禁用不必要的函数_PHP危险函数安全加固

ThinkPHP如何禁用不必要的函数_PHP危险函数安全加固

  发布于2026-07-09 阅读(0)

扫一扫,手机访问

你可能觉得 `disable_functions` 是个万能防护,禁掉 `exec`、`system` 这类高危函数就安全了。但现实是,ThinkPHP 压根不依赖这些函数运行,而攻击者真正利用的反倒是反序列化、模板渲染、路由解析这些路径——它们完全绕开了函数级限制。真正的风险从来不是“用了什么函数”,而是“谁控制了那个函数的参数”。

ThinkPHP如何禁用不必要的函数_PHP危险函数安全加固

为什么 disable_functions 对 ThinkPHP 几乎无效

先说结论:ThinkPHP 本身就是靠框架内部机制运行的,跟 `exec`、`system`、`shell_exec` 这些命令执行函数没什么关系。你把它禁了,框架照样跑得欢,但攻击者根本不会走这条路——他们更擅长从反序列化入手,或者通过模板渲染、路由解析这些内部通道来绕过。所以问题的焦点不在“函数是否被禁用”,而在“函数参数是不是用户可控的”。

  • disable_functions 只拦截 PHP 内置函数调用,对 eval()assert()(PHP 7.2+ 默认可用)和动态类加载完全无效
  • ThinkPHP 5.1+ 默认开了模板编译缓存,如果攻击者能往 runtime/view/ 目录写东西,那就能直接植入恶意 PHP 代码——函数禁用根本拦不住
  • 有个常见翻车操作:在 php.ini 里禁用 file_put_contents,结果 ThinkPHP 的日志写不了、缓存生成失败,反而把错误路径暴露给攻击者

ThinkPHP 模板层才是高危入口,不是 system()

很多人的第一反应是防 `system()`,但 ThinkPHP 真正的风险藏在模板层。`think\template\driver\File` 和 `{:function()}` 语法允许在模板里直接执行任意 PHP 表达式。一旦模板内容被用户间接影响——比如用户提交的页面标题、富文本字段没过滤就塞进模板——那 `eval` 就会在后台无声无息地触发。

  • 危险写法示例:{:system('id')}{:call_user_func('phpinfo')} —— 只要模板被用户间接影响,这些都可能被执行
  • ThinkPHP 6.x 默认把模板引擎的 tpl_deny_func 配置关了,你得手动在 config/template.php 里显式加上:'tpl_deny_func' => ['exec','shell_exec','system','passthru','popen','proc_open']
  • 更稳妥的做法是直接禁用模板里的函数调用语法:把 'tpl_begin' => '{' 改成非 PHP 兼容符号(比如 'tpl_begin' => '{@'),同时确保所有模板变量都经过 htmlspecialchars 输出

Runtime 目录权限比禁用函数更重要

ThinkPHP 的 runtime/ 是缓存、日志、模板编译的落盘位置。如果 Web 进程(比如 www-data)对这个目录有写+执行权限,那攻击者上传一句话木马后,只要触发一次模板编译,恶意代码就能直接落地成可访问的 PHP 文件。

  • 典型自杀式配置:chmod -R 777 runtime/ —— 这等于直接给攻击者递钥匙
  • 正确权限(Linux):chown -R www-data:www-data runtime/ && chmod -R 755 runtime/ && find runtime/ -type f -exec chmod 644 {} \;
  • 额外加固:在 Nginx/Apache 配置里禁止直接访问 runtime/ 下的 PHP 文件,比如 Nginx 加上 location ~ ^/runtime/.*\.php$ { return 403; }

别碰 assert()call_user_func_array() 的参数

  • 检查项目中所有 assert( 调用,确保参数是硬编码字符串或经过白名单校验的常量——绝不能是 $_GET['x'] 或数据库读取的字段
  • 排查 think\Container::invokeMethodthink\facade\Route::miss 等调用链,确认回调方法名是否被用户控制(比如 URL 里传 ?callback=system
  • PHP 8.1+ 已经废弃了 assert() 的字符串执行模式,升级 PHP 版本是最省事的加固方式之一

真正卡住攻击链的地方,从来不是“哪个函数被禁了”,而是“哪个变量没过滤”和“哪个目录多给了执行权”。ThinkPHP 的安全水平,取决于你对输入边界的把控,而不是 php.ini 里那一行 disable_functions

本文转载于:https://www.php.cn/faq/2407336.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注