news 2026/9/16 16:29:16

用 Checkov 扫描 Serverless Framework 配置:从 CLI 实战到源码级原理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用 Checkov 扫描 Serverless Framework 配置:从 CLI 实战到源码级原理

用 Checkov 扫描 Serverless Framework 配置:从 CLI 实战到源码级原理

【免费下载链接】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

Checkov 支持直接对 Serverless Framework 的服务定义文件(serverless.yml/serverless.yaml)执行安全策略评估,在构建阶段提前发现云资源错误配置。本文将围绕docs/7.Scan Examples/Serverless Framework.md的完整流程展开:先给出一个刻意配置错误的serverless.yml示例与真实扫描输出,再深入 Checkov 源码剖析 serverless 扫描引擎的解析、变量求值、图构建与检查分发机制,最后结合测试用例给出修复建议,帮助你既会用、又懂原理。

一、Serverless Framework 扫描能力概述

Serverless Framework 允许开发者用一份 YAML 服务定义文件同时描述 Lambda 函数、IAM 角色、事件源以及底层云资源(通过resources节内嵌 CloudFormation 模板语法)。Checkov 的 serverless 扫描会对这类文件运行策略检查,验证其是否符合 AWS 最佳实践,例如:

  • 是否开启了日志记录与审计(如 S3 访问日志、CloudTrail);
  • S3 存储桶是否加密、是否开启版本控制;
  • 是否启用了 HTTPS 传输;
  • IAM 策略是否过度授权;
  • 是否存在硬编码凭据。

需要特别说明的是,Serverless Framework 扫描复用了 CloudFormation 扫描实现中的大量检查,因为Serverless 的资源定义是对 CloudFormation 定义的扩展resources节内的资源本质就是 CloudFormation 资源)。这一设计可以在源码中直接印证:serverless Runner 在检查resources节时调用的正是cfn_registry(见 checkov/serverless/runner.py)。

完整的 Serverless 策略清单参见仓库内的策略索引文档 docs/5.Policy Index/serverless.md,其中既包含作用于serverless_aws实体的专用检查,也包含通过 CloudFormation 通道复用的 AWS 资源检查(如AWS::S3::BucketAWS::Lambda::FunctionAWS::IAM::Policy等)。

二、快速开始:扫描一个 Serverless 服务目录

1. 文件识别规则

默认情况下,Checkov 的 serverless 扫描只会识别文件名恰好为serverless.ymlserverless.yaml的文件。该掩码定义在 checkov/serverless/utils.py:

SLS_FILE_MASK = os.getenv( "CKV_SLS_FILE_MASK", "serverless.yml,serverless.yaml").split(",")

也就是说,你可以通过环境变量CKV_SLS_FILE_MASK自定义要扫描的文件名集合(逗号分隔)。扫描目录时,Checkov 会递归遍历目录树,并自动跳过node_modules目录(见 get_scannable_file_paths),避免扫描无关依赖。

2. 指定框架运行扫描

对当前目录下的 serverless 服务执行扫描:

checkov -d . --framework serverless
  • -d .:扫描当前目录(递归);
  • --framework serverless:仅运行 serverless 框架相关的检查。如果省略该参数,Checkov 会按默认的框架集全量扫描;也可以组合多个框架,例如--framework serverless cloudformation,同时覆盖服务定义与内嵌的 CloudFormation 资源。

3. 解析前提:仅支持 AWS provider

从源码看,serverless 解析器对模板有严格的准入校验。is_checked_sls_template(见 checkov/serverless/parsers/parser.py)要求模板必须包含provider字段,且其name必须位于SUPPORTED_PROVIDERS = ['aws']中(provider既可以写成字典,也可以直接写成字符串aws)。也就是说,当前版本的 serverless 扫描面向 AWS provider,其他云厂商的服务定义不会被纳入扫描范围。

三、示例:一个刻意配置错误的 Serverless 服务

以下示例定义了一个名为usersCrud的 AWS 服务:包含一个 Lambda 函数myFunc(带 IAM 角色语句、标签、超时与内存配置),并在resources节内嵌了一个 CloudFormation 风格的 S3 存储桶S3BucketPublicRead,其AccessControl被显式设置为PublicRead

service: usersCrud provider: aws functions: myFunc: name: myFunc tags: RESOURCE: lambda PUBLIC: false iamRoleStatements: - Effect: Allow Action: - "lambda:InvokeFunction" Resource: - "arn:aws:lambda:#{AWS::Region}:#{AWS::AccountId}:function:invokedLambda" handler: Handler.handle timeout: 600 memorySize: 320 resources: # CloudFormation template syntax Resources: S3BucketPublicRead: Type: AWS::S3::Bucket Properties: AccessControl: PublicRead BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256

