API Fuzzing 作业故障排除
API Fuzzing 作业在 N 小时后超时
对于较大的仓库,API Fuzzing 作业可能会在默认设置的 Linux 小型托管运行器 上超时。如果您的作业出现这种情况,应该升级到 更大的运行器。
请参阅以下文档章节获取帮助:
API Fuzzing 作业完成时间过长
请参阅 性能调优和测试速度
错误:等待 API Fuzzing 'http://127.0.0.1:5000' 可用时出错
在 v1.6.196 之前的 API Fuzzing analyzer 版本中存在一个 bug,可能导致后台进程在某些条件下失败。解决方案是更新到更新版本的 API Fuzzing analyzer。
版本信息可以在 apifuzzer_fuzz 作业的作业详情中找到。
如果问题出现在 v1.6.196 或更高版本中,请联系支持并提供以下信息:
- 引用本故障排除章节,并请求将问题升级到动态分析团队。
- 作业的完整控制台输出。
- 作为作业工件的
gl-api-security-scanner.log文件。在作业详情页面的右侧面板中,选择 Browse 按钮。 - 来自您的
.gitlab-ci.yml文件的apifuzzer_fuzz作业定义。
错误消息
- 在 GitLab 15.6 及更高版本 中,
Error waiting for API Fuzzing 'http://127.0.0.1:5000' to become available - 在 GitLab 15.5 及更早版本中,
Error waiting for API Security 'http://127.0.0.1:5000' to become available
无法启动扫描器会话。请重试,如果问题持续存在,请联系支持。
当 API Fuzzing 引擎无法与扫描器应用程序组件建立连接时,会输出错误消息。该错误消息显示在 apifuzzer_fuzz 作业的作业输出窗口中。此问题的常见原因是后台组件无法使用所选端口,因为该端口已被占用。如果时机因素(竞争条件)导致此问题间歇性发生。当其他服务被映射到容器中导致端口冲突时,此问题最常出现在 Kubernetes 环境中。
在继续解决方案之前,重要的是确认错误消息的产生是因为端口已被占用。要确认这是原因:
-
转到作业控制台。
-
查找工件
gl-api-security-scanner.log。您可以通过选择 Download 下载所有工件然后搜索文件,或者直接选择 Browse 开始搜索。 -
在文本编辑器中打开文件
gl-api-security-scanner.log。 -
如果错误消息的产生是因为端口已被占用,您应该在文件中看到类似以下的消息:
-
在 GitLab 15.5 及更高版本 中:
Failed to bind to address http://127.0.0.1:5500: address already in use. -
在 GitLab 15.4 及更早版本中:
Failed to bind to address http://[::]:5000: address already in use.
前一条消息中的 http://[::]:5000 在您的情况下可能不同,例如可能是 http://[::]:5500 或 http://127.0.0.1:5500。只要错误消息的其余部分相同,就可以安全地假定端口已被占用。
如果您没有找到端口已被占用的证据,请检查其他故障排除章节,这些章节也处理作业控制台输出中显示的相同错误消息。如果没有更多选项,请随时通过适当的渠道 获取支持或请求改进。
一旦确认问题的产生是因为端口已被占用。那么,GitLab 15.5 及更高版本 引入了配置变量 FUZZAPI_API_PORT。此配置变量允许为扫描器后台组件设置固定端口号。
解决方案
- 确保您的
.gitlab-ci.yml文件定义了配置变量FUZZAPI_API_PORT。 - 将
FUZZAPI_API_PORT的值更新为任何大于 1024 的可用端口号。我们建议检查新值是否未被 GitLab 使用。有关 GitLab 使用的完整端口列表,请参阅 Package defaults
错误:使用发布的 OpenAPI schema 验证文档时发现错误
在 API Fuzzing 作业开始时,OpenAPI Specification 会根据 发布的 schema 进行验证。当提供的 OpenAPI Specification 存在验证错误时,会显示此错误:
Error, the OpenAPI document is not valid.
Errors were found during validation of the document using the published OpenAPI schema在手动创建 OpenAPI Specification 时,以及在 schema 生成时,都可能会引入错误。
对于自动生成的 OpenAPI Specification,验证错误通常是缺少代码注释的结果。
错误消息
Error, the OpenAPI document is not valid. Errors were found during validation of the document using the published OpenAPI schemaOpenAPI 2.0 schema validation error ...OpenAPI 3.0.x schema validation error ...
解决方案
对于自动生成的 OpenAPI Specification
- 识别验证错误。
- 使用 Swagger Editor 来识别规范中的验证问题。Swagger Editor 的可视化特性使您更容易理解需要更改的内容。
- 或者,您可以检查日志输出并查找 schema 验证警告。它们以
OpenAPI 2.0 schema validation error或OpenAPI 3.0.x schema validation error等消息为前缀。每次失败的验证都会提供关于location和description的额外信息。JSON Schema 验证消息可能很复杂,编辑器可以帮助您验证 schema 文档。
- 查阅您的框架/技术栈使用的 OpenAPI 生成的文档。识别生成正确 OpenAPI 文档所需的更改。
- 解决验证问题后,重新运行您的 pipeline。
对于手动创建的 OpenAPI Specification
- 识别验证错误。
- 最简单的解决方案是使用可视化工具来编辑和验证 OpenAPI 文档。例如 Swagger Editor 会突出显示 schema 错误和可能的解决方案。
- 或者,您可以检查日志输出并查找 schema 验证警告。它们以
OpenAPI 2.0 schema validation error或OpenAPI 3.0.x schema validation error等消息为前缀。每次失败的验证都会提供关于location和description的额外信息。更正每个验证失败,然后重新提交 OpenAPI 文档。JSON Schema 验证消息可能很复杂,编辑器可以帮助您验证 schema 文档。
- 解决验证问题后,重新运行您的 pipeline。
无法启动扫描器会话(未找到版本头)
当 API Fuzzing 引擎无法与扫描器应用程序组件建立连接时,会输出错误消息。该错误消息显示在 apifuzzer_fuzz 作业的作业输出窗口中。此问题的常见原因是将 FUZZAPI_API 变量从其默认值更改。
错误消息
Failed to start scanner session (version header not found).
解决方案
- 从
.gitlab-ci.yml文件中删除FUZZAPI_API变量。该值继承自 API Fuzzing CI/CD 模板。我们推荐此方法而不是手动设置值。 - 如果无法删除该变量,请检查该值是否在最新版本的 API Fuzzing CI/CD 模板 中已更改。如果是,请在
.gitlab-ci.yml文件中更新该值。
应用程序无法确定目标 API 的基础 URL
当 API Fuzzing analyzer 在检查 OpenAPI 文档后无法确定目标 API 时,会输出错误消息。当目标 API 未在 .gitlab-ci.yml 文件中设置、在 environment_url.txt 文件中不可用,并且无法使用 OpenAPI 文档计算时,会显示此错误消息。
API Fuzzing analyzer 在检查不同来源时尝试获取目标 API 时有一个优先顺序。首先,它尝试使用 FUZZAPI_TARGET_URL。如果未设置环境变量,则 API Fuzzing analyzer 尝试使用 environment_url.txt 文件。如果没有 environment_url.txt 文件,API Fuzzing analyzer 现在使用 OpenAPI 文档内容和 FUZZAPI_OPENAPI 中提供的 URL(如果提供了 URL)来尝试计算目标 API。
最适合的解决方案取决于您的目标 API 是否每次部署都会发生变化:
静态环境解决方案
此解决方案适用于目标 API URL 不变的 pipeline(静态环境)。
添加环境变量
对于目标 API 保持不变的环境,我们建议您使用 FUZZAPI_TARGET_URL 环境变量指定目标 URL。在您的 .gitlab-ci.yml 文件中,添加一个变量 FUZZAPI_TARGET_URL。该变量必须设置为 API 测试目标的基础 URL。例如:
stages:
- fuzz
include:
- template: API-Fuzzing.gitlab-ci.yml
variables:
FUZZAPI_TARGET_URL: http://test-deployment/
FUZZAPI_OPENAPI: test-api-specification.json动态环境解决方案
在动态环境中,您的目标 API 每次不同的部署都会变化。在这种情况下,有多种可能的解决方案,我们建议在处理动态环境时使用 environment_url.txt 文件。
使用 environment_url.txt
为了支持目标 API URL 在每个 pipeline 中发生变化的动态环境,API Fuzzing 支持使用包含要使用的 URL 的 environment_url.txt 文件。此文件不会检入仓库,而是在 pipeline 期间由部署测试目标的作业创建,并作为工件收集,供 pipeline 中的后续作业使用。创建 environment_url.txt 文件的作业必须在 API Fuzzing 作业之前运行。
- 修改测试目标部署作业,在项目根目录的
environment_url.txt文件中添加基础 URL。 - 修改测试目标部署作业,将
environment_url.txt作为工件收集。
示例:
deploy-test-target:
script:
# 执行部署步骤
# 创建 environment_url.txt(示例)
- echo http://${CI_PROJECT_ID}-${CI_ENVIRONMENT_SLUG}.example.org > environment_url.txt
artifacts:
paths:
- environment_url.txt使用无效 schema 的 OpenAPI
在某些情况下,文档是使用无效 schema 自动生成的,或者无法及时手动编辑。在这些场景中,可以通过设置变量 FUZZAPI_OPENAPI_RELAXED_VALIDATION 来执行宽松验证。我们建议提供完全符合规范的 OpenAPI 文档以防止意外行为。
编辑不符合规范的 OpenAPI 文件
为了检测和修正不符合 OpenAPI 规范的元素,我们建议使用编辑器。编辑器通常提供文档验证,并创建符合 schema 的 OpenAPI 文档的建议。建议的编辑器包括:
| Editor | OpenAPI 2.0 | OpenAPI 3.0.x | OpenAPI 3.1.x |
|---|---|---|---|
| Swagger Editor | YAML, JSON | YAML, JSON | YAML, JSON |
| Stoplight Studio | YAML, JSON | YAML, JSON | YAML, JSON |
如果您的 OpenAPI 文档是手动生成的,请在编辑器中加载文档并修复任何不符合规范的内容。如果您的文档是自动生成的,请在编辑器中加载它以识别 schema 中的问题,然后转到应用程序并根据您使用的框架执行更正。
启用 OpenAPI 宽松验证
宽松验证适用于 OpenAPI 文档无法满足 OpenAPI 规范但仍具有足够内容供不同工具使用的情况。会执行验证,但在文档 schema 方面不那么严格。
API Fuzzing 仍然可以尝试使用不完全符合 OpenAPI 规范的 OpenAPI 文档。要指示 API Fuzzing analyzer 执行宽松验证,将变量 FUZZAPI_OPENAPI_RELAXED_VALIDATION 设置为任何值,例如:
stages:
- fuzz
include:
- template: API-Fuzzing.gitlab-ci.yml
variables:
FUZZAPI_PROFILE: Quick-10
FUZZAPI_TARGET_URL: http://test-deployment/
FUZZAPI_OPENAPI: test-api-specification.json
FUZZAPI_OPENAPI_RELAXED_VALIDATION: 'On'OpenAPI 文档中没有操作使用任何支持的媒体类型
API Fuzzing 使用 OpenAPI 文件中指定的媒体类型生成请求。如果没有支持的媒体类型而无法创建请求,则会抛出错误。
错误消息
Error, no operation in the OpenApi document is consuming any supported media type. Check 'OpenAPI Specification' to check the supported media types.
解决方案
- 查看 OpenAPI Specification 部分中的支持媒体类型。
- 编辑您的 OpenAPI 文档,允许至少一个操作接受任何支持的媒体类型。或者,可以在 OpenAPI 文档级别设置支持的媒体类型并应用于所有操作。此步骤可能需要更改您的应用程序,以确保应用程序接受支持的媒体类型。
错误:无法建立 SSL 连接,请查看内部异常。
API fuzzing 兼容广泛的 TLS 配置,包括过时的协议和密码。 尽管支持广泛,您可能会遇到连接错误,例如:
Error, error occurred trying to download `<URL>`:
There was an error when retrieving content from Uri:' <URL>'.
Error:The SSL connection could not be established, see inner exception.此错误发生是因为 API fuzzing 无法与给定 URL 的服务器建立安全连接。
要解决此问题:
如果错误消息中的主机支持非 TLS 连接,请在您的配置中将 https:// 更改为 http://。
例如,如果以下配置出现错误:
stages:
- fuzz
include:
- template: API-Fuzzing.gitlab-ci.yml
variables:
FUZZAPI_TARGET_URL: https://test-deployment/
FUZZAPI_OPENAPI: https://specs/openapi.json将 FUZZAPI_OPENAPI 的前缀从 https:// 更改为 http://:
stages:
- fuzz
include:
- template: API-Fuzzing.gitlab-ci.yml
variables:
FUZZAPI_TARGET_URL: https://test-deployment/
FUZZAPI_OPENAPI: http://specs/openapi.json如果您无法使用非 TLS 连接访问 URL,请联系支持团队寻求帮助。
您可以使用 testssl.sh 工具 加速调查。从具有 bash shell 并能够连接到受影响服务器的机器:
- 从 https://github.com/drwetter/testssl.sh/releases 下载最新的
zip或tar.gz文件并解压。 - 运行
./testssl.sh --log https://specs。 - 将日志文件附加到您的支持工单中。
ERROR: Job failed: failed to pull image
当从需要身份验证才能访问的容器注册表(非公共)拉取镜像时,会出现此错误消息。
在作业控制台输出中,错误如下所示:
Running with gitlab-runner 15.6.0~beta.186.ga889181a (a889181a)
on blue-2.shared.runners-manager.gitlab.com/default XxUrkriX
Resolving secrets
00:00
Preparing the "docker+machine" executor
00:06
Using Docker executor with image registry.gitlab.com/security-products/api-security:2 ...
Starting service registry.example.com/my-target-app:latest ...
Pulling docker image registry.example.com/my-target-app:latest ...
WARNING: Failed to pull image with policy "always": Error response from daemon: Get https://registry.example.com/my-target-app/manifests/latest: unauthorized (manager.go:237:0s)
ERROR: Job failed: failed to pull image "registry.example.com/my-target-app:latest" with specified policies [always]: Error response from daemon: Get https://registry.example.com/my-target-app/manifests/latest: unauthorized (manager.go:237:0s)错误消息
- 在 GitLab 15.9 及更早版本中,
ERROR: Job failed: failed to pull image后跟Error response from daemon: Get IMAGE: unauthorized。
解决方案
身份验证凭据使用 从私有容器注册表访问镜像 文档部分中概述的方法提供。使用的方法取决于您的容器注册表提供者及其配置。如果您使用第三方提供的容器注册表,例如云提供者(Azure、Google Could (GCP)、AWS 等),请查阅提供者文档以了解如何向其容器注册表进行身份验证。
以下示例使用 静态定义凭据 身份验证方法。在此示例中,容器注册表是 registry.example.com,镜像是 my-target-app:latest。
-
阅读 确定您的
DOCKER_AUTH_CONFIG数据 以了解如何计算DOCKER_AUTH_CONFIG的变量值。配置变量DOCKER_AUTH_CONFIG包含 Docker JSON 配置,以提供适当的身份验证信息。例如,要访问私有容器注册表:registry.example.com,凭据为abcdefghijklmn,Docker JSON 如下所示:{ "auths": { "registry.example.com": { "auth": "abcdefghijklmn" } } } -
将
DOCKER_AUTH_CONFIG添加为 CI/CD 变量。您应该在项目中创建 CI/CD 变量,而不是在.gitlab-ci.yml文件中直接添加配置变量。 -
重新运行您的作业,静态定义的凭据现在用于登录私有容器注册表
registry.example.com,并允许您拉取镜像my-target-app:latest。如果成功,作业控制台会显示如下输出:Running with gitlab-runner 15.6.0~beta.186.ga889181a (a889181a) on blue-4.shared.runners-manager.gitlab.com/default J2nyww-s Resolving secrets 00:00 Preparing the "docker+machine" executor 00:56 Using Docker executor with image registry.gitlab.com/security-products/api-security:2 ... Starting service registry.example.com/my-target-app:latest ... Authenticating with credentials from $DOCKER_AUTH_CONFIG Pulling docker image registry.example.com/my-target-app:latest ... Using docker image sha256:139c39668e5e4417f7d0eb0eeb74145ba862f4f3c24f7c6594ecb2f82dc4ad06 for registry.example.com/my-target-app:latest with digest registry.example.com/my-target- app@sha256:2b69fc7c3627dbd0ebaa17674c264fcd2f2ba21ed9552a472acf8b065d39039c ... Waiting for services to be up and running (timeout 30 seconds)...
sudo: "no new privileges" 标志已设置,这阻止了 sudo 以 root 身份运行。
从 analyzer 的 v5 版本开始,默认使用非 root 用户。这需要在执行特权操作时使用 sudo。
此错误发生在特定的容器守护进程设置中,该设置阻止运行的容器获得新权限。在大多数设置中,这不是默认配置,而是专门配置的,通常作为安全加固指南的一部分。
错误消息
可以通过在执行 before_script 或 FUZZAPI_PRE_SCRIPT 时生成的错误消息来识别此问题:
$ sudo apk add nodejs
sudo: The "no new privileges" flag is set, which prevents sudo from running as root.
sudo: If sudo is running in a container, you may need to adjust the container configuration to disable the flag.解决方案
可以通过以下方式解决此问题:
-
以
root用户运行容器。建议测试此配置,因为它可能不适用于所有情况。这可以通过修改 CICD 配置并检查作业输出来确保whoami返回root而不是gitlab来完成。如果显示gitlab,请使用其他解决方法。测试完成后可以删除before_script。apifuzzer_fuzz: image: name: $SECURE_ANALYZERS_PREFIX/$FUZZAPI_IMAGE:$FUZZAPI_VERSION$FUZZAPI_IMAGE_SUFFIX docker: user: root before_script: - whoami示例作业控制台输出:
Executing "step_script" stage of the job script Using docker image sha256:8b95f188b37d6b342dc740f68557771bb214fe520a5dc78a88c7a9cc6a0f9901 for registry.gitlab.com/security-products/api-security:5 with digest registry.gitlab.com/security-products/api-security@sha256:092909baa2b41db8a7e3584f91b982174772abdfe8ceafc97cf567c3de3179d1 ... $ whoami root $ /peach/analyzer-api-fuzzing 17:17:14 [INF] API Security: Gitlab API Security 17:17:14 [INF] API Security: ------------------- 17:17:14 [INF] API Security: 17:17:14 [INF] API Security: version: 5.7.0 -
包装容器并在构建时添加任何依赖项。此选项的好处是运行时权限低于 root,这可能是某些客户的要求。
-
创建一个新的
Dockerfile来包装现有镜像。ARG SECURE_ANALYZERS_PREFIX ARG FUZZAPI_IMAGE ARG FUZZAPI_VERSION ARG FUZZAPI_IMAGE_SUFFIX FROM $SECURE_ANALYZERS_PREFIX/$FUZZAPI_IMAGE:$FUZZAPI_VERSION$FUZZAPI_IMAGE_SUFFIX USER root RUN pip install ... RUN apk add ... USER gitlab -
在 API Fuzzing 作业开始之前构建新镜像并将其推送到您的本地容器注册表。作业完成后应删除该镜像。
TARGET_NAME=apifuzz-$CI_COMMIT_SHA docker build -t $TARGET_IMAGE \ --build-arg "SECURE_ANALYZERS_PREFIX=$SECURE_ANALYZERS_PREFIX" \ --build-arg "FUZZAPI_IMAGE=$APISEC_IMAGE" \ --build-arg "FUZZAPI_VERSION=$APISEC_VERSION" \ --build-arg "FUZZAPI_IMAGE_SUFFIX=$APISEC_IMAGE_SUFFIX" \ . docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY docker push $TARGET_IMAGE -
扩展
apifuzzer_fuzz作业并使用新镜像名称。apifuzzer_fuzz: image: apifuzz-$CI_COMMIT_SHA -
从注册表中删除临时容器。有关删除容器镜像的信息,请参阅 此文档页面。
-
-
更改 GitLab Runner 配置,禁用 no-new-privileges 标志。这可能会带来安全影响,应与您的运维和安全团队讨论。
索引超出数组范围。在 Peach.Web.Runner.Services.RunnerOptions.GetHeaders()
此错误消息表明 API Fuzzing analyzer 无法解析 FUZZAPI_REQUEST_HEADERS 或 FUZZAPI_REQUEST_HEADERS_BASE64 配置变量的值。
错误消息
可以通过两个错误消息来识别此问题。第一个错误消息出现在作业控制台输出中,第二个出现在 gl-api-security-scanner.log 文件中。
来自作业控制台的错误消息:
05:48:38 [ERR] API Security: Testing failed: An unexpected exception occurred: Index was outside the bounds of the array.来自 gl_api_security-scanner.log 的错误消息:
08:45:43.616 [ERR] <Peach.Web.Core.Services.WebRunnerMachine> Unexpected exception in WebRunnerMachine::Run()
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Peach.Web.Runner.Services.RunnerOptions.GetHeaders() in /builds/gitlab-org/security-products/analyzers/api-fuzzing-src/web/PeachWeb/Runner/Services/[RunnerOptions.cs:line 362
at Peach.Web.Runner.Services.RunnerService.Start(Job job, IRunnerOptions options) in /builds/gitlab-org/security-products/analyzers/api-fuzzing-src/web/PeachWeb/Runner/Services/RunnerService.cs:line 67
at Peach.Web.Core.Services.WebRunnerMachine.Run(IRunnerOptions runnerOptions, CancellationToken token) in /builds/gitlab-org/security-products/analyzers/api-fuzzing-src/web/PeachWeb/Core/Services/WebRunnerMachine.cs:line 321
08:45:43.634 [WRN] <Peach.Web.Core.Services.WebRunnerMachine> * Session failed: An unexpected exception occurred: Index was outside the bounds of the array.
08:45:43.677 [INF] <Peach.Web.Core.Services.WebRunnerMachine> Finished testing. Performed a total of 0 requests.解决方案
此问题是由于格式错误的 FUZZAPI_REQUEST_HEADERS 或 FUZZAPI_REQUEST_HEADERS_BASE64 变量造成的。预期格式是一个或多个 Header: value 构造的标头,用逗号分隔。解决方案是更正语法以匹配预期格式。
有效示例:
Authorization: Bearer XYZX-Custom: Value,Authorization: Bearer XYZ
无效示例:
Header:,valueHeaderA: value,HeaderB:,HeaderC: valueHeader