Qt OpenAPI 安全注意事项
处理来自外部源的 OpenAPI 规范
OpenAPI 规范文件是代码生成管道的主要输入。它定义了生成的客户端的全部功能范围:API 端点、数据模型、服务器 URL、身份验证方案以及操作参数。由于生成器会将规范内容直接转换为 C++ 源代码,因此仅应使用可信的输入。
用户有责任在根据外部来源获取的 OpenAPI 规范生成代码之前对其进行审核。从第三方服务或公共仓库下载的规范可能包含某些值,这些值一旦编译,可能会产生意外或有害的行为。在使用外部规范之前,请检查以下内容:
- 意外或可疑的复杂服务器 URL 模式和变量定义。
- 描述字段或扩展属性中包含不应出现在生成的源代码中的内容。
- 过深或循环的模型引用,这可能会影响运行时的稳定性。
- 可能改变预期请求目标的服务器变量枚举值或默认值。
虽然生成器会进行转义处理,以防止通过规范衍生的字符串直接注入代码,但恶意规范仍会控制生成的客户端的结构和行为——包括类名、端点 URL、数据流以及操作语义。无论进行多少转义处理,在未经事先审查的情况下,任何根本上不可信的规范都无法确保安全使用。
防范资源耗尽
除了审查 OpenAPI 规范的语义内容外,处理来自不可信来源规范的用户还应考虑限制代码生成和执行过程中消耗的资源。
恶意构造的规范可能会在代码生成过程中本身就导致过度的资源消耗,例如通过极其复杂的模式结构、大量引用或深度嵌套的模型。 此外,如果该规范的设计旨在触发资源密集型代码路径或数据结构,则由此生成的代码在运行时可能会消耗过多资源,从而可能导致资源耗尽或服务拒绝(DoS)状况。
底层的 YAML 解析器支持多种配置选项,有助于缓解由恶意 YAML 输入(例如过度的别名展开(如“十亿次笑声”攻击)、深度嵌套的集合、递归映射键或异常大的文档)引起的拒绝服务攻击。 这些限制可通过 JVM 系统属性进行配置(例如,使用JAVA_OPTIONS 或JAVA_TOOL_OPTIONS ),包括:
| 属性 | 用途 |
|---|---|
maxYamlReferences | 限制文件中所有 YAML 别名 (*) 的总数,无论其数据类型如何。作为针对文本级别重复内容的广泛防 DoS 措施。锚点和别名用法示例:别名会影响原始 YAML 语法的解析;与 OpenAPI 的 $ref 指针完全无关。 |
maxYamlAliasesForCollections | 限制专门指向数组或对象的别名(*),忽略普通字符串。这可缓解“Billion Laughs”风格的攻击。 |
supportYamlAnchors | 完全启用或禁用 YAML 锚点的处理。禁用锚点可消除一类基于别名的攻击。 |
maxYamlDepth | 限制 YAML 集合的最大嵌套深度,以防止栈溢出和解析器过度递归。每次向右缩进以创建子对象或子列表时,垂直嵌套深度都会增加 1。请注意,此限制仅计入文件字面缩进,并完全忽略逻辑上的 OpenAPI$ref 指针。 |
maxYamlCodePoints | 限制 YAML 输入文档的总大小。 |
示例:
qt_add_openapi_client(Example
SPEC_FILE
${CMAKE_CURRENT_SOURCE_DIR}/unstructed-source-spec.yaml
JAVA_OPTIONS
-DmaxYamlAliasesForCollections=10
-DmaxYamlDepth=100
-DmaxYamlCodePoints=5000000
-DmaxYamlReferences=10
-DsupportYamlAnchors=false
OUTPUT_DIRECTORY
${CMAKE_CURRENT_BINARY_DIR}
)虽然 YAML 解析器可以阻止语法层面的攻击,但无法防范所有类型的资源耗尽攻击。无论是解析器还是 OpenAPI Generator,均不会限制模式复杂度、测量$ref 链的深度,也不会计算生成的 C++ 结构体将占用的栈空间。因此,代码生成和编译的成功并不能保证运行时安全。 在处理生产环境中的网络流量时,应用程序仍易受以下两个关键攻击向量的影响:
- 水平扩展(宽有效载荷)——模式的嵌套深度可能很小,但允许存在数量庞大的同级对象。运行时解析这些对象需要过度的堆内存分配,从而导致严重的内存碎片化或内存不足(OOM)崩溃。
- 垂直加深(深度有效载荷)——一种模式可能合法地定义了深度嵌套的数组或对象链,且能通过编译。 然而,当利用这种深度的恶意有效载荷通过网络传入时,运行时解析器的递归执行将迅速耗尽线程的固定栈空间,从而引发无法恢复的栈溢出。
对于处理来自不可信来源的规范的应用程序,用户应在调用生成器之前对规范进行额外的手动审查。建议检查以下内容:
| 建议的审查内容 | 目的 |
|---|---|
$ref 循环引用 | 防止可能增加处理复杂度或暴露实现特定限制的递归引用图。 |
| 最大模式嵌套深度(嵌套对象) | 避免对象层次结构过深。 |
$ref 解析的最大深度(嵌套模式引用) | 避免过长的引用链。 |
| 模式的最大数量 | 限制规范的整体规模和复杂度。 |
| 数组和映射的最大嵌套深度 | 避免可能消耗过多资源的深度嵌套集合类型。 |
网络通信
生成的客户端使用QNetworkAccessManager 进行 HTTP 请求。凭据(API 密钥、承载令牌、基本认证)将附加到出站请求中。该库不强制要求使用 HTTPS;应用程序必须确保凭据仅通过安全连接传输。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.