DAST 基于浏览器的分析器

  • 引入于 13.12 版本,作为 Beta 功能。
  • 一般可用于 15.7 版本(DAST v3.0.50)。
caution 不要对生产服务器运行 DAST 扫描。它不仅可以执行用户可以执行的任何功能,例如单击按钮或提交表单,而且还可能触发错误,导致生产数据被修改或丢失。仅对测试服务器运行 DAST 扫描。

基于浏览器的 DAST 分析器由极狐GitLab 构建,用于扫描现代 Web 应用程序的漏洞。 扫描在浏览器中运行,优化严重依赖 JavaScript 的测试应用程序,例如单页应用程序。 有关详细信息,请参阅DAST 如何扫描应用程序

要将分析器添加到您的 CI/CD 流水线,请参阅开始使用

DAST 如何扫描应用程序

扫描执行以下步骤:

  1. 身份验证。
  2. 爬取目标应用程序,通过执行用户操作(例如跟踪链接、单击按钮和填写表单)来发现应用程序的表面区域。
  3. 被动扫描搜索在抓取时发现的 HTTP 消息和页面中的漏洞。
  4. 主动扫描通过在抓取阶段记录的 HTTP 请求中注入负载来搜索漏洞。

爬取应用程序

“导航”是用户可能在页面上执行的操作,例如单击按钮、单击锚点链接、打开菜单项或填写表单。 “导航路径”是表示用户可能如何遍历应用程序的一系列导航动作。 DAST 通过爬取页面和内容并识别导航路径,来发现应用程序的表面区域。

爬取是使用包含一个导航的导航路径初始化的,该导航在专门检测的 Chromium 浏览器中加载目标应用程序 URL。 DAST 然后爬取导航路径,直到所有路径都被爬取。

