标准答案

  1. XSS 的重点是按 HTML、属性、URL、JavaScript 等输出上下文进行正确编码,必要时使用可信富文本净化器和内容安全策略,不能只依赖输入过滤。
  2. SQL 注入的重点是使用参数化查询或 ORM 参数绑定,让数据和 SQL 结构分离;表名、排序字段等不能参数化的部分必须使用白名单映射。
  3. 命令注入的重点是避免把用户输入拼接进 shell。优先调用库 API 或使用参数数组执行固定程序,并限制可执行命令、参数和值范围。
  4. 输入校验应验证类型、长度、格式、范围和业务语义,但校验不是唯一防线,因为同一数据可能在不同输出或执行上下文中被重新解释。
  5. 数据库、执行账户、文件系统和网络访问应遵循最小权限,即使发生注入也尽量限制可访问资源和横向移动能力。

题目解析

“过滤危险字符”很脆弱,因为不同上下文的转义规则不同,编码、拼接位置和解释器行为也不同。将数据交给专门 API 处理比手写黑名单可靠。

安全问题常在第二跳出现:最初安全保存的文本,后来被用于日志页面、导出 CSV、模板渲染或运维脚本时仍可能成为注入入口。

代码示例

数据库条件应作为参数传入,动态排序字段则只从服务端定义的映射中选择。

TypeScript
const sortable = { createdAt: "created_at", amount: "amount" }
const column = sortable[input.sortBy] ?? sortable.createdAt

await db.query(
  "SELECT * FROM orders WHERE user_id = ? ORDER BY " + column + " DESC",
  [currentUser.id]
)

常见误区

  • 用黑名单替代参数化查询、输出编码和执行隔离。
  • 认为后端返回 JSON 就永远不会有 XSS 风险。
  • 为了方便把用户输入直接拼进 shell、模板或管理脚本。

作者信息