以下故障排除场景来自客户支持案例。如果您遇到这里未解决的问题,或者这里的信息未能解决您的问题,请创建支持票。有关更多详细信息,请参阅极狐GitLab 支持页面。

当出现问题时

当 DAST 扫描出现问题时,如果您有特定的错误信息,请检查已知问题。否则,请尝试通过回答以下问题来发现问题:

  1. 预期结果是什么?
  2. 结果是否可由人类实现?
  3. 有任何原因导致 DAST 无法工作吗?
  4. 您的应用程序如何工作?
  5. DAST 正在做什么?

预期结果是什么?

遇到 DAST 扫描问题的许多用户对扫描器应该执行的操作有一个很好的高层次想法。例如,它没有扫描特定页面,或者没有选择页面上的按钮。

尽量将问题隔离,以帮助缩小解决方案的搜索范围。例如,考虑 DAST 未扫描特定页面的情况。DAST 应该从哪里找到该页面?它采取了什么路径到达那里?在引用页面上是否有 DAST 应该选择的元素,但没有选择?

结果是否可由人类实现?

如果人类无法手动遍历应用程序,DAST 将无法扫描应用程序。

了解您期望的结果,尝试使用您机器上的浏览器手动复制它。例如:

  1. 打开一个新的隐身/私人浏览器窗口。
  2. 打开开发者工具。密切关注控制台中的错误消息。
    • 在 Chrome 中:View -> Developer -> Developer Tools
    • 在 Firefox 中:Tools -> Browser Tools -> Web Developer Tools
  3. 如果进行身份验证:
    • 访问 DAST_AUTH_URL
    • DAST_AUTH_USERNAME_FIELD 中输入 DAST_AUTH_USERNAME
    • DAST_AUTH_PASSWORD_FIELD 中输入 DAST_AUTH_PASSWORD
    • 选择 DAST_AUTH_SUBMIT_FIELD
  4. 选择链接并填写表单。导航到未正确扫描的页面。
  5. 观察您的应用程序行为。注意是否有任何可能导致自动扫描器出现问题的因素。

有任何原因导致 DAST 无法工作吗?

当出现以下情况时,DAST 无法正确扫描:

  1. 存在 CAPTCHA。在被扫描应用程序的测试环境中关闭这些。
  2. 无法访问目标应用程序。确保极狐GitLab Runner 可以使用 DAST 配置中使用的 URL 访问应用程序。

您的应用程序如何工作?

了解您的应用程序如何工作对于找出 DAST 扫描失败的原因至关重要。例如,以下情况可能需要额外的配置设置。

  1. 是否有弹出模态隐藏元素?
  2. 加载页面在特定时间后是否发生显著变化?
  3. 应用程序加载速度是否特别慢或快?
  4. 目标应用程序在加载时是否不稳定?
  5. 应用程序是否根据客户端的位置不同而工作?
  6. 应用程序是否为单页面应用程序?
  7. 应用程序是否提交 HTML 表单,或者是否使用 JavaScript 和 AJAX?
  8. 应用程序是否使用 websockets?
  9. 应用程序是否使用特定的 Web 框架?
  10. 选择按钮是否在继续提交表单之前运行 JavaScript?快还是慢?
  11. 是否可能在元素或页面准备好之前 DAST 已经选择或搜索元素?

DAST 正在做什么?

日志记录仍然是了解 DAST 正在做什么的最佳方式:

  1. 基于浏览器的分析器日志记录,用于了解分析器正在做什么。
  2. Chromium DevTools 日志记录,用于检查 DAST 和 Chromium 之间的通信。
  3. Chromium 日志,用于在 Chromium 意外崩溃时记录错误。

基于浏览器的分析器日志记录

分析器日志是帮助诊断扫描问题的最有用工具之一。分析器的不同部分可以在不同级别进行日志记录。

日志消息格式

日志消息的格式为 [time] [log level] [log module] [message] [additional properties]

例如,以下日志条目具有级别 INFO,属于 CRAWL 日志模块,消息为 Crawled path,额外属性为 nav_idpath

2021-04-21T00:34:04.000 INF CRAWL Crawled path nav_id=0cc7fd path="LoadURL [https://my.site.com:8090]"

日志目的地

