管理范围

范围控制 DAST 在抓取目标应用程序时跟随哪些 URL。正确管理范围可以缩短扫描运行时间,同时确保仅检查目标应用程序的漏洞。

范围类型

范围有三种类型:

  • 在范围内
  • 超出范围
  • 从范围中排除

在范围内

DAST 会跟随范围内的 URL,并在 DOM 中搜索后续操作以继续抓取。记录的范围内 HTTP 消息会被被动检查漏洞,并在运行全面扫描时用于构建攻击。

超出范围

DAST 会跟随超出范围的 URL,用于非文档内容类型,如图片、样式表、字体、脚本或 AJAX 请求。除了搜索信息泄露的被动检查外,记录的超出范围 URL 的 HTTP 消息不会被检查漏洞。

从范围中排除

DAST 不会跟随从范围中排除的 URL。除了搜索信息泄露的被动检查外,记录的从范围中排除的 URL 的 HTTP 消息不会被检查漏洞。

在认证期间范围的不同工作方式

许多目标应用程序的认证过程依赖于外部网站,例如使用身份访问管理提供商进行单点登录 (SSO)。为了确保 DAST 能够与这些提供商进行认证,DAST 会在认证期间跟随超出范围的 URL 进行完整页面加载。DAST 不会跟随从范围中排除的 URL。

DAST 如何阻止 HTTP 请求

DAST 指示浏览器在由于范围规则而阻止请求时,像往常一样发出 HTTP 请求。随后请求会被拦截并以 BlockedByClient 原因被拒绝。这种方法允许 DAST 记录 HTTP 请求,同时确保请求永远不会到达目标服务器。被动检查(例如 200.1)使用这些记录的请求来验证发送到外部主机的信息。

如何配置范围

默认情况下,匹配目标应用程序主机的 URL 被视为在范围内。所有其他主机被视为超出范围。

范围通过以下变量进行配置:

  • 使用 DAST_SCOPE_ALLOW_HOSTS 添加在范围内的主机。
  • 使用 DAST_SCOPE_IGNORE_HOSTS 添加到超出范围的主机。
  • 使用 DAST_SCOPE_EXCLUDE_HOSTS 添加到从范围中排除的主机。
  • 使用 DAST_SCOPE_EXCLUDE_URLS 设置特定 URL 以从范围中排除。

规则:

  • 排除主机优先于忽略主机,忽略主机优先于允许主机。
  • 为主机配置范围不配置该主机的子域范围。
  • 为主机配置范围不配置该主机的所有端口范围。

以下可能是一个典型配置:

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

dast:
  variables:
    DAST_TARGET_URL: "https://my.site.com"                   # my.site.com URLs are considered in-scope by default
    DAST_SCOPE_ALLOW_HOSTS: "api.site.com:8443"       # include the API as part of the scan
    DAST_SCOPE_IGNORE_HOSTS: "analytics.site.com"      # explicitly disregard analytics from the scan
    DAST_SCOPE_EXCLUDE_HOSTS: "ads.site.com"           # don't visit any URLs on the ads subdomain
    DAST_SCOPE_EXCLUDE_URLS: "https://my.site.com/user/logout"  # don't visit this URL

漏洞检测

DAST 通过我们的全面基于浏览器的漏洞检查检测漏洞。这些检查在扫描期间识别您的 Web 应用程序中的安全问题。

抓取器在浏览器中运行目标网站,并配置 DAST 作为代理服务器。这确保浏览器发出的所有请求和响应都被 DAST 被动扫描。运行全面扫描时,DAST 执行的主动漏洞检查不使用浏览器。这种检查漏洞的方式差异可能导致某些功能需要禁用以确保扫描按预期工作。

例如,对于包含反 CSRF 令牌的目标网站,被动扫描按预期工作,因为浏览器会显示页面和表单,就像用户在查看页面一样。然而,运行全面扫描的主动漏洞检查无法提交包含反 CSRF 令牌的表单。在这种情况下,我们建议您在运行全面扫描时禁用反 CSRF 令牌。

