更新示例把请求字段名直接拼入 SQL,可造成 SQL 注入或越权修改列
原文依据:2 处控制器把整个请求体作为 updates 传递,而仓储层用 Object.keys(updates) 生成 SQL 标识符。只有字段值使用了参数占位符;攻击者控制的字段名仍被直接插入查询。TypeScript DTO 不会在运行时过滤 HTTP JSON。
若更新端点可被攻击者调用,构造的字段名可能改写角色、权限或其他未授权列,也可能改变查询结构或使查询持续失败。操作会以应用数据库账户的权限执行。
这是文档中的可复制示例,不会因读取 Skill 自动执行;但若用户采用该更新流程,请求体会直接成为 updates,而运行时没有展示字段白名单。仓储层只参数化值,却把 Object.keys(updates) 直接拼成 SQL 列名。恶意字段名可能改变 SQL 结构,普通额外字段也可能造成越权列更新。用户可要求作者加入运行时 schema 严格模式及固定的“允许更新列”映射。
async updateUser(req: Request, res: Response, next: NextFunction) { try { const { id } = req.params; const updates: UpdateUserDTO = req.body; const user = await this.userService.updateUser(id, updates); res.json(user); } catch (error) {查看另外 1 个位置
async update(id: string, updates: UpdateUserDTO): Promise<UserEntity | null> { const fields = Object.keys(updates); const values = Object.values(updates); const setClause = fields .map((field, idx) => `${field} = $${idx + 2}`) .join(", "); const query = ` UPDATE users SET ${setClause}, updated_at = CURRENT_TIMESTAMP WHERE id = $1 RETURNING * `; const { rows } = await this.db.query(query, [id, ...values]); return rows[0] || null;