开源Docker镜像安全审计实战:从漏洞扫描到权限最小化配置

发布时间:2026/6/30 4:19:45

开源Docker镜像安全审计实战:从漏洞扫描到权限最小化配置 1. 项目概述为什么开源镜像的安全审计刻不容缓最近在整理内部开发环境时发现团队里不少同事为了图方便直接从一些公共仓库拉取未经审计的第三方Docker镜像来部署测试服务。问起来大家的理由都差不多“这是某某大厂开源的镜像版本号也对得上应该没问题吧” 直到有一次一个用于数据处理的Python服务镜像被安全团队扫出了好几个高危的CVE漏洞其中一个甚至能导致容器逃逸我们才惊出一身冷汗。这件事让我意识到对于“Nunchaku-FLUX.1-dev”这类开源项目镜像光看名字和来源是远远不够的必须有一套系统性的安全审计流程。“Nunchaku-FLUX.1-dev”听起来像是一个特定版本的开源项目或工具链的Docker镜像。开源镜像的安全问题远比我们想象的要复杂。它不仅仅是“这个镜像里有没有病毒”那么简单而是一个立体的风险集合上游基础镜像可能自带漏洞项目引入的第三方依赖包比如Python的pip包、Node.js的npm包版本可能过时且含有已知漏洞镜像的构建过程和运行时配置可能违背了“权限最小化”原则为攻击者留下了后门。这次要聊的就是如何对这类镜像进行一次从里到外的“体检”核心就两件事依赖包漏洞扫描和权限最小化配置验证。这不仅是安全团队的职责更是每一位负责构建、部署和维护服务的工程师应该掌握的技能。2. 开源镜像安全审计的整体思路与核心目标给一个镜像做安全审计不能东一榔头西一棒子。我的思路是把它当成一次标准化的“外科手术”目标明确步骤清晰。整个审计过程可以拆解为三个层次由表及里层层深入。2.1 审计目标分层从软件供应链到运行时配置第一层是软件供应链安全。这是最基础也是风险最集中的一层。一个“Nunchaku-FLUX.1-dev”镜像可以看作一个软件供应链的终点。它依赖于一个基础镜像比如ubuntu:22.04或python:3.9-slim在此基础上项目通过包管理工具安装了一堆依赖。供应链上任何一个环节出问题都会污染最终产物。我们的目标就是确保基础镜像和所有显式安装的依赖包都不包含已知的、可被利用的中高危漏洞。第二层是镜像构建过程安全。这关注的是Dockerfile的编写是否安全。常见的坏习惯包括使用root用户运行应用、将敏感信息如密钥硬编码在镜像层中、不必要的apt-get upgrade这会导致镜像层无法被稳定缓存且可能引入不兼容的更新。审计这一层就是为了确保构建过程本身没有引入安全反模式。第三层也是最能体现“防御纵深”的一层是运行时安全配置。镜像最终要跑在容器里容器的安全配置决定了攻击面的大小。这包括容器是否以特权模式运行、是否挂载了敏感的主机目录、是否配置了AppArmor或Seccomp安全配置文件、运行的用户是否非root、文件系统是否只读等。权限最小化验证主要就是针对这一层。2.2 工具链选型自动化与手动检查的结合基于以上目标纯靠人眼检查Dockerfile和docker inspect输出是不现实的必须借助工具。我的工具链选型原则是核心扫描自动化深度分析手动化。对于依赖包漏洞扫描自动化工具是绝对主力。我主要使用Trivy和Grype。为什么选它们Trivy由Aqua Security开发速度快数据库更新及时对OS包apt, apk, yum和语言包pip, npm, go mod等的支持都非常好而且输出格式友好。Grype是Anchore公司Syft工具链的一部分同样优秀有时在特定漏洞的检测上可以和Trivy互为补充。我通常会先用Trivy做全面快速扫描对于它报告的高危项再用Grype进行二次确认避免误报。对于权限最小化配置验证情况更复杂一些。有像Docker Bench for Security这样的自动化检查脚本它基于CIS Docker Benchmark标准能检查主机和容器的上百项配置。然而自动化工具无法理解业务上下文。比如它可能会警告“容器未设置内存限制”但对于一个简单的测试服务这可能不是问题反之它可能检查不出一个容器是否不必要地挂载了/var/run/docker.sock这极其危险。因此这一层需要自动化工具初筛 基于Dockerfile和运行命令的手动复核。注意工具只是辅助真正的安全审计需要审计者具备安全知识和业务理解。工具报告出的“问题”需要结合镜像的实际用途来评估风险等级决定是必须修复、可以缓解还是可以接受。2.3 审计流程设计四步闭环我设计的审计流程是一个四步闭环确保没有遗漏信息收集获取目标镜像nunchaku-flux.1-dev:latest的Dockerfile和实际镜像文件。如果没有Dockerfile需先逆向分析或联系维护者获取。静态扫描对镜像文件进行依赖包漏洞扫描Trivy/Grype对Dockerfile进行安全反模式检查可使用hadolint这类Dockerfile linter。动态验证基于Dockerfile或审计后的Dockerfile重新构建镜像并以最小权限方式运行容器检查其运行状态和配置使用docker inspect和docker exec进入容器查看。报告与修复汇总所有发现评估风险提出具体的修复建议如升级某个包、修改Dockerfile中的USER指令、添加安全上下文约束并跟踪修复情况。3. 核心细节解析依赖包漏洞扫描的实战要点依赖包漏洞扫描听起来就是一条命令的事但要想扫得准、扫得全、分析得透里面有不少门道。以“Nunchaku-FLUX.1-dev”镜像为例我们一步步拆解。3.1 获取与解析镜像的软件物料清单SBOM扫描的前提是知道镜像里有什么。这就需要生成软件的物料清单。我强烈推荐在扫描前先用Syft为镜像生成一份详细的SBOM。这能让你对镜像内容有一个全局视图。# 使用Syft生成镜像的SBOM输出为JSON格式 syft nunchaku-flux.1-dev:latest -o json sbom-nunchaku-flux.json查看这个JSON文件你可以清晰地看到镜像的分层结构每一层里包含了哪些操作系统包、哪些语言依赖包。这对于后续分析漏洞来源至关重要。比如你发现一个libssl的漏洞通过SBOM你可以立刻定位到这个包是来自基础镜像如ubuntu:22.04的第几层而不是项目自己安装的。3.2 使用Trivy进行深度漏洞扫描有了SBOM的宏观认识接下来就用Trivy进行微观的漏洞探测。这里有几个关键参数和场景需要掌握。基础扫描# 对镜像进行全面漏洞扫描 trivy image nunchaku-flux.1-dev:latest这条命令会输出一个表格按漏洞严重性CRITICAL, HIGH, MEDIUM, LOW列出所有找到的漏洞包括漏洞ID如CVE-2021-12345、关联的包、当前版本、修复版本等。进阶扫描与输出然而在CI/CD管道中或者需要进一步分析时我们需要更结构化的输出。# 输出为JSON格式便于后续工具处理 trivy image -f json -o trivy-report.json nunchaku-flux.1-dev:latest # 只显示严重性为CRITICAL和HIGH的漏洞 trivy image --severity CRITICAL,HIGH nunchaku-flux.1-dev:latest # 排除某些不想看到的漏洞类型谨慎使用 trivy image --ignore-unfixed nunchaku-flux.1-dev:latest--ignore-unfixed参数非常有用它只显示已有修复版本的漏洞。对于那些还没有官方补丁的漏洞告警了也无法立即解决在初期审计时可以先过滤掉专注于可行动项。实操心得扫描速度与数据库更新Trivy默认会使用本地漏洞数据库如果很久没更新扫描结果可能不准。在重要的审计任务前务必更新数据库trivy image --download-db-only另外第一次扫描一个较大的镜像可能会比较慢因为要下载漏洞数据库并分析各层。Trivy支持缓存后续扫描会快很多。在自动化流水线中可以考虑在单独的“扫描节点”上持久化Trivy的缓存目录。3.3 漏洞报告的分析与风险定级拿到一份密密麻麻的漏洞报告新手容易陷入恐慌。我的方法是分层定级聚焦可 exploitation可利用性。看严重性Severity优先处理CRITICAL和HIGH。但要注意工具判定的严重性是基于通用评分如CVSS不一定完全符合你的上下文。看漏洞状态是否有修复版本Fixed Version列如果有修复成本通常较低升级包版本。如果没有就需要考虑缓解措施。看影响范围这个漏洞影响的包在你的镜像里是核心依赖还是间接依赖这个包在运行时是否真的被加载和使用例如一个Python镜像里可能安装了binutils这样的系统工具包并存在漏洞但如果你的Python应用运行时根本不会调用它其实际风险就较低。看利用条件有些漏洞的利用需要网络访问权限如远程代码执行RCE有些则需要本地权限如权限提升。结合你容器的网络策略是否暴露端口和用户权限是否非root可以进一步判断风险。踩过的坑曾经遇到一个报告显示基础镜像里的glibc有一个HIGH级别漏洞。但修复版本需要升级到新的OS版本而这可能与当前镜像中的其他软件不兼容。最终评估认为该漏洞在容器化环境中被利用的条件极为苛刻且升级风险更大因此决定暂时接受风险但记录了决策原因并计划在下一个大的版本升级周期中解决。审计报告里不仅要记录问题更要记录风险评估和决策逻辑。4. 权限最小化配置验证的实操指南如果说漏洞扫描是“查毒”那么权限最小化配置验证就是“加固城墙”。一个即使没有已知漏洞的镜像如果以特权模式运行风险也是巨大的。这部分工作更需要手动介入和深度理解。4.1 Dockerfile安全反模式检查一切始于Dockerfile。一个安全的Dockerfile是构建安全镜像的基石。以下是我重点检查的几个方面并附上“坏例子”和“好例子”的对比。1. 用户上下文坚决不用root# 坏例子默认以root运行 FROM python:3.9 COPY . /app RUN pip install -r requirements.txt CMD [python, app.py] # 好例子创建非root用户并切换 FROM python:3.9-slim RUN groupadd -r appgroup useradd -r -g appgroup appuser WORKDIR /app COPY --chownappuser:appgroup . /app RUN pip install --no-cache-dir -r requirements.txt USER appuser CMD [python, app.py]为什么容器内的root用户虽然受到内核命名空间隔离但一旦有漏洞导致容器逃逸攻击者在主机上获得的权限就是容器内的用户权限。非root用户能极大增加攻击难度。2. 构建缓存与安全更新慎用apt-get upgrade# 有风险的例子upgrade破坏缓存并可能引入不稳定版本 FROM ubuntu:22.04 RUN apt-get update apt-get upgrade -y # 更好的例子仅安装必要的包并固定版本 FROM ubuntu:22.04 RUN apt-get update apt-get install -y --no-install-recommends \ package-a1.2.3 \ package-b4.5.6 \ rm -rf /var/lib/apt/lists/*为什么upgrade会尝试将所有包升级到最新这导致镜像层无法被稳定缓存因为仓库元数据在变且可能将经过测试的稳定环境升级到未经验证的新版本引入兼容性或新漏洞风险。通常应依赖基础镜像维护者提供的安全更新而非在构建时升级。3. 敏感信息绝不硬编码# 致命错误将密钥写在Dockerfile里 ENV API_KEYsupersecret123为什么Dockerfile和镜像层是明文存储的。任何能访问镜像仓库或镜像文件的人都能提取出密钥。密钥必须通过构建参数--build-arg在构建时传入或更常见的是在运行时通过环境变量或密钥管理服务如K8s Secrets注入。自动化检查工具可以使用hadolint对Dockerfile进行静态分析。hadolint Dockerfile它会提示很多最佳实践比如Always tag the version of an image explicitly总是指明基础镜像的具体标签而不是用latest。4.2 容器运行时安全配置验证即使Dockerfile写得完美运行时的配置也能“破功”。我们需要验证容器实际运行时的状态。1. 使用Docker Bench for Security进行基线检查这是一个脚本能快速检查主机和容器的配置是否符合CIS基准。# 下载并运行 git clone https://github.com/docker/docker-bench-security.git cd docker-bench-security sudo ./docker-bench-security.sh运行后它会输出大量检查项[PASS],[WARN],[INFO],[NOTE]。重点关注[WARN]项。例如它可能会警告“2.11 - Ensure that authorization for Docker client commands is enabled”应确保Docker客户端命令有授权机制。这对于生产主机是重要的但对于单个容器的安全配置审计我们更关注容器相关的部分输出中的第4、5部分。2. 手动深度检查关键配置自动化工具是很好的起点但深度审计必须手动检查几个核心项。假设我们已经以审计后的方式运行了容器docker run -d --name nunchaku-audit \ --user 1000:1000 \ # 指定非root用户UID/GID --read-only \ # 根文件系统只读 --tmpfs /tmp \ # 为需要可写的地方挂载tmpfs nunchaku-flux.1-dev:audited然后使用docker inspect进行验证# 检查是否以特权模式运行 docker inspect nunchaku-audit --format{{.HostConfig.Privileged}} # 期望输出false # 检查是否挂载了敏感的主机目录或socket docker inspect nunchaku-audit --format{{json .Mounts}} | jq . # 检查输出中是否有 /, /etc, /var/run/docker.sock 等危险挂载 # 检查运行用户 docker inspect nunchaku-audit --format{{.Config.User}} # 期望输出不是空或0:0而是像1000:1000或appuser:appgroup # 检查安全选项AppArmor, Seccomp docker inspect nunchaku-audit --format{{json .HostConfig.SecurityOpt}} | jq . # 期望看到非空的配置如[no-new-privileges:true]3. 网络与能力Capabilities检查Linux能力机制将root用户的特权细分成了几十种不同的能力。容器默认只拥有一个子集。但有些应用可能需要额外的能力如NET_ADMIN来配置网络。# 检查容器拥有的额外能力 docker inspect nunchaku-audit --format{{json .HostConfig.CapAdd}} | jq . # 理想情况下应为null或空数组。任何额外的能力都需要有明确的业务理由。原则是移除所有不必要的能力。Docker默认已经移除了很多但你可以通过--cap-dropALL --cap-add...来进一步收紧。实操心得只读根文件系统的挑战与解决--read-only是一个强大的安全特性能防止攻击者在容器内持久化恶意文件或篡改应用。但很多应用需要写入日志、缓存或临时文件。解决方案是使用--tmpfs挂载内存文件系统到/tmp,/run,/var/run等目录。使用-v卷挂载将特定的可写目录映射到主机或外部存储。 例如docker run --read-only --tmpfs /tmp --tmpfs /var/run ...。在审计时需要确认应用的所有必要写路径都得到了妥善处理否则容器会启动失败。5. 整合审计流程与生成可操作报告单点的扫描和检查必须整合成一个可重复、自动化的流程并且最终要产出对人友好的审计报告。我通常使用一个Shell脚本作为“胶水”将各个工具串联起来。5.1 自动化审计脚本示例以下是一个简化的审计脚本框架针对“nunchaku-flux.1-dev:latest”镜像#!/bin/bash set -euo pipefail IMAGE_NAMEnunchaku-flux.1-dev:latest AUDIT_DIR./audit_${IMAGE_NAME//[:\/]/_} REPORT_FILE${AUDIT_DIR}/final_report.md mkdir -p ${AUDIT_DIR} echo # 安全审计报告: ${IMAGE_NAME} ${REPORT_FILE} echo 审计日期: $(date) ${REPORT_FILE} echo ${REPORT_FILE} echo ## 1. 软件物料清单(SBOM) ${REPORT_FILE} syft ${IMAGE_NAME} -o json ${AUDIT_DIR}/sbom.json 21 || echo Syft执行失败 ${REPORT_FILE} echo SBOM已生成至: ${AUDIT_DIR}/sbom.json ${REPORT_FILE} echo ${REPORT_FILE} echo ## 2. 依赖包漏洞扫描结果 ${REPORT_FILE} echo ### 2.1 Trivy 扫描 ${REPORT_FILE} trivy image --severity CRITICAL,HIGH,MEDIUM -f json -o ${AUDIT_DIR}/trivy_report.json ${IMAGE_NAME} 21 | tail -20 ${REPORT_FILE} # 将JSON结果转换为简表并追加到报告 jq -r .Results[]? | select(.Vulnerabilities ! null) | .Target as $target | .Vulnerabilities[]? | [$target, .VulnerabilityID, .PkgName, .InstalledVersion, .FixedVersion, .Severity] | tsv ${AUDIT_DIR}/trivy_report.json ${AUDIT_DIR}/trivy_summary.tsv if [ -s ${AUDIT_DIR}/trivy_summary.tsv ]; then echo 发现漏洞汇总 ${REPORT_FILE} echo | 目标 | 漏洞ID | 包名 | 当前版本 | 修复版本 | 严重性 | ${REPORT_FILE} echo |------|--------|------|----------|----------|--------| ${REPORT_FILE} cat ${AUDIT_DIR}/trivy_summary.tsv | while IFS$\t read -r target vulid pkg curr fix sev; do echo | $target | $vulid | $pkg | $curr | ${fix:-N/A} | $sev | ${REPORT_FILE} done else echo 未发现中高危漏洞。 ${REPORT_FILE} fi echo ${REPORT_FILE} echo ## 3. Dockerfile安全分析 ${REPORT_FILE} # 假设Dockerfile在当前目录 if [ -f Dockerfile ]; then hadolint Dockerfile ${AUDIT_DIR}/hadolint.txt 21 echo Hadolint检查结果 ${REPORT_FILE} cat ${AUDIT_DIR}/hadolint.txt ${REPORT_FILE} else echo 警告未找到Dockerfile无法进行构建过程安全分析。 ${REPORT_FILE} fi echo ${REPORT_FILE} echo ## 4. 运行时配置检查 ${REPORT_FILE} # 这里简化实际应运行容器并检查。以下为示例命令输出。 echo 请手动验证以下项目 ${REPORT_FILE} echo - 容器是否以非root用户运行 ${REPORT_FILE} echo - 是否设置了 --read-only 或恰当的文件系统挂载 ${REPORT_FILE} echo - 是否移除了不必要的Linux能力--cap-drop ${REPORT_FILE} echo - 是否配置了安全计算模式Seccomp和AppArmor配置文件 ${REPORT_FILE} echo - 网络模式是否合理非host模式 ${REPORT_FILE} echo ${REPORT_FILE} echo ## 5. 修复建议汇总 ${REPORT_FILE} echo 根据以上扫描结果提出以下修复建议 ${REPORT_FILE} # 这里可以编写逻辑从trivy_report.json中提取有修复版本的漏洞自动生成升级建议。 # 例如 jq -r .Results[]? | select(.Vulnerabilities ! null) | .Vulnerabilities[]? | select(.FixedVersion ! null) | 升级 \(.PkgName) 从 \(.InstalledVersion) 到 \(.FixedVersion) (修复 \(.VulnerabilityID)) ${AUDIT_DIR}/trivy_report.json 2/dev/null | head -5 ${REPORT_FILE} || true echo ${REPORT_FILE} echo 审计完成。详细数据请查看 ${AUDIT_DIR} 目录。 ${REPORT_FILE} echo 报告已生成: ${REPORT_FILE}这个脚本将关键步骤串联并生成一个Markdown格式的初步报告。在实际工作中你可以将其集成到CI/CD流水线中在构建镜像后自动进行安全扫描并将报告归档或发送通知。5.2 报告解读与风险处置策略生成的报告不是终点而是起点。面对一份报告我们需要制定清晰的处置策略。我通常将发现的问题分为四类问题类型特征处置策略示例必须修复有可用补丁的高危/严重漏洞违反核心安全原则的配置如特权模式运行。立即阻断部署修复后重新审计。CVE-2021-12345 (CRITICAL, RCE)容器配置了--privileged。计划修复有修复版本的中危漏洞不影响当前功能但存在隐患的配置。纳入下一个迭代或版本计划设定修复截止日期。基础镜像中的某个库有MEDIUM级别漏洞升级基础镜像需验证兼容性。风险接受无修复版本的漏洞利用条件极其苛刻且缓解成本过高。记录接受原因由安全团队或项目负责人审批并持续监控。一个仅用于内部离线测试的镜像其漏洞需要复杂交互才能触发。误报/不适用工具误判漏洞存在于不使用的组件中。在审计报告中标注并说明理由。可考虑在扫描时添加忽略规则。扫描工具报告了一个Python包的漏洞但该包仅在构建阶段使用最终镜像中已不存在。最重要的步骤将处置决策和理由记录到审计报告中。这份报告不仅是技术清单更是团队的安全决策档案。下次再审计新版本时可以回顾之前的决策看是否有新的补丁发布或者风险环境是否发生了变化。6. 常见问题与排查技巧实录在实际操作中你肯定会遇到各种预料之外的情况。下面是我总结的几个典型问题及其解决方法。6.1 漏洞扫描相关问题1Trivy扫描速度慢或者卡住不动。可能原因网络问题导致漏洞数据库下载慢镜像层数非常多、非常大。排查与解决检查网络尝试trivy --download-db-only看是否能顺利更新数据库。使用缓存确保Trivy能使用缓存目录。可以设置环境变量TRIVY_CACHE_DIR指向一个持久化目录。离线扫描在内网环境可以搭建一个Trivy镜像库缓存服务器或者定期将漏洞数据库同步到本地。分析镜像考虑优化镜像本身比如使用更小的基础镜像Alpine, distroless合并RUN指令减少层数。问题2扫描报告显示基础镜像如ubuntu:22.04有大量漏洞不知如何下手。核心思路区分责任向上游追溯。操作步骤确认基础镜像标签确保你使用的是官方镜像的特定版本号如ubuntu:22.04而不是ubuntu:latest。latest标签是流动的今天和明天的漏洞状态可能不同无法稳定追踪。检查官方更新访问Docker Hub上该官方镜像的页面查看是否有更新的小版本如ubuntu:22.04sha256:...。官方会定期发布包含安全更新的新镜像。考虑更小基础镜像如果漏洞主要来自操作系统自带的非必要工具可以考虑切换到更精简的镜像如ubuntu:22.04-slim或debian:bullseye-slim甚至语言专用的官方镜像如python:3.9-slim。自行构建基础镜像对于极端安全要求可以基于一个干净的最小化OS自己控制所有包的安装和更新。但这会带来巨大的维护成本。问题3同一个漏洞被多个扫描工具报告但严重性不一致。原因不同工具使用的漏洞数据库NVD, Red Hat, Debian Security Tracker等和评分算法可能有细微差别。处理建议以最高严重性为准采取保守策略按最严重的那个评级来处理。手动核实根据漏洞ID如CVE-XXXX-XXXX去权威的漏洞数据库如 NVD 查看详情了解CVSS评分、影响范围和利用复杂度做出自己的判断。统一工具链在团队或项目内固定使用同一套扫描工具和策略确保结果可比性。6.2 权限配置相关问题1应用以非root用户运行后启动失败报权限错误。典型场景应用需要写入某个目录如/var/log,/app/data或者需要绑定1024以下的特权端口如80端口。解决方案文件权限在Dockerfile中用chown或COPY --chown确保应用用户对需要写入的目录有权限。或者在运行时通过卷挂载由主机提供具有合适权限的目录。端口问题容器内应用可以监听任意端口如8080然后通过Docker或K8s的端口映射将主机的80端口映射到容器的8080端口。这样应用无需特权。能力Capability极少数情况应用可能需要特定的Linux能力如NET_BIND_SERVICE来绑定特权端口。可以通过--cap-addNET_BIND_SERVICE添加但这比直接给root权限更精细、更安全。务必确认这是唯一且必要的方式。问题2设置了--read-only后容器启动失败。排查步骤查看容器日志docker logs container_id通常错误信息会明确指出哪个文件或目录无法写入。常见需写入的位置/tmp,/var/run,/run,/proc,/sys以及应用自己定义的日志、数据目录。针对性挂载使用--tmpfs为临时文件系统挂载点如/tmp,/run提供内存存储。使用-v或--mount为应用数据、日志目录挂载持久化卷。docker run --read-only \ --tmpfs /tmp \ --tmpfs /run \ -v /path/to/app/logs:/app/logs \ your-image问题3如何验证Seccomp或AppArmor配置文件是否生效验证Seccomp运行容器时通过--security-opt seccomp/path/to/profile.json指定自定义配置。使用docker inspect检查SecurityOpt字段。更直接的验证需要结合容器的行为测试。验证AppArmor在主机上查看进程的AppArmor状态cat /proc/$(docker inspect -f {{.State.Pid}} container_id)/attr/current。输出应该显示你配置的AppArmor策略名而不是unconfined。心得自定义Seccomp和AppArmor策略编写复杂通常从默认策略开始。Docker提供了一个默认的Seccomp配置文件已经禁用了许多危险的系统调用。在大多数情况下使用默认配置并加上--security-opt no-new-privileges:true就能提供很好的保护。除非有特殊需求否则不建议新手直接修改。安全审计是一个持续的过程而不是一次性的任务。对于像“Nunchaku-FLUX.1-dev”这样的镜像应该将其纳入持续集成/持续部署CI/CD的管道中确保每次构建都能自动进行安全扫描和基线检查。这样安全就从一个“门禁”变成了融入开发流程的“免疫系统”。

相关新闻