管理扫描时间

预计使用基于浏览器的抓取器对许多 Web 应用程序的覆盖率更好,与标准极狐GitLab DAST 解决方案相比。这可能会导致扫描时间增加。

您可以通过以下措施管理覆盖率与扫描时间之间的权衡:

  • 垂直扩展 runner,并使用更高数量的浏览器和 变量 DAST_CRAWL_WORKER_COUNT。默认情况下,动态设置为可用逻辑 CPU 的数量。
  • 使用 变量 DAST_CRAWL_MAX_ACTIONS 限制浏览器执行的操作数量。默认值为 10,000
  • 使用 变量 DAST_CRAWL_MAX_DEPTH 限制浏览器抓取器检查覆盖率的页面深度。抓取器使用广度优先搜索策略,因此首先抓取较小深度的页面。默认值为 10
  • 使用 变量 DAST_CRAWL_TIMEOUT 限制抓取目标应用程序的时间。默认值为 24h。当抓取器超时时,扫描继续进行被动和主动检查。
  • 使用 变量 DAST_CRAWL_GRAPH 构建抓取图,查看正在抓取的页面。
  • 使用 变量 DAST_SCOPE_EXCLUDE_URLS 防止页面被抓取。
  • 使用 变量 DAST_SCOPE_EXCLUDE_ELEMENTS 防止元素被选择。谨慎使用,因为定义此变量会导致每个抓取页面进行额外查找。
  • 如果目标应用程序渲染速度较快或较小,请考虑将 变量 DAST_PAGE_DOM_STABLE_WAIT 降低到较小的值。默认值为 500ms

超时

由于网络条件不佳或应用程序负载繁重,默认超时可能不适用于您的应用程序。

基于浏览器的扫描提供了调整各种超时的功能,以确保在从一个页面过渡到另一个页面时继续顺利。这些值使用 Duration 字符串配置,允许您使用前缀配置持续时间:m 表示分钟,s 表示秒,ms 表示毫秒。

导航或加载新页面的行为通常需要最多的时间,因为它们正在加载多个新资源,例如 JavaScript 或 CSS 文件。根据这些资源的大小或返回速度,默认 DAST_PAGE_READY_AFTER_NAVIGATION_TIMEOUT 可能不够。

稳定性超时,例如可配置的 DAST_PAGE_DOM_READY_TIMEOUTDAST_PAGE_READY_AFTER_ACTION_TIMEOUT,也可以配置。稳定性超时确定基于浏览器的扫描何时认为页面完全加载。基于浏览器的扫描认为页面加载完成的条件是:

  1. DOMContentLoaded 事件已触发。
  2. 没有打开或未完成的请求被视为重要,例如 JavaScript 和 CSS。媒体文件通常被视为不重要。
  3. 根据浏览器是否执行了导航、被强制过渡或动作:

    • DAST_PAGE_DOM_READY_TIMEOUTDAST_PAGE_READY_AFTER_ACTION_TIMEOUT 持续时间后,没有新的 DOM 修改事件。

这些事件发生后,基于浏览器的扫描认为页面加载完成并准备好,并尝试下一步动作。

如果您的应用程序出现延迟或返回许多导航失败,请考虑调整超时值,例如以下示例:

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

dast:
  variables:
    DAST_TARGET_URL: "https://my.site.com"
    DAST_PAGE_READY_AFTER_NAVIGATION_TIMEOUT: "45s"
    DAST_PAGE_READY_AFTER_ACTION_TIMEOUT: "15s"
    DAST_PAGE_DOM_READY_TIMEOUT: "15s"

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

调整这些值可能会影响扫描时间,因为它们调整每个浏览器等待各种活动完成的时间。

{{< /alert >}}

页面准备超时