日志要么发送到文件,要么发送到控制台(CI/CD 作业日志)。您可以使用环境变量 DAST_LOG_CONFIG 为控制台日志和 DAST_LOG_FILE_CONFIG 为文件日志配置每个目的地以接受不同的日志。

例如:

include:
  - template: DAST.gitlab-ci.yml

dast:
  variables:
    DAST_BROWSER_SCAN: "true"
    DAST_LOG_CONFIG: "auth:debug"                               # console log defaults to INFO level, logs AUTH module at DEBUG
    DAST_LOG_FILE_CONFIG: "loglevel:debug,cache:warn"           # file log defaults to DEBUG level, logs CACHE module at WARN

默认情况下,文件日志是一个名为 gl-dast-scan.log 的作业产物。要配置此路径,修改 DAST_LOG_FILE_PATH CI/CD 变量。

日志级别

可以配置的日志级别如下:

日志模块 组件概述 更多信息
TRACE 用于特定的、通常嘈杂的功能内工作。  
DEBUG 描述功能的内部工作。用于诊断目的。  
INFO 描述扫描的高层流程和结果。 如果未指定,则为默认级别。
WARN 描述 DAST 恢复并继续扫描的错误情况。  
FATAL/ERROR/PANIC 描述退出前无法恢复的错误。  

日志模块

LOGLEVEL 配置日志目的地的默认日志级别。如果配置了以下任何模块,DAST 使用该模块的日志级别优先于默认日志级别。

可以配置日志记录的模块如下:

日志模块 组件概述
ACTIV 用于主动攻击。
AUTH 用于创建身份验证扫描。
BPOOL 为爬虫租赁的浏览器集合。
BROWS 用于查询浏览器的状态或页面。
CACHE 用于报告缓存 HTTP 资源的缓存命中和未命中。
CHROM 用于记录 Chrome DevTools 消息。
CONFG 用于记录分析器配置。
CONTA 用于容器收集 DevTools 消息中的 HTTP 请求和响应部分。
CRAWL 用于核心爬虫算法。
CRWLG 用于爬虫图生成器。
DATAB 用于将数据持久化到内部数据库。
LEASE 用于创建浏览器以将其添加到浏览器池中。
MAIN 用于爬虫主事件循环的流程。
NAVDB 用于持久化机制以存储导航条目。
REGEX 用于记录运行正则表达式时的性能统计信息。
REPT 用于生成报告。
STAT 用于运行扫描时的一般统计信息。
VLDFN 用于加载和解析漏洞定义。
WEBGW 用于记录在运行主动检查时发送到目标应用程序的消息。
SCOPE 用于记录与范围管理相关的消息。

SECURE_LOG_LEVEL

{{< history >}}

  • 引入于极狐GitLab 17.11。

{{< /history >}}

作为使用 DAST_LOG_FILE_CONFIG 配置日志模块的简单替代方法,您可以设置 SECURE_LOG_LEVEL

  1. 设置为任何支持的日志级别。这样做时,指定的级别将成为日志文件中所有模块的默认日志级别。
  2. 设置为 debugtrace 以启用身份验证报告
  3. 设置为 trace 以启用DevTools 日志记录

例如:

include:
  - template: DAST.gitlab-ci.yml

dast:
  variables:
    SECURE_LOG_LEVEL: "trace"
    # is equivalent to:
    # DAST_LOG_FILE_CONFIG: "loglevel:trace"
    # DAST_LOG_DEVTOOLS_CONFIG: "Default:messageAndBody,truncate:2000"
    # DAST_AUTH_REPORT: "true"

来自 DAST_LOG_FILE_CONFIGDAST_LOG_DEVTOOLS_CONFIGDAST_AUTH_REPORT 的设置会覆盖来自 SECURE_LOG_LEVEL 的设置。

示例 - 日志爬网路径

将日志模块 CRAWL 设置为 DEBUG 以记录在扫描的爬虫阶段找到的导航路径。这对于了解 DAST 是否正确地爬虫您的目标应用程序非常有用。

include:
  - template: DAST.gitlab-ci.yml

dast:
  variables:
    DAST_LOG_CONFIG: "crawl:debug"

例如,以下输出显示在 https://example.com 页面爬虫过程中发现了四个锚链接。

