Laravel Cookie伪造漏洞分析
字数 1713 2025-08-20 18:17:47
Laravel Cookie伪造漏洞分析与防护指南
漏洞概述
Laravel框架在2020年7月27日发布安全通告,修复了一个严重的Cookie伪造漏洞(CVE-2020-15148)。该漏洞存在于Laravel的Cookie加密机制中,允许攻击者在特定条件下伪造合法Cookie,可能导致远程代码执行(RCE)。
漏洞原理分析
原始加密机制(漏洞版本)
在Laravel 7.21.0及以下版本中,Cookie加密流程存在以下问题:
-
加密过程:
$this->encrypter->encrypt($cookie->getValue(), static::serialized($cookie->getName()))- 直接对Cookie值进行加密,未与Cookie名称建立关联
- 使用
APP_KEY作为加密密钥 - 采用AES加密算法(默认配置)
-
加密实现细节:
- 生成随机IV(初始化向量)
- 使用
openssl_encrypt进行加密 - 计算MAC(消息认证码)用于验证完整性
- 最终输出格式:
base64_encode(json_encode(['iv' => ..., 'value' => ..., 'mac' => ...]))
-
核心问题:
- Cookie值与名称无绑定关系
- 攻击者可利用程序返回的加密结果构造合法Cookie
- 当Session处理器配置为Cookie时风险最高
攻击场景
-
前提条件:
- 应用程序对用户输入进行加密并返回结果
- 使用默认的
APP_KEY或已知密钥 - 最好Session处理器配置为Cookie(非默认配置)
-
攻击步骤:
- 获取合法加密的Cookie值
- 构造恶意序列化数据
- 替换原有Cookie值
- 服务器解密后反序列化执行恶意代码
-
RCE可能性:
- 当
SESSION_DRIVER=cookie时,Session数据存储在Cookie中 - 解密后会自动反序列化
- 结合POP链可实现远程代码执行
- 当
补丁分析
Laravel在7.22.4版本中完全修复了此漏洞:
修复方案
-
加密流程修改:
CookieValuePrefix::create($cookie->getName(), $this->encrypter->getKey()).$cookie->getValue()- 在Cookie值前添加基于名称和密钥生成的前缀
-
前缀生成机制:
hash_hmac('sha1', $cookieName.'v2', $key).'|'- 使用HMAC-SHA1算法
- 拼接"v2"防止数组类型名称问题
- 添加分隔符"|"
-
解密验证流程:
- 解密后检查值是否以正确前缀开头
- 验证失败则将Cookie值设为null
- 有效前缀则去除前缀部分(
substr($cookieValue, 41))
修复效果
- 强制Cookie值与名称绑定
- 攻击者无法伪造合法前缀(需要密钥)
- 即使获取加密结果也无法构造有效Cookie
影响版本
- Laravel <= 7.21.0(7.22.0开始修复,7.22.4完全修复)
- Laravel <= 6.18.26(6.18.27开始修复,6.18.31完全修复)
防护措施
1. 升级Laravel版本
立即升级到以下或更高版本:
- Laravel 7.22.4+
- Laravel 6.18.31+
2. 配置检查
确保以下配置:
APP_KEY保持机密且足够复杂- 避免使用
SESSION_DRIVER=cookie(默认是file) - 定期轮换加密密钥
3. 自定义加密验证
如需自定义加密机制,可参考修复方案:
// 加密时
$prefix = hash_hmac('sha256', $cookieName, $secretKey);
$encryptedValue = encrypt($prefix . '|' . $cookieValue);
// 解密时
$decrypted = decrypt($encryptedValue);
if (strpos($decrypted, $expectedPrefix) === 0) {
$value = substr($decrypted, strlen($expectedPrefix) + 1);
} else {
$value = null; // 无效Cookie
}
4. 安全审计
检查应用程序中:
- 所有Cookie处理逻辑
- 自定义加密/解密实现
- Session配置和存储方式
漏洞验证方法
1. 版本检测
检查composer.lock或运行:
php artisan --version
2. 加密测试
尝试加密不同名称但相同值的Cookie,观察结果:
// 漏洞版本 - 结果相同
encrypt('value', 'name1');
encrypt('value', 'name2');
// 修复版本 - 结果不同
encrypt(prefix.'value', 'name1');
encrypt(prefix.'value', 'name2');
总结
该漏洞揭示了加密机制中上下文绑定的重要性。Laravel的修复通过将Cookie名称与值关联,有效防止了伪造攻击。开发者应:
- 及时更新框架版本
- 避免非常规配置(如Cookie Session驱动)
- 实现加密时考虑完整上下文
- 定期进行安全审计
参考资源
- Laravel官方安全通告:https://blog.laravel.com/laravel-cookie-security-releases
- CVE详细信息:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-15148
- Laravel加密文档:https://laravel.com/docs/encryption