将上述内容保存为serverless.yml后,直接运行:

checkov -d . --framework serverless

可以看到两个层面的检查对象:

  1. 函数级检查myFunciamRoleStatementsenvironment(若存在)会被逐一评估。示例中iamRoleStatements声明了lambda:InvokeFunctionAllow语句,CloudFormation 风格的#{AWS::Region}#{AWS::AccountId}伪参数由 serverless 解析器保留供后续替换。
  2. CloudFormation 资源检查resources.Resources节内的AWS::S3::Bucket会被提取出来,交给 CloudFormation 资源注册表(cfn_registry)扫描,因此 S3 相关的全部检查(加密、ACL、日志、版本控制、公有访问块等)都会生效。

四、解读扫描输出

对上述示例执行扫描,典型的控制台输出如下(篇幅所限,仅保留核心结构):

_ _ ___| |__ ___ ___| | _______ __ / __| '_ \ / _ \/ __| |/ / _ \ \ / / | (__| | | | __/ (__| < (_) \ V / \___|_| |_|\___|\___|_|\_\___/ \_/ By Prisma Cloud | version: x.x.x serverless scan results: Passed checks: 5, Failed checks: 7, Skipped checks: 0 Check: CKV_AWS_19: "Ensure the S3 bucket has server-side-encryption enabled" PASSED for resource: AWS::S3::Bucket.S3BucketPublicRead File:/serverless.yml:22-29 Check: CKV_AWS_57: "Ensure the S3 bucket does not allow WRITE permissions to everyone" PASSED for resource: AWS::S3::Bucket.S3BucketPublicRead File:/serverless.yml:22-29 Check: CKV_AWS_49: "Ensure no IAM policies documents allow "*" as a statement's actions" PASSED for resource: myFunc File:/serverless.yml:5-19 Check: CKV_AWS_41: "Ensure no hard coded AWS access key and secret key exists in provider" PASSED for resource: myFunc File:/serverless.yml:5-19 Check: CKV_AWS_1: "Ensure IAM policies that allow full "*-*" administrative privileges are not created" PASSED for resource: myFunc File:/serverless.yml:5-19 Check: CKV_AWS_20: "Ensure the S3 bucket does not allow READ permissions to everyone" FAILED for resource: AWS::S3::Bucket.S3BucketPublicRead File:/serverless.yml:22-29 22 | S3BucketPublicRead: 23 | Type: AWS::S3::Bucket 24 | Properties: 25 | AccessControl: PublicRead 26 | BucketEncryption: 27 | ServerSideEncryptionConfiguration: 28 | - ServerSideEncryptionByDefault: 29 | SSEAlgorithm: AES256 Check: CKV_AWS_18: "Ensure the S3 bucket has access logging enabled" FAILED for resource: AWS::S3::Bucket.S3BucketPublicRead File:/serverless.yml:22-29 Check: CKV_AWS_53: "Ensure S3 bucket has block public ACLS enabled" FAILED for resource: AWS::S3::Bucket.S3BucketPublicRead File:/serverless.yml:22-29 Check: CKV_AWS_54: "Ensure S3 bucket has block public policy enabled" FAILED for resource: AWS::S3::Bucket.S3BucketPublicRead File:/serverless.yml:22-29 Check: CKV_AWS_21: "Ensure the S3 bucket has versioning enabled" FAILED for resource: AWS::S3::Bucket.S3BucketPublicRead File:/serverless.yml:22-29 Check: CKV_AWS_55: "Ensure S3 bucket has ignore public ACLs enabled" FAILED for resource: AWS::S3::Bucket.S3BucketPublicRead File:/serverless.yml:22-29 Check: CKV_AWS_56: "Ensure S3 bucket has 'restrict_public_bucket' enabled" FAILED for resource: AWS::S3::Bucket.S3BucketPublicRead File:/serverless.yml:22-29

输出中的几个关键要素:

  • 汇总行Passed checks: 5, Failed checks: 7, Skipped checks: 0给出三类结果的数量统计(Skipped 通常来自checkov:skip=跳过注释)。
  • 检查条目:每条输出包含检查 ID(如CKV_AWS_20)、策略描述、针对的资源(AWS::S3::Bucket.S3BucketPublicRead或函数名myFunc)、命中的文件与行号区间,以及失败时附带的代码片段,方便直接定位到serverless.yml中对应的配置行。
  • 结果对照myFunc的函数级检查(CKV_AWS_1、CKV_AWS_41、CKV_AWS_49)全部通过,说明 IAM 语句未使用*通配符、不存在硬编码凭据;而S3BucketPublicRead由于AccessControl: PublicRead且缺少日志、版本控制与公有访问块配置,导致 6 项 S3 检查失败。加密检查(CKV_AWS_19)通过,是因为示例中配置了SSEAlgorithm: AES256