2022-11-17T11:18:05.578 DBG CRAWL executing step nav_id=6ec647d8255c729160dd31cb124e6f89 path="LoadURL [https://example.com]" step=1
...
2022-11-17T11:18:11.900 DBG CRAWL found new navigations browser_id=2243909820020928961 nav_count=4 nav_id=6ec647d8255c729160dd31cb124e6f89 of=1 step=1
2022-11-17T11:18:11.901 DBG CRAWL adding navigation action="LeftClick [a href=/docs/page1.html]" nav=bd458cc1fc2d7c6fb984464b6d968866 parent_nav=6ec647d8255c729160dd31cb124e6f89
2022-11-17T11:18:11.901 DBG CRAWL adding navigation action="LeftClick [a href=/docs/page2.html]" nav=6dcb25f9f9ece3ee0071ac2e3166d8e6 parent_nav=6ec647d8255c729160dd31cb124e6f89
2022-11-17T11:18:11.901 DBG CRAWL adding navigation action="LeftClick [a href=/docs/page3.html]" nav=89efbb0c6154d6c6d85a63b61a7cdc6f parent_nav=6ec647d8255c729160dd31cb124e6f89
2022-11-17T11:18:11.901 DBG CRAWL adding navigation action="LeftClick [a href=/docs/page4.html]" nav=f29b4f4e0bdee70f5255de7fc080f04d parent_nav=6ec647d8255c729160dd31cb124e6f89

Chromium DevTools 日志记录

{{< alert type=”warning” >}}

记录 DevTools 消息是一个安全风险。输出包含用户名、密码和身份验证令牌等密钥。输出上传到极狐GitLab 服务器,并可能在作业日志中可见。

{{< /alert >}}

DAST 基于浏览器的扫描器使用 Chrome DevTools 协议协调 Chromium 浏览器。记录 DevTools 消息有助于提供浏览器正在做什么的透明性。例如,如果选择按钮不起作用,DevTools 消息可能显示原因是浏览器控制台日志中的 CORS 错误。包含 DevTools 消息的日志可能非常大。因此,它应该仅在持续时间较短的作业上启用。

要记录所有 DevTools 消息,请将 CHROM 日志模块调为 trace 并配置日志级别。以下是 DevTools 日志的示例:

