ThinkPHP缓存安全加固核心是防止缓存穿越,需禁用自动反序列化(如将Redis等驱动的serialize设为false)、统一改用JSON编解码、隔离runtime目录、禁用phar、过滤缓存内容并加密敏感数据。

ThinkPHP缓存安全加固,核心是防止“缓存穿越”——即攻击者绕过正常业务逻辑,直接操控缓存写入/读取过程,注入恶意序列化数据、伪造类实例、触发反序列化链,甚至写入WebShell或执行命令。这类风险在Redis、File、Memcached等驱动中尤为突出,尤其当缓存值未经校验就被unserialize()解析时。
禁用自动反序列化(最优先)
多数缓存驱动(尤其是ThinkPHP 5.x/6.x的Redis、File)默认开启serialize选项,导致get()时无条件反序列化原始值。这是缓存穿越的主入口。
- 将
config/cache.php中所有缓存驱动的'serialize' => true改为false(如Redis、Memcached) - 统一改用
json_encode()存、json_decode($val, true)取,彻底规避PHP原生序列化机制 - 若必须存对象(极少数场景),先
base64_encode(serialize($obj))存储;读取时先base64_decode(),再用unserialize($data, ['allowed_classes' => ['My\SafeClass']])白名单校验
隔离缓存目录与运行时环境
File缓存若落在Web可访问路径下(如public/runtime/cache/),攻击者可能通过URL直接下载缓存文件,分析结构或上传伪造payload。
- 确保
runtime/目录位于Web根目录之外(例如项目根为/var/www/app/,Web root设为/var/www/app/public/,而runtime放在/var/www/app/runtime/) - 在
config/app.php中显式配置'runtime_path' => '/var/www/app/runtime/' - Linux下执行:
chmod 750 /var/www/app/runtime,并确认Web服务器用户(如www-data)仅具备读写权限,无执行权限
加固Redis等外部缓存服务
Redis本身不校验数据格式,但ThinkPHP驱动若未做类型约束,就可能把任意字符串当对象反序列化。
- 禁用Phar协议:在
php.ini中设置phar.readonly = On,并确认extension=phar.so已加载 - 避免使用
eval、assert等函数处理缓存键名或值,尤其不要拼接用户输入进缓存key(如cache('user_'.$_GET['id'])) - Redis连接字符串中不硬编码密码;改用环境变量(如
REDIS_PASSWORD)注入,并在config/cache.php中用getenv('REDIS_PASSWORD')获取
启用缓存前的内容过滤
即使缓存内容来自内部生成,也要防范上游污染(如数据库字段被注入恶意序列化字符串)。
- 对所有写入缓存的值,在
set()前做基础校验:用is_string($val) && !preg_match('/^[OC]:/', $val)排除常见序列化头(O:对象、C:自定义) - 敏感业务缓存(如用户权限、菜单配置)启用AES加密:用
openssl_encrypt()封装后再存,读取后解密再解析 - 日志中记录缓存key的来源上下文(如“来自UserModel::getMenu()”),便于异常时快速溯源
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











