yii 2.0.54输入校验漏洞修复核心是建立分层校验+上下文感知+防御性默认机制,需覆盖路由参数、json请求体、文件上传、动态sql四层场景,强化模型规则、严控输出、强制开启csrf/cookie验证等关键配置。

Yii 2.0.54 输入校验漏洞修复的核心,不是“打补丁”,而是建立**分层校验+上下文感知+防御性默认**的机制。框架本身已提供坚实基础,关键在于是否用对、用全、用严。
一、输入校验必须覆盖四层场景
仅靠模型规则(rules())远远不够。真实漏洞常出现在它管不到的地方:
-
路由参数与查询字符串:比如
/user/view?id=123中的id,需在控制器中显式校验类型和范围:$id = (int) Yii::$app->request->get('id');
若为字符串 ID,应配合正则白名单:if (!preg_match('/^[a-zA-Z0-9_\-]{3,32}$/', $uid)) { throw new BadRequestHttpException(); } -
JSON API 请求体:不能依赖
load()自动绑定就认为安全。必须搭配validate()并检查返回值;对数组字段(如tags)要限制长度和单个元素格式。 -
文件上传元信息:
$_FILES['avatar']['name']可被伪造,禁止直接拼入路径或数据库。应始终使用$model->imageFile->baseName等框架生成的安全名称。 -
动态 SQL 子句参数:如
orderBy、groupBy、select中的字段名,必须走白名单校验:$allowedFields = ['created_at', 'status', 'price'];<br>$sort = Yii::$app->request->get('sort', 'created_at');<br>if (!in_array($sort, $allowedFields)) { $sort = 'created_at'; }
二、模型层校验要“深”且“实”
Yii 的 rules() 是第一道防线,但容易被绕过或配置不全:
- 避免只写
['username', 'required'],而应补充['username', 'string', 'min' => 3, 'max' => 32]和['username', 'match', 'pattern' => '/^[a-z0-9_]+$/i']; - 密码字段必须启用
'safe' => false(防止 mass assignment),并用password_hash或$security->generatePasswordHash()处理; - 对敏感业务规则(如“余额不能为负”、“折扣不能超 95%”),不要只在前端 JS 校验,必须在模型
beforeSave()或自定义验证方法中二次确认。
三、输出环节不能依赖“自动转义”免责
Yii 默认对 echo $var 做 HTML 转义,但这是有前提的:
- 仅适用于
Html::encode()或视图中直接= $var ?>;若用了= Html::raw($var) ?>、echo $var(未经过 helper)、或json_encode()输出到 JS 变量,就完全绕过防护; - 富文本内容必须用
HtmlPurifier组件清洗,而不是简单strip_tags()—— 后者无法防javascript:alert(1)这类编码绕过; - 生成 URL 时,用户输入的跳转地址(如
returnUrl)必须用Url::to()或白名单域名校验,禁止直接拼接header("Location: " . $_GET['r'])。
四、关键配置必须强制开启
这些开关不打开,再细的校验也可能被绕过:
-
'enableCsrfValidation' => true(默认已开,但迁移旧项目时易被注释掉); -
'cookieValidationKey'必须设为强随机字符串,不可为空或用默认值; -
'enableStrictMode' => true(2.0.54 支持),可捕获未声明变量、非法数组键等潜在逻辑漏洞; - 生产环境禁用
'debug' => false和'showScriptName' => false,防止暴露路径和调试信息。
不复杂但容易忽略。校验不是一次写完就结束的事,而是贯穿请求生命周期每个数据入口的条件反射。











