直接修改源码临时修复yii 2.0.40漏洞,仅限紧急止血:禁用高危反序列化入口、加固batchqueryresult的__wakeup、重置并统一cookievalidationkey三处配置。

直接修改源码临时修复 Yii 2.0.40 框架漏洞,仅适用于紧急止血、无法立即升级且确认漏洞已复现的场景。需明确:这不是长期方案,而是为争取修复窗口期采取的最小侵入式补丁。重点针对两个高发风险点——反序列化入口和 Cookie 密钥泄露利用链。
禁用高危反序列化触发点(CVE-2020-15148 衍生防护)
Yii 2.0.40 虽已高于 2.0.38(官方修复版),但若项目中存在自定义 unserialize() 调用点(如日志回放、缓存反解、旧接口兼容逻辑),仍可能被绕过。此时可在关键入口加白名单拦截:
- 打开你项目中实际调用
unserialize()的文件(常见于/controllers/下某Action或/components/工具类) - 在
unserialize($data)前插入校验逻辑:
if (!is_string($data) || strlen($data) > 10240 || !preg_match('/^[aO]:/', $data)) {
throw new BadRequestHttpException('Invalid serialized data');
}
// 再执行 unserialize($data)
- 同时检查所有
base64_decode()+unserialize()组合,确保$data来源绝对可信(如仅来自内部加密 token,而非$_GET['aaa']这类直传参数)
强制重写 BatchQueryResult 的反序列化行为(防御链加固)
即使官方在 2.0.38 修复了 BatchQueryResult::__wakeup(),部分定制化部署可能因 autoload 或 vendor 覆盖导致补丁未生效。可手动补强:
- 编辑文件:
vendor/yiisoft/yii2/db/BatchQueryResult.php - 在类开头添加(或确认已有):
public function __wakeup()
{
throw new \BadMethodCallException('Unserialization is disabled for security');
}
- 若该文件被 Composer 锁定不可改,可在应用启动前(如
web/index.php顶部)注入运行时补丁:
if (class_exists('yii\db\BatchQueryResult')) {
$r = new \ReflectionClass('yii\db\BatchQueryResult');
if (!$r->hasMethod('__wakeup')) {
eval('namespace yii\db; class BatchQueryResult { public function __wakeup() { throw new \BadMethodCallException("Blocked"); } }');
}
}
⚠️ 注意:
eval方式仅限调试环境临时使用,生产环境必须通过文件补丁或升级解决。
阻断 CookieValidationKey 泄露后的伪造利用
密钥一旦泄露(如 config 备份外泄),攻击者可伪造任意合法 Cookie 触发反序列化。临时缓解手段是让已泄露密钥立即失效:
- 修改
config/web.php中的cookieValidationKey为全新随机字符串(32+ 字符,含大小写字母与数字) -
同时在
web/index.php顶部强制覆盖:
defined('YII_COOKIE_VALIDATION_KEY') or define('YII_COOKIE_VALIDATION_KEY', '全新长随机串');
- 并在
components→request配置中显式指定:
'request' => [
'cookieValidationKey' => '同样全新长随机串',
],
三处一致,确保无遗漏路径绕过。
不复杂但容易忽略。