五、源码原理:Serverless 扫描引擎的四个阶段

理解了输出之后,我们再从 checkov/serverless 模块出发,看一次扫描在 Checkov 内部是如何完成的。

阶段一:文件发现与解析

Runner 通过get_scannable_file_paths在目标目录中按SLS_FILE_MASK匹配文件,随后调用get_files_definitions并行解析(见 checkov/serverless/runner.py)。解析器使用cfn_yaml.load(filename, cfn_yaml.ContentType.SLS)加载 YAML(见 checkov/serverless/parsers/parser.py),这一设计保证了与 CloudFormation 解析器共享底层实现,同时记录了每个节点的起始/结束行号,供后续输出代码片段使用。非 YAML、文件缺失、权限不足等情况都会被捕获并跳过,不会中断整个扫描。

阶段二:变量求值

Serverless Framework 的模板大量使用${...}变量语法。process_variables(见 checkov/serverless/parsers/parser.py)在解析后对模板做原地变量替换,支持:

  • ${self:custom.xxx}:引用模板自身其他部分;
  • ${env:VAR_NAME}:引用环境变量;
  • ${file(./path/to/file.yml)}:引用外部 YAML/JSON 文件(${file(...)}也支持带路径内部属性,如${file(./conf.yml):deploy.bucket});
  • 逗号分隔的兜底值语法:如${self:custom.env, 'dev'}

变量替换采用循环求值以处理链式引用,上限为 25 轮防止振荡。从源码注释可以看到,若provider.variableSyntax被自定义,则使用自定义正则;否则使用默认模式SLS_DEFAULT_VAR_PATTERN。此外,环境变量CHECKOV_SERVERLESS_DISABLE_VARS=true可关闭${env:}${file()}的解析(${self:}不受影响),用于需要在扫描中保留原始变量形态的场景(见 _load_var_data)。

阶段三:图构建

解析完成后,Runner 会构建一个 Serverless 局部图(ServerlessLocalGraph,见 checkov/serverless/graph_builder/local_graph.py)。图中为每个文件的 9 类顶层元素分别建立顶点:functionsparamsproviderlayerscustompackagepluginsserviceresources(枚举定义见 checkov/serverless/utils.py)。图构建完成后,顶点数据会被转换回定义结构,供后续检查阶段消费。

阶段四:检查分发

add_python_check_results(见 checkov/serverless/runner.py)按四类通道分发检查:

通道覆盖节注册表说明
cfn_resources_checksresources.Resourcescfn_registry将内嵌的 CloudFormation 资源交给 CloudFormation 检查体系(如全部 S3 检查)
multi_item_sections_checksfunctionslayersfunction_registrylayer_registry多实体节,逐项检查每个函数/层
single_item_sections_checksprovidercustompackagepluginsservice对应注册表单实体节,整体检查
complete_python_checks整个文件complete_registry针对整个模板的全局检查

其中SINGLE_ITEM_SECTIONSMULTI_ITEM_SECTIONS的定义见 checkov/serverless/runner.py。

一个值得注意的细节是enrich_function_with_provider(见 checkov/serverless/parsers/context_parser.py):在扫描functions节时,Runner 会把provider块中的iamRoleStatementsenvironmentstackTags(映射为函数tags)、runtimetimeoutmemorySize等属性下推合并到每个函数配置中,因为从 Serverless 运行时的语义看,函数会继承这些 provider 级配置。这样一来,函数级检查看到的配置就是"完整生效"的配置,而不是缺省的片段。

函数级检查的三份实现样例

Serverless 专属的serverless_aws实体检查位于 checkov/serverless/checks/function/aws,其中三份实现与示例输出中的检查一一对应:

  • CKV_AWS_1(AdminPolicyDocument.py):遍历iamRoleStatements,若存在Effect: AllowActionResource均为*的语句,则判定 FAILED,防止创建"*-*"全管理权限策略。
  • CKV_AWS_41(AWSCredentials.py):检查函数environment中的字符串值是否命中 AWS access key / secret key 正则模式,用于发现硬编码凭据。
  • CKV_AWS_49(StarActionPolicyDocument.py):检查 IAM 策略文档是否在Allow语句的Action中使用*通配符。

这些检查类均继承自BaseFunctionCheck,通过scan_function_conf接收被"provider 属性充实过"的函数配置字典,返回CheckResult.PASSED / FAILED / UNKNOWN。此外,providerservicecustomlayerpackageplugin等节也有各自的基类与注册表,共同构成 checkov/serverless/checks 目录下的分层检查体系。

六、Serverless 检查与 CloudFormation 检查的关系

