无服务器与函数安全
识别无服务器函数独有的攻击面(权限过大的 IAM 角色、事件注入和依赖项风险),并应用最小权限和输入验证控制。
无服务器与函数安全 是 CoddyKit 上的免费 Security+ Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Security+ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Security+ Academy 课程共包含 4 节课。
什么是无服务器计算
无服务器计算(函数即服务,FaaS)允许开发人员部署由事件触发的独立函数,例如 HTTP 请求、队列消息、数据库触发器或定时器,而无需管理底层服务器。主要平台包括 AWS Lambda、Google Cloud Functions 和 Azure Functions。云服务提供商负责补丁、扩展和基础设施管理。虽然这减轻了运维负担,但也改变了安全责任模型:提供商负责保护运行时环境,而开发人员则独自负责函数代码、权限和配置。
独特的无服务器攻击面
与传统应用相比,无服务器函数具有独特的攻击面:函数通常生命周期很短(几秒到几分钟),因此传统 EDR 和网络监控的效果会降低;函数由事件驱动,意味着许多不同的输入源(S3 事件、API Gateway、SNS)都可以触发执行;函数通常拥有能够访问其他云资源的 IAM 权限;此外还会使用可能包含恶意代码的第三方依赖项(npm、pip 软件包)。攻击面由事件输入、IAM 权限和依赖项信任链共同构成。
权限过大的 IAM 角色:首要威胁
最常见的无服务器安全漏洞是权限过大的 IAM 角色。当开发人员需要函数访问一个 S3 存储桶时,为避免权限错误,很容易直接分配 s3:*(完整 S3 访问权限)。拥有此角色的函数一旦遭到入侵或存在漏洞,攻击者就可以读取、写入或删除账户中的任何存储桶。防御措施是严格采用最小权限 IAM 角色:每个函数都应拥有专用角色,仅授予该函数完成特定任务所需的最低权限。AWS IAM Access Analyzer 和 Cloudsplaining 等工具可以自动识别权限过大的 Lambda 角色。
# IAM policy: least privilege for specific Lambda function
{
'Version': '2012-10-17',
'Statement': [{
'Effect': 'Allow',
'Action': ['s3:GetObject'],
'Resource': 'arn:aws:s3:::my-specific-bucket/uploads/*'
}]
}事件注入攻击
当事件负载中由攻击者控制的数据被函数代码不安全地处理时,就会发生事件注入。由于无服务器函数可以由多种事件源触发——HTTP 标头、查询参数、数据库变更记录、队列消息正文和电子邮件内容——其中任何一种都可能携带恶意负载。常见的注入类型包括:函数使用事件数据查询数据库时的SQL 注入;NoSQL 注入(在 JSON 负载中注入 MongoDB 操作符);事件数据被用于 OS 命令时的命令注入;以及获取事件数据中的 URL 时的SSRF(服务器端请求伪造)。输入验证和参数化查询是必不可少的防御措施。
# Vulnerable: event data used directly in shell command
# const filename = event.filename;
# exec('convert ' + filename + ' output.jpg');
# Safe: validate and sanitize input
# const filename = path.basename(event.filename);
# if (!/^[a-z0-9_-]+\.(jpg|png)$/i.test(filename)) throw new Error('Invalid');
# execFile('convert', [filename, 'output.jpg']);依赖项风险:第三方软件包
无服务器函数经常依赖数十个第三方软件包。这些依赖项会引入供应链风险:恶意或遭到入侵的软件包可以在函数的执行环境中运行任意代码、访问环境变量(其中通常包含机密信息)、建立出站网络连接,并利用函数的 IAM 角色访问云资源。2018 年 event-stream npm 软件包遭到入侵,以及大量仿冒拼写软件包事件,都说明了这种风险。防御措施包括固定依赖项版本、在持续集成/持续交付流程中进行 SCA 扫描,以及尽量减少依赖项数量。
无服务器环境中的机密信息:环境变量
无服务器函数通常通过云控制台中配置的环境变量接收机密信息。任何拥有 Lambda 配置 IAM 访问权限的人员都可以查看这些环境变量,并且函数内运行的任何代码都可以访问它们。最佳实践包括:避免将机密信息直接存储为明文环境变量;Use 存储 ARN 或机密名称,并在运行时从 AWS Secrets Manager 或参数存储中 Retrieve 机密信息;为静态存储的 Lambda 环境变量启用 KMS 加密;并且绝不要记录环境变量(许多调试日志记录器会在发生错误时转储所有环境变量)。
# Retrieve secret at runtime instead of hardcoding
# Using AWS SDK in Lambda
# const secretsClient = new SecretsManagerClient({});
# const response = await secretsClient.send(
# new GetSecretValueCommand({ SecretId: 'prod/myapp/db-password' })
# );
# const dbPassword = response.SecretString;函数超时与并发限制
针对无服务器函数的拒绝服务攻击可能采取调用洪泛的形式:能够反复触发函数的攻击者可能耗尽账户的并发限制(Lambda 的默认值是每个区域 1,000 个并发执行实例),使账户中的其他函数无法执行。处理用户控制输入的函数应在 API Gateway 层实施速率限制,验证负载大小限制,并设置适当的超时值,以防止执行失控。如果输入未限制大小,攻击者还可以在解析 XML/YAML 时利用“Billion Laughs”式扩展攻击发动攻击。
# AWS Lambda: set reserved concurrency to prevent account-wide DoS
aws lambda put-function-concurrency \
--function-name my-api-handler \
--reserved-concurrent-executions 100VPC 集成与网络隔离
默认情况下,AWS Lambda 函数运行在 AWS 管理的 VPC 中,可以访问互联网,但无法访问您私有 VPC 中的资源(RDS 数据库、ElastiCache、私有 API)。要访问私有资源,必须将 Lambda 配置为在您的 VPC 内运行,并指定子网和安全组。但是,连接到 VPC 的 Lambda 函数默认无法访问互联网——它们需要使用NAT Gateway访问外部互联网。附加到 Lambda 函数的安全组应遵循最小权限规则:仅允许所需的特定端口和目标。请避免在生产函数的安全组中使用 0.0.0.0/0 出站规则。
监控无服务器函数
无服务器安全监控需要采用不同于传统主机监控的方法。由于函数具有短暂性,基于主机的代理并不实用。有效的监控方式包括:使用 AWS CloudTrail 记录所有 Lambda API 调用(调用、配置更改和角色假设);使用 CloudWatch Logs Insights 查询函数执行日志,以查找异常模式;使用 Amazon GuardDuty 检测威胁,包括异常的 Lambda 网络活动;以及使用商业化的无服务器原生安全工具,例如 Protego(现已成为 Check Point 的一部分),或使用 Datadog 的无服务器监控,通过层为函数添加检测能力,从而提供运行时可见性。
# Query CloudWatch Logs for Lambda errors and anomalies
aws logs start-query \
--log-group-name '/aws/lambda/my-function' \
--start-time $(date -d '-1 hour' +%s) \
--end-time $(date +%s) \
--query-string 'fields @timestamp, @message | filter @message like /ERROR|WARN|credential/'无服务器安全测试
测试无服务器安全需要专门的工具:PureSec CLI(现为 Check Point)和 Prowler 可扫描云配置中的无服务器错误配置;DAST 工具可以测试由 HTTP 触发的函数是否存在注入漏洞;使用 Bandit(Python)或 ESLint 安全插件等工具对函数代码进行静态分析,可以发现不安全的编码模式;手动测试则应枚举能够触发每个函数的所有事件源,并使用格式错误和恶意负载逐一进行测试。OWASP 无服务器十大风险提供了专门针对无服务器架构的全面漏洞检查清单。
# Prowler: check Lambda security posture
prowler aws --service lambda
# Checks: public URL, over-privileged roles, unencrypted env vars,
# outdated runtime, missing VPC config, excessive timeout无服务器环境中的共同责任
无服务器计算使共同责任模型进一步向提供商倾斜。云服务提供商负责:函数运行时环境、OS 补丁、底层基础设施安全以及物理设施。客户仍需负责:函数代码安全、IAM 权限设计、机密信息管理、输入验证、依赖项管理、日志配置和网络策略。基础设施责任减少并不意味着安全责任减少——它只是改变了安全投入的重点,主要转向应用层安全和 IAM 安全。
快速检查
请检验您对本课 CompTIA Security+(SY0-701)相关概念的理解。
课程回顾
本课您学习了:权限过大的 IAM 角色是无服务器环境的首要风险——每个函数都需要专用的最小权限角色;事件注入攻击会利用任何事件源,将攻击者控制的数据传递给缺少输入验证的函数;第三方软件包带来的依赖项供应链风险可能危及函数执行,并使攻击者获得 IAM 凭证和机密信息。接下来我们将探讨基础设施即代码安全扫描,以便在部署前发现错误配置。
常见问题解答
「无服务器与函数安全」课时是免费的吗?
是的 — 「无服务器与函数安全」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Security+ Academy 课程的其余内容,请升级到 CoddyKit PRO。 Security+ Academy 课程共包含 4 节课。
「无服务器与函数安全」这节课中我会学到什么?
识别无服务器函数独有的攻击面(权限过大的 IAM 角色、事件注入和依赖项风险),并应用最小权限和输入验证控制。 你通过在浏览器中直接运行的动手代码来练习 Security+ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Security+ Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Security+ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「无服务器与函数安全」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Security+ Academy 课中编写并运行代码吗?
能。每节 Security+ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。