页面准备是指页面完全加载完成、其 DOM 已稳定且交互元素可用的状态。正确的页面准备检测对于以下方面至关重要:

  • 扫描准确性:在页面完全加载前分析页面可能会遗漏内容或产生误判。
  • 抓取效率:等待时间过长会浪费扫描时间,而等待时间不够会遗漏动态内容。
  • 现代 Web 应用程序支持:单页应用程序、AJAX 密集型网站和渐进加载模式需要复杂的准备检测。

使用一系列可选可配置超时,DAST 扫描器可以检测页面的不同部分何时完全加载。

超时变量

使用以下 CI/CD 变量自定义 DAST 页面准备超时。有关详细列表,请参阅 可用 CI/CD 变量

超时变量 默认值 描述
DAST_PAGE_READY_AFTER_NAVIGATION_TIMEOUT 15s 浏览器从一个页面导航到另一个页面的最长等待时间。在文档加载阶段用于完整页面加载。
DAST_PAGE_READY_AFTER_ACTION_TIMEOUT 7s 浏览器认为页面已加载并准备分析的最长等待时间。在不触发完整页面加载的页面内操作中替代 DAST_PAGE_READY_AFTER_NAVIGATION_TIMEOUT
DAST_PAGE_DOM_STABLE_WAIT 500ms 定义在检查页面稳定之前等待 DOM 更新的时间。用于客户端渲染阶段开始时。
DAST_PAGE_DOM_READY_TIMEOUT 6s 浏览器在导航完成后认为页面已加载并准备分析的最长等待时间。控制等待后台数据获取和 DOM 渲染。
DAST_PAGE_IS_LOADING_ELEMENT 当页面上不再可见时,指示分析器页面已加载完成,扫描可以继续的选择器。标志客户端渲染过程结束。

页面加载工作流程

现代 Web 应用程序以多个阶段加载。DAST 扫描器为过程中的每个步骤设置了特定超时:

  1. 文档加载:浏览器获取并处理基本页面结构。

    1. 从服务器获取 HTML 内容。
    2. 加载引用的 CSS 和 JavaScript 文件。
    3. 解析内容并渲染初始页面。
    4. 触发标准 “document ready” 事件。

    此阶段使用 DAST_PAGE_READY_AFTER_NAVIGATION_TIMEOUT (用于完整页面加载)或 DAST_PAGE_READY_AFTER_ACTION_TIMEOUT (用于页面内操作),设置文档加载的最长等待时间。

  2. 客户端渲染:在初始加载后,许多单页应用程序:

    • 执行初始 JavaScript 执行 (DAST_PAGE_DOM_STABLE_WAIT)。
    • 使用 AJAX 或其他 API 调用获取后台数据。
    • 渲染 DOM 并基于获取的数据进行更新 (DAST_PAGE_DOM_READY_TIMEOUT)。
    • 显示页面加载指示器 (DAST_PAGE_IS_LOADING_ELEMENT)。

    扫描器监控这些活动以确定页面何时准备好进行交互。

以下图表展示了抓取页面时使用的顺序超时:

%%{init: { "gantt": { "leftPadding": 250, "sectionFontSize": 15, "topPadding": 40, "fontFamily": "GitLab Sans" } }}%% gantt dateFormat YYYY-MM-DD axisFormat section Document load DAST_PAGE_READY_AFTER_NAVIGATION_TIMEOUT :done, nav1, 2024-01-01, 6d Fetch HTML :active, nav1, 2024-01-01, 3d Fetch CSS&JS :active, nav1, 2024-01-04, 3d DocumentReady :milestone, nav1, 2024-01-07, 0d section Load Data / Client-side render DAST_PAGE_DOM_STABLE_WAIT :done, dom1, 2024-01-07, 3d Initial JS Execution :active, dom1, 2024-01-07, 3d DAST_PAGE_DOM_READY_TIMEOUT :done, ready1, 2024-01-10, 4d Fetch Data :active, dom1, 2024-01-10, 2d Render DOM :active, dom1, 2024-01-10, 2d DAST_PAGE_IS_LOADING_ELEMENT :milestone, load1, 2024-01-14, 0d