原文档明确指出:"Serverless 扫描利用的是 Checkov CloudFormation 扫描实现中的检查,因为 Serverless 资源定义扩展了 CloudFormation 定义。"这句话在源码层面有两处体现:

  1. 解析器复用:serverless 解析直接调用cfn_yaml加载 YAML(checkov/serverless/parsers/parser.py),并复用 CloudFormation 的ContextParser提取代码行与收集跳过注释。
  2. 资源检查复用resources节内的资源以cfn_resources_checks通道交给cfn_registry扫描(checkov/serverless/runner.py),因此 S3、Lambda、IAM 等 AWS 资源的全部 CloudFormation 检查自动对 serverless 模板生效。

策略索引文档 docs/5.Policy Index/serverless.md 也印证了这一点:表格上半部分是serverless_aws实体专属的 3 项检查(CKV_AWS_1、CKV_AWS_41、CKV_AWS_49),下半部分则是大量标为 Cloudformation 的 AWS 资源检查(如 CKV_AWS_18、CKV_AWS_19、CKV_AWS_20、CKV_AWS_21、CKV_AWS_53~56 等 S3 检查),它们会通过 CloudFormation 通道作用于 serverless 模板中的内嵌资源。

七、测试验证与修复建议

仓库为 serverless 扫描提供了完整的单元测试,可作为验证行为与学习用法的参考:

  • tests/serverless/runner/test_runner.py:验证 Runner 各注册表report_type均为CheckType.SERVERLESS、记录路径的相对化、以及 enforcement rules 过滤等行为;
  • tests/serverless/runner/resources/serverless.yaml:一个真实的扫描样例,覆盖${self:}/${file()}变量、provider 级environment继承、ECR 镜像、文件系统配置等复杂场景;
  • tests/serverless/checks/aws:针对AdminPolicyDocumentAWSCredentialsStarActionPolicyDocument等检查的用例。

针对本文示例中失败的 7 项检查,修复思路非常明确:为 S3 存储桶补充版本控制(VersioningConfiguration)、访问日志(LoggingConfiguration)、以及完整四件套的公有访问块配置(PublicAccessBlockConfiguration下的BlockPublicAclsIgnorePublicAclsBlockPublicPolicyRestrictPublicBuckets均设为true),并将AccessControlPublicRead改为私有。修改后重新运行checkov -d . --framework serverless,即可看到 Failed 数量归零。

如果需要对个别策略做豁免,可以在serverless.yml相应资源块上方添加# checkov:skip=CKV_AWS_20:reason跳过注释,或结合--skip-check参数在命令行过滤(详见 docs/2.Basics/Suppressing and Skipping Policies.md)。将 serverless 扫描纳入 CI 流水线后,即可在每次构建阶段自动拦截公有存储桶、硬编码凭据、过度授权 IAM 等高风险配置,实现"基础设施即代码"的左移安全治理。

【免费下载链接】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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 16:29:08

DEAP脑电情绪识别二分类实战:从MNE数据处理到XGBoost建模

简介&#xff1a;面向脑电情绪识别入门者与机器学习初学者的二分类算法实现&#xff0c;基于公开 DEAP 脑电数据集&#xff0c;完整覆盖快速傅里叶变换&#xff08;FFT&#xff09;特征提取、数据预处理与模型训练评估流程。代码共5个文件&#xff0c;包含4个 Python 脚本和1个…

作者头像 李华
网站建设 2026/9/16 16:28:20

STM32L496嵌入式TLS实战:内存裁剪、证书预加载与LWIP适配

简介&#xff1a;本资源是一套基于RT-Thread操作系统的STM32L496嵌入式TLS安全通信完整工程&#xff0c;面向嵌入式开发工程师、物联网安全实践者及RTOS进阶学习者&#xff0c;解决低功耗Cortex-M4平台下mbedtls集成与TLS端到端实现难题。压缩包共7134个文件&#xff0c;主体为…

作者头像 李华
网站建设 2026/9/16 16:25:54

Wasp 子目录部署指南:baseDir 与 WASP_WEB_CLIENT_URL 的正确配置

Wasp 子目录部署指南&#xff1a;baseDir 与 WASP_WEB_CLIENT_URL 的正确配置 【免费下载链接】wasp The batteries-included full-stack framework for the AI era. Develop JS/TS web apps (React, Node.js, and Prisma) using declarative code that abstracts away complex…

作者头像 李华
网站建设 2026/9/16 16:25:31

WinForms迁移Blazor实战:MWGA工具解析与应用

1. 项目背景与核心挑战最近接手了一个历史遗留的WinForms系统迁移项目&#xff0c;这个拥有7万行代码的C#桌面程序已经稳定运行了十几年。随着业务发展&#xff0c;客户强烈要求将其改造成Web应用。面对这个看似不可能的任务&#xff0c;我发现了一个名为MWGA&#xff08;Make …

作者头像 李华