2022-12-05T06:27:24.280 TRC CHROM event received    {"method":"Fetch.requestPaused","params":{"requestId":"interception-job-3.0","request":{"url":"http://auth-auto:8090/font-awesome.min.css","method":"GET","headers":{"Accept":"text/css,*/*;q=0.1","Referer":"http://auth-auto:8090/login.html","User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/105.0.5195.102 Safari/537.36"},"initialPriority":"VeryHigh","referrerPolicy":"strict-origin-when-cross-origin"},"frameId":"A706468B01C2FFAA2EB6ED365FF95889","resourceType":"Stylesheet","networkId":"39.3"}} method=Fetch.requestPaused
2022-12-05T06:27:24.280 TRC CHROM request sent      {"id":47,"method":"Fetch.continueRequest","params":{"requestId":"interception-job-3.0","headers":[{"name":"Accept","value":"text/css,*/*;q=0.1"},{"name":"Referer","value":"http://auth-auto:8090/login.html"},{"name":"User-Agent","value":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/105.0.5195.102 Safari/537.36"}]}} id=47 method=Fetch.continueRequest
2022-12-05T06:27:24.281 TRC CHROM response received {"id":47,"result":{}} id=47 method=Fetch.continueRequest

自定义 DevTools 日志级别

Chrome DevTools 请求、响应和事件按域进行命名空间。DAST 允许每个域和每个带消息的域具有不同的日志记录配置。环境变量 DAST_LOG_DEVTOOLS_CONFIG 接受一个以分号分隔的日志记录配置列表。日志记录配置使用结构 [domain/message]:[what-to-log][,truncate:[max-message-size]] 声明。

  • domain/message 指的是日志记录内容。
    • Default 可用作值,代表所有域和消息。
    • 可以是域,例如 BrowserCSSPageNetwork
    • 可以是带消息的域,例如 Network.responseReceived
    • 如果适用多个配置,则使用最具体的配置。
  • what-to-log 指的是是否以及记录什么。
    • message 记录收到消息,并且不记录消息内容。
    • messageAndBody 记录消息及其内容。推荐与 truncate 一起使用。
    • suppress 不记录消息。用于静音嘈杂的域和消息。
  • truncate 是一个可选配置,用于限制打印消息的大小。

示例 - 记录所有 DevTools 消息

用于记录所有内容,当您不确定从哪里开始时使用。

include:
  - template: DAST.gitlab-ci.yml

dast:
  variables:
    DAST_LOG_FILE_CONFIG: "chrom:trace"
    DAST_LOG_DEVTOOLS_CONFIG: "Default:messageAndBody,truncate:2000"

示例 - 记录 HTTP 消息

当资源未正确加载时很有用。记录 HTTP 消息事件以及继续或失败请求的决策。浏览器控制台中的任何错误也会被记录。

include:
  - template: DAST.gitlab-ci.yml

dast:
  variables:
    DAST_LOG_FILE_CONFIG: "chrom:trace"
    DAST_LOG_DEVTOOLS_CONFIG: "Default:suppress;Fetch:messageAndBody,truncate:2000;Network:messageAndBody,truncate:2000;Log:messageAndBody,truncate:2000;Console:messageAndBody,truncate:2000"

Chromium 日志

在 Chromium 崩溃的罕见情况下,将 Chromium 进程 STDOUTSTDERR 写入日志可能会有所帮助。设置环境变量 DAST_LOG_BROWSER_OUTPUTtrue 可以实现此目的。

DAST 启动并停止许多 Chromium 进程。DAST 将每个进程输出发送到所有日志目的地,日志模块为 LEASE,日志级别为 INFO

例如:

include:
  - template: DAST.gitlab-ci.yml

dast:
  variables:
    DAST_LOG_BROWSER_OUTPUT: "true"

已知问题

日志包含 response body exceeds allowed size

默认情况下,DAST 处理 HTTP 响应正文大小为 10 MB 或更小的 HTTP 请求。否则,DAST 阻止响应,这可能导致扫描失败。此约束旨在减少扫描期间的内存消耗。

以下是一个日志示例,其中 DAST 阻止了在 https://example.com/large.js 发现的 JavaScript 文件,因为其大小超过了限制:

2022-12-05T06:28:43.093 WRN BROWS response body exceeds allowed size allowed_size_bytes=1000000 browser_id=752944257619431212 nav_id=ae23afe2acbce2c537657a9112926f1a of=1 request_id=interception-job-2.0 response_size_bytes=9333408 step=1 url=https://example.com/large.js
2022-12-05T06:28:58.104 WRN CONTA request failed, attempting to continue scan error=net::ERR_BLOCKED_BY_RESPONSE index=0 requestID=38.2 url=https://example.com/large.js

这可以通过配置 DAST_PAGE_MAX_RESPONSE_SIZE_MB 更改。例如,

include:
  - template: DAST.gitlab-ci.yml

dast:
  variables:
    DAST_PAGE_MAX_RESPONSE_SIZE_MB: "25"

爬虫未达到预期页面

尝试禁用缓存

如果 DAST 错误地缓存了您的应用程序页面,可能导致 DAST 无法正确地爬虫您的应用程序。如果您发现一些页面未被爬虫意外找到,请尝试设置 DAST_USE_CACHE: "false" 变量以查看是否有帮助。请注意,这可能会显著降低扫描的性能。确保仅在绝对必要时禁用缓存。如果您有订阅,请创建支持票以调查缓存阻止您的网站被爬虫的原因。

直接指定目标路径

爬虫通常从定义的目标 URL 开始,并尝试通过与网站交互找到更多页面。但是,有两种方式可以直接为爬虫指定路径:

  1. 使用 sitemap.xml:Sitemap 是一个定义良好的协议,用于指定网站中的页面。DAST 的爬虫会在 <target URL>/sitemap.xml 寻找 sitemap.xml 文件,并将所有指定的 URL 作为爬虫的起始点。Sitemap Index 文件不受支持。
  2. 使用 DAST_TARGET_PATHS:此配置变量允许指定爬虫的输入路径。例如:DAST_TARGET_PATHS: /,/page/1.html,/page/2.html

确保请求未被阻止

默认情况下,DAST 仅允许请求目标 URL 的域。如果您的网站向目标之外的域发出请求,请使用 DAST_SCOPE_ALLOW_HOSTS 指定这些主机。例如:”example.com” 向 “auth.example.com” 发出身份验证请求以更新身份验证令牌。由于域未被允许,请求被阻止,爬虫无法找到新页面。