为了爬取导航路径,DAST 打开一个浏览器窗口,并指示它执行导航路径中的所有导航操作。 当浏览器完成加载最终操作的结果时,DAST 检查页面以查找用户可能执行的操作,为每个找到的操作创建一个新导航,并将它们添加到导航路径以形成新的导航路径。例如:

  1. DAST 处理导航路径 LoadURL[https://example.com]
  2. DAST 找到两个用户操作,LeftClick[class=menu]LeftClick[id=users]
  3. DAST 创建了两个新的导航路径,LoadURL[https://example.com] -> LeftClick[class=menu]LoadURL[https://example.com] -> LeftClick[id=users]
  4. 在两条新的导航路径上开始爬取。

一个 HTML 元素存在于应用程序的多个位置是很常见的,例如在每个页面上都可见的菜单。 重复的元素可能会导致爬虫再次爬取相同的页面或陷入循环。 DAST 使用基于 HTML 属性的元素唯一性计算来丢弃它之前抓取的新导航操作。

被动扫描

被动扫描检查在扫描的爬取阶段发现的页面中的漏洞。 默认情况下启用被动扫描。

这些检查会在 HTTP 消息、cookie、存储事件、控制台事件和 DOM 中搜索漏洞。 被动检查的示例包括搜索暴露的信用卡、暴露的 secret 令牌、丢失的内容安全策略以及重定向到不受信任的位置。

主动扫描

主动扫描通过将攻击负载注入扫描爬取阶段记录的 HTTP 请求来检查漏洞。 由于探测攻击的性质,默认情况下禁用主动扫描。

DAST 分析每个记录的 HTTP 请求的注入位置,例如查询值、header 值、cookie 值、表单 posts 和 JSON 字符串值。 攻击载荷被注入到注入位置,形成一个新的请求。 DAST 将请求发送到目标应用程序并使用 HTTP 响应来确定攻击是否成功。

主动扫描运行两种类型的主动检查:

  • 匹配响应攻击分析响应内容以确定攻击成功。例如,攻击试图读取系统密码文件,则当响应正文包含密码文件的证据时,就会创建一个调查结果。
  • 定时攻击使用响应时间来确定攻击成功与否。例如,攻击试图强制目标应用程序休眠,则当应用程序响应时间比休眠时间长时,就会创建一个结果。定时攻击使用不同的攻击有效载荷重复多次,以最大限度地减少误报。

简化的定时攻击的工作原理如下:

  1. 爬取阶段记录 HTTP 请求 https://example.com?search=people
  2. DAST 分析 URL,找到一个 URL 参数注入位置 https://example.com?search=[INJECT]
  3. 主动检查定义了一个有效负载,sleep 10,它试图让 Linux 主机进入睡眠状态。
  4. DAST 向目标应用程序发送一个新的 HTTP 请求,其中注入了有效载荷 https://example.com?search=sleep%2010
  5. 如果目标应用程序将查询参数值作为未经验证的系统命令执行,则目标应用程序存在漏洞,例如,system(params[:search])
  6. 如果响应时间超过 10 秒,DAST 会创建一个结果。

开始使用

要运行 DAST 扫描:

  • 阅读运行 DAST 扫描的先决条件
  • 在您的 CI/CD 流水线中创建一个 DAST 作业
  • 如果您的应用程序需要,作为用户进行身份验证。

创建 DAST CI/CD 作业

  • 此模板更新到 DAST_VERSION: 2 于 14.0 版本。
  • 此模板更新到 DAST_VERSION: 3 于 15.0 版本。

要将 DAST 扫描添加到您的应用程序,请使用极狐GitLab DAST CI/CD 模板文件中定义的 DAST 作业。模板的更新随极狐GitLab 升级一起提供,使您可以从任何改进和添加中受益。

创建 CI/CD 作业:

  1. 包括适当的 CI/CD 模板:

    caution 最新版本的模板可能包含重大更改。除非您需要仅在最新模板中提供的功能,否则请使用稳定模板。
  1. 在极狐GitLab CI/CD 阶段配置中添加一个 dast 阶段。

  2. 使用以下方法之一定义 DAST 扫描的 URL:

    • 设置 DAST_WEBSITE CI/CD 变量。如果设置,则此值优先。

    • 在项目根目录下的 environment_url.txt 文件中添加 URL 非常适合在动态环境中进行测试。要针对在极狐GitLab CI/CD 流水线期间动态创建的应用程序运行 DAST,请将应用程序 URL 写入 environment_url.txt 文件。DAST 自动读取 URL 找到扫描目标。

      您可以在 Auto DevOps CI YAML 中看到一个示例

  3. DAST_BROWSER_SCAN CI/CD 变量设置为 true

例如:

stages:
  - build
  - test
  - deploy
  - dast

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

dast:
  variables:
    DAST_WEBSITE: "https://example.com"
    DAST_BROWSER_SCAN: "true"

可用的 CI/CD 变量

以下 CI/CD 变量特定于基于浏览器的 DAST 分析器。它们可用于根据您的要求自定义 DAST 的行为。

CI/CD 变量 类型 示例 描述
DAST_ADVERTISE_SCAN boolean true 设置为 true,向每个发送的请求添加 Via 标头,宣传该请求是作为 DAST 扫描的一部分发送的。引入于 14.1 版本。
DAST_BROWSER_ACTION_STABILITY_TIMEOUT 持续时间字符串 800ms 完成操作后,等待浏览器开始加载页面并准备好进行分析的最长时间。
DAST_BROWSER_ACTION_TIMEOUT 持续时间字符串 7s 等待浏览器完成操作的最长时间。
DAST_BROWSER_ALLOWED_HOSTS 字符串列表 site.com,another.com 爬取时,此变量中包含的主机名被视为在范围内。默认情况下,DAST_WEBSITE 主机名包含在允许的主机列表中。使用 DAST_REQUEST_HEADERS 设置的 header 会添加到对这些主机名发出的每个请求中。
DAST_BROWSER_COOKIES dictionary abtesting_group:3,region:locked 要添加到每个请求的 cookie 名称和值。
DAST_BROWSER_CRAWL_GRAPH boolean true 设置为 true,生成在扫描的爬取阶段访问的导航路径的 SVG 图。您还必须将 gl-dast-crawl-graph.svg 定义为 CI 作业产物,以便能够访问生成的图。
DAST_BROWSER_CRAWL_TIMEOUT 持续时间字符串 5m 等待扫描的爬网阶段完成的最长时间。默认为 24h
DAST_BROWSER_DEVTOOLS_LOG string Default:messageAndBody,truncate:2000 设置为记录 DAST 和 Chromium 浏览器之间的协议消息。
DAST_BROWSER_DOM_READY_AFTER_TIMEOUT 持续时间字符串 200ms 定义在检查页面是否稳定之前等待 DOM 更新的时间。默认为 500ms
DAST_BROWSER_ELEMENT_TIMEOUT 持续时间字符串 600ms 在确定元素已准备好进行分析之前,等待元素的最长时间。
DAST_BROWSER_EXCLUDED_ELEMENTS selector a[href='2.html'],css:.no-follow 扫描时忽略的逗号分隔的选择器列表。
DAST_BROWSER_EXCLUDED_HOSTS strings 列表 site.com,another.com 此变量中包含的主机名被视为已排除,连接将被强制删除。
DAST_BROWSER_EXTRACT_ELEMENT_TIMEOUT 持续时间字符串 5s 允许浏览器提取新发现的元素或导航的最长时间。
DAST_BROWSER_FILE_LOG strings 列表 brows:debug,auth:debug 模块列表及其在文件日志中使用的预期日志记录级别。
DAST_BROWSER_FILE_LOG_PATH string /output/browserker.log 设置为文件日志的路径。
DAST_BROWSER_IGNORED_HOSTS strings 列表 site.com,another.com 此变量中包含的主机名被访问,未被攻击,也未被报告。
DAST_BROWSER_INCLUDE_ONLY_RULES strings 列表 16.1,16.2,16.3 用于扫描的以逗号分隔的检查标识符列表。
DAST_BROWSER_LOG strings 列表 brows:debug,auth:debug 在控制台日志中使用的模块列表及其预期的日志记录级别。
DAST_BROWSER_LOG_CHROMIUM_OUTPUT boolean true 设置为 true,记录 Chromium 的 STDOUTSTDERR
DAST_BROWSER_MAX_ACTIONS number 10000 爬虫执行的最大操作数。例如,选择链接或填写表格。
DAST_BROWSER_MAX_DEPTH number 10 爬虫执行的最大链式操作数。例如,Click -> Form Fill -> Click 的深度为三。
DAST_BROWSER_MAX_RESPONSE_SIZE_MB number 15 HTTP 响应主体的最大大小。主体大于此大小的响应会被浏览器阻止。默认为 10 MB。
DAST_BROWSER_NAVIGATION_STABILITY_TIMEOUT 持续时间字符串 7s 导航完成后,等待浏览器开始加载页面并准备好进行分析的最长时间。
DAST_BROWSER_NAVIGATION_TIMEOUT 持续时间字符串 15s 等待浏览器从一个页面导航到另一个页面的最长时间。
DAST_BROWSER_NUMBER_OF_BROWSERS number 3 要使用的最大并发浏览器实例数。对于 SaaS 上的共享 runner,我们建议最多三个。拥有更多资源的私人 runner 可能会受益于更高的数量,但在 5 到 7 个实例之后效果不显著。
DAST_BROWSER_PAGE_LOADING_SELECTOR selector css:#page-is-loading 选择器在页面上不再可见时,向分析器指示页面已完成加载并且可以继续扫描。不能与 DAST_BROWSER_PAGE_READY_SELECTOR 一起使用。
DAST_BROWSER_PAGE_READY_SELECTOR selector css:#page-is-ready 选择器,当检测到页面上可见时,向分析器指示页面已完成加载并且可以继续扫描。不能与 DAST_BROWSER_PAGE_LOADING_SELECTOR 一起使用。
DAST_BROWSER_PASSIVE_CHECK_WORKERS int 5 并行被动扫描的 worker 数量。建议设置为可用 CPU 的数量。
DAST_BROWSER_SCAN boolean true 需要为 true,才能运行基于浏览器的扫描。
DAST_BROWSER_SEARCH_ELEMENT_TIMEOUT 持续时间字符串 3s 允许浏览器搜索新元素或用户操作的最长时间。
DAST_BROWSER_STABILITY_TIMEOUT 持续时间字符串 7s 等待浏览器开始页面加载并准备好进行分析的最长时间。
DAST_EXCLUDE_RULES string 10020,10026 设置为逗号分隔的 ZAP 漏洞规则 ID 列表,以排除它们在扫描期间运行。规则 ID 是数字,可以从 DAST 日志或 ZAP 项目中找到。
DAST_EXCLUDE_URLS URLs https://example.com/.*/sign-out 在经过身份验证的扫描期间要跳过的 URL,按逗号分隔。正则表达式语法可用于匹配多个 URL,例如,.* 匹配任意字符序列。
DAST_FF_ENABLE_BAS boolean true 在此 DAST 扫描期间设置为 true启用入侵和攻击模拟
DAST_FULL_SCAN_ENABLED boolean true 设置为 true,同时运行被动和主动检查。默认值:false
DAST_PATHS string /page1.html,/category1/page3.html 设置为以逗号分隔的相对于 DAST_WEBSITE 的 URL 路径列表,供 DAST 扫描。
DAST_PATHS_FILE string /builds/project/urls.txt 设置为包含相对于 DAST 扫描的 DAST_WEBSITE 的 URL 路径列表的文件路径。该文件必须是纯文本,每行一个路径。
DAST_PKCS12_CERTIFICATE_BASE64 string ZGZkZ2p5NGd... PKCS12 证书用于需要双向 TLS 的站点。必须编码为 base64 文本。
DAST_PKCS12_PASSWORD string password DAST_PKCS12_CERTIFICATE_BASE64 中使用的证书的密码。使用 UI 创建敏感的自定义 CI/CI 变量
DAST_REQUEST_HEADERS string Cache-control:no-cache 设置为以逗号分隔的请求标头名称和值列表。
DAST_SKIP_TARGET_CHECK boolean true 设置为 true,防止 DAST 在扫描之前检查目标是否可用。默认值:false
DAST_TARGET_AVAILABILITY_TIMEOUT number 60 等待目标可用性的时间限制(以秒为单位)。
DAST_WEBSITE URL https://example.com 要扫描的网站的 URL。
SECURE_ANALYZERS_PREFIX URL registry.organization.com 设置从中下载分析器的 Docker 镜像库基础地址。

漏洞检测

漏洞检测正逐渐从默认的 Zed Attack Proxy (ZAP) 解决方案迁移到基于浏览器的分析器。

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

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

管理扫描时间

与普通的极狐GitLab DAST 解决方案相比,运行基于浏览器的爬虫有望更好地覆盖许多 Web 应用程序。这可能会以增加扫描时间为代价。

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

  • 通过变量 DAST_BROWSER_NUMBER_OF_BROWSERS 垂直扩展 runner 并使用更多浏览器。默认值为 3
  • 使用 DAST_BROWSER_MAX_ACTIONS 变量限制浏览器执行的操作数。默认值为 10,000
  • 限制基于浏览器的爬虫将使用 DAST_BROWSER_MAX_DEPTH 变量检查覆盖范围的页面深度。爬虫采用广度优先的搜索策略,所以深度较小的页面会先被爬取。默认值为 10
  • 使用变量 DAST_BROWSER_CRAWL_TIMEOUT 限制抓取目标应用程序所需的时间。默认值为 24h。当爬取超时时,扫描会继续进行被动和主动检查。
  • 使用变量 DAST_BROWSER_CRAWL_GRAPH 构建抓取图,用于查看正在抓取的页面。
  • 使用变量 DAST_EXCLUDE_URLS 阻止页面被抓取。
  • 使用变量 DAST_BROWSER_EXCLUDED_ELEMENTS 阻止选择元素。请谨慎使用,因为定义此变量会导致对每个已爬网页面进行额外查找。
  • 如果目标应用程序具有最小或快速渲染,请考虑将变量 DAST_BROWSER_DOM_READY_AFTER_TIMEOUT 减少到较小的值。默认值为 500ms

超时

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

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

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

还可以配置稳定性超时,例如可使用 DAST_BROWSER_NAVIGATION_STABILITY_TIMEOUTDAST_BROWSER_STABILITY_TIMEOUTDAST_BROWSER_ACTION_STABILITY_TIMEOUT 配置的超时。稳定性超时确定基于浏览器的扫描何时考虑页面已完全加载。基于浏览器的扫描会考虑在以下情况加载的页面:

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

    • DAST_BROWSER_NAVIGATION_STABILITY_TIMEOUTDAST_BROWSER_STABILITY_TIMEOUTDAST_BROWSER_ACTION_STABILITY_TIMEOUT 持续时间后,没有新的文档对象模型 (DOM) 修改事件。

这些事件发生后,基于浏览器的扫描会认为页面已加载并准备就绪,然后尝试下一步操作。

如果您的应用程序遇到延迟或返回许多导航失败,请考虑调整超时值,如本例所示:

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

dast:
  variables:
    DAST_WEBSITE: "https://my.site.com"
    DAST_BROWSER_NAVIGATION_TIMEOUT: "25s"
    DAST_BROWSER_ACTION_TIMEOUT: "10s"
    DAST_BROWSER_STABILITY_TIMEOUT: "15s"
    DAST_BROWSER_NAVIGATION_STABILITY_TIMEOUT: "15s"
    DAST_BROWSER_ACTION_STABILITY_TIMEOUT: "3s"
note 调整这些值可能会影响扫描时间,因为它们会调整每个浏览器等待各种活动完成的时间。