API 网关专栏 · 第 55 章

API 网关如何应对 SQL 注入与 XSS:检测边界与纵深防御

2026年09月09日
API 网关如何应对 SQL 注入与 XSS:检测边界与纵深防御

API 网关可以在请求到达应用前拒绝格式错误的输入、限制请求结构与大小、应用 WAF 特征规则,并发现可疑流量。但它无法修复通过字符串拼接构造的 SQL,也不能保证不可信数据在最终浏览器上下文中经过正确编码。防止 SQL 注入,需要使用参数化查询并限制数据库权限;防止跨站脚本(XSS),则要在 HTML、属性、URL、CSS 或 JavaScript 等具体输出上下文中正确编码,并在确实需要接收 HTML 时执行清理。

因此,应将网关控制视为纵深防御中由边缘统一运维的一层,而不是根因修复方案。

核心要点

  • 模式验证可以减少意外输入,但不能证明一个字符串用于 SQL 或 HTML 时是安全的。
  • WAF 规则可以阻断已知攻击载荷并为响应争取时间,但绕过方式和误报始终是必须面对的运维问题。
  • SQL 注入必须在构造查询的位置消除,主要手段是预处理语句或参数化查询。
  • XSS 必须在输出进入 HTML、属性、URL、CSS 或 JavaScript 上下文的位置处理。
  • 应把检测结果记录为安全信号,但避免不必要地保留凭证、敏感载荷或被反射的攻击字符串。

理解两条数据流

SQL 注入和 XSS 都涉及不可信数据,但危险的解释器和控制点并不相同。

1flowchart LR
2    C[客户端输入] --> G[API 网关验证与 WAF]
3    G --> A[应用]
4    A --> Q[参数化数据库查询]
5    Q --> D[(数据库)]
6    D --> A
7    A --> E[按上下文编码或清理]
8    E --> B[浏览器渲染上下文]

对于 SQL 注入,漏洞边界位于应用数据被解释为数据库命令语法的位置;对于 XSS,漏洞边界位于不可信数据被浏览器解释为可执行标记或脚本的位置。API 网关通常只能看到数据进入上述最终上下文前的字节流。

网关可以做什么

强制执行请求契约

验证内容类型、必填字段、数据类型、长度、数值范围、数组大小、嵌套深度和枚举值。在兼容性允许时拒绝意外字段。这样可以缩小输入空间,也能防止超大或格式错误的请求过度消耗应用资源。

但验证不能让自由文本自动变得安全。一个有效的 100 字符搜索词,如果被拼接到 SQL 中,仍然可能造成危险;一段符合模式的个人简介,如果未经适当处理就插入 HTML 上下文,仍然可能触发 XSS。

应用 WAF 检测

WAF 可以检测常见注入载荷、协议异常、编码技巧和已知利用模式。它既适合在有时限的事故响应中提供虚拟补丁,也能为多个服务增加统一筛查层。

Apache APISIX 提供 chaitin-waf 插件,用于集成长亭雷池 WAF。实际部署前,应确认其前置条件、网络路径、策略归属、故障行为和延迟。第三方决策服务并不会天然可用,也不能被假定为永远正确。

限制并观察滥用

可以按可信身份、路由和来源上下文限制重复探测。记录规则标识、路由、执行结果、可信主体和链路追踪信息。对原始值进行采样或脱敏,避免安全日志变成另一套存储可执行载荷或个人数据的系统。

必须在应用中修复什么

在构造查询时防止 SQL 注入

OWASP SQL 注入防护备忘单将使用预处理语句执行参数化查询列为主要防御方式。参数值与 SQL 语法分开绑定,因此用户输入不会被解释为命令片段。

1const result = await db.query(
2  "SELECT id, name FROM products WHERE category = $1 AND price <= $2",
3  [category, maximumPrice]
4);

不要用临时拼凑的转义逻辑或网关正则表达式代替参数化。对于无法作为值绑定的标识符,例如由用户选择的排序列,应把允许的外部值映射到硬编码的内部标识符。应用所使用的数据库账号只应具备必要表和操作权限,也不要把数据库错误直接返回给调用方。

在输出上下文中防止 XSS

OWASP 跨站脚本防护备忘单指出,不同输出上下文需要不同的编码规则。HTML 文本、属性、URL、CSS 和 JavaScript 的处理方式并不相同。应使用默认执行安全编码的框架功能,并避开不安全的渲染函数。

如果产品确实需要接受 HTML,应在存储或渲染前使用维护活跃且策略明确的 HTML 清理器。内容安全策略(CSP)可以作为额外一层降低影响,但不能替代正确编码与清理。基于 DOM 的 XSS 可能完全发生在客户端代码中,API 网关根本看不到这条数据流。

增加 APISIX 请求验证

APISIX request-validation 插件会根据配置的模式验证请求头和请求体。以下 Apache APISIX 3.18 配置片段限制一项 JSON 商品搜索请求:

1{
2  "uri": "/v1/products/search",
3  "methods": ["POST"],
4  "plugins": {
5    "request-validation": {
6      "header_schema": {
7        "type": "object",
8        "required": ["Content-Type"],
9        "properties": {
10          "Content-Type": {
11            "type": "string",
12            "pattern": "^application/json$"
13          }
14        }
15      },
16      "body_schema": {
17        "type": "object",
18        "required": ["query"],
19        "properties": {
20          "query": {
21            "type": "string",
22            "minLength": 1,
23            "maxLength": 120
24          },
25          "sort": {
26            "type": "string",
27            "enum": ["relevance", "price_asc", "price_desc"]
28          },
29          "page": {
30            "type": "integer",
31            "minimum": 1,
32            "maximum": 100
33          }
34        },
35        "additionalProperties": false
36      }
37    }
38  }
39}

请求头模式明确了示例对 JSON 媒体类型的要求,请求体模式则可以减少意外输入,并建立清晰的 API 契约。如果客户端确实需要发送 charset 等媒体类型参数,应有意识地调整请求头规则,并测试所有允许形式。但这项验证既不能授权请求,也无法让 query 变得可以安全拼接到 SQL 中。应用仍须将该值作为参数绑定;如果它随后显示在网页中,展示层仍须针对具体输出上下文进行编码。

设计 WAF 故障与发布行为

大范围启用 WAF 策略前,应明确以下问题:

  • 每条路由在 WAF 评估超时时放行还是拒绝请求;
  • 延迟和容量预算如何纳入检查路径;
  • 哪些规则先以仅检测模式运行;
  • 谁可以批准阻断、排除项或紧急虚拟补丁;
  • 如何在不保留敏感数据的前提下复现误报;
  • 临时排除项和补丁何时到期;
  • 如何进行策略版本的金丝雀发布和回滚;
  • 如何处理经过编码、压缩、使用 multipart、GraphQL 或流式传输的请求体。

故障开放可以维持可用性,但在 WAF 不可用时会撤销保护;故障关闭可以守住检查边界,却也可能让 WAF 成为单点可用性依赖。公共读取与敏感管理写入可以采用不同选择。

测试完整防御链路

应使用经过授权的预发布环境和安全测试记录,并覆盖:

  1. 符合模式与不符合模式的请求;
  2. 边界长度、嵌套对象、意外字段、编码和内容类型;
  3. 参数化查询测试,确认传入值始终作为数据处理;
  4. 在真实浏览器上下文中测试存储型、反射型和基于 DOM 的 XSS;
  5. WAF 检测、阻断、超时、不可用、排除和回滚行为;
  6. 使用多个身份和对象,确认验证没有被误当作授权;
  7. 检查日志和告警,确保保留有效证据的同时不泄露密钥或载荷。

不要对生产数据执行破坏性 SQL 或攻击载荷测试。安全测试需要明确授权、受控流量、清理方案和事故联系人。

纵深防御检查清单

  • 是否在边缘和应用同时限制请求内容类型、模式、大小和结构?
  • 每条数据库查询是否将参数值与 SQL 语法分开绑定?
  • 动态标识符是否通过允许列表映射?
  • 数据库身份是否遵循最小权限?
  • 不可信浏览器输出是否针对具体上下文编码?
  • 有意接收的 HTML 是否由维护活跃且策略明确的工具清理?
  • CSP 是否作为额外控制,而不是 XSS 的主要修复手段?
  • WAF 规则是否经过金丝雀发布、版本管理,具备可观测性并可以回滚?
  • 是否按路由定义 WAF 超时和故障行为?
  • 日志是否避免记录凭证和不必要的原始攻击载荷?
  • 是否测试存储型、反射型和基于 DOM 的 XSS?

总结

API 网关适合强制执行请求契约、筛查已知攻击模式、限制探测并集中生成安全遥测。但造成 SQL 注入和 XSS 的解释器边界仍由应用负责。绑定数据库参数、限制数据库权限、按上下文编码输出、清理有意接收的 HTML,并测试完整数据流。在此基础上,网关验证与 WAF 才能成为有价值的额外防线,而不会制造错误的安全承诺。

常见问题

JSON Schema 验证能阻止 SQL 注入吗?

它可以拒绝意外类型和长度,但如果应用把一个符合模式的字符串拼接到 SQL 中,该字符串仍不安全。必须使用参数化查询。

WAF 能彻底消除 XSS 吗?

不能。它可以阻断已知模式,却无法可靠理解每一种输出上下文或 DOM 数据流,仍须正确编码、使用安全渲染方式并执行清理。

网关应该记录完整的恶意载荷吗?

通常不应。应记录足以支持调查的元数据;确实需要载荷证据时,也应采用受控采样或脱敏。完整请求体可能包含密钥、个人数据或可执行字符串。

后续步骤

建立更完整的 API 网关安全扫描体系,并结合 DDoS 防护。如果需要托管式企业网关安全策略,可以进一步了解 API7 企业版。

获取方案