本文目录导读:

无服务器架构(Serverless)的核心特点是“开发者无需管理服务器”,但这并不意味着安全责任完全由云厂商承担,无服务器架构遵循共享责任模型(Shared Responsibility Model),只是责任的边界发生了显著变化。
以下是关于无服务器架构安全责任划分的详细分析,以及一些容易被忽视的盲点。
核心原则:责任的“向上”与“向下”移动
与传统云架构(如IaaS或PaaS)相比,无服务器架构中:
- 云厂商的责任增加了: 它们负责底层基础设施(物理机、虚拟机、网络)以及运行时环境(如AWS Lambda的执行环境、操作系统的补丁、底层容器的隔离)。
- 用户的责任也改变了(并未消失): 用户不再需要管理OS补丁和防火墙,但需要负责代码安全、配置安全、数据安全、身份与访问管理(IAM)以及业务逻辑安全。
详细责任划分边界
可以按“云厂商负责”和“用户负责”两个维度来拆解:
云厂商(如AWS、Azure、GCP)负责的部分
- 物理基础设施安全: 数据中心、网络、电力、散热、物理访问控制。
- 虚拟化/容器层安全: 确保不同客户的函数执行环境是隔离的(沙箱机制),防止侧信道攻击。
- 运行时环境的安全: 负责底层操作系统(Amazon Linux、Ubuntu等)的补丁和加固,包括内核、系统库等。
- 核心服务API的安全: 保证其提供的API Gateway、函数计算服务、对象存储等核心服务的API本身不存在高危漏洞。
- 函数生命周期管理: 确保函数冷启动时的安全初始化、热实例的回收和清理(如/tmp目录的清理)。
用户(开发/运维团队)负责的部分
这是容易被忽视或误判的部分,具体包括:
- 代码安全(第一位): 函数的代码本身是否存在漏洞(SQL注入、命令注入、不安全的反序列化等),无服务器代码暴露的攻击面更大。
- 依赖项安全: 函数引用的第三方库(如npm、PyPI、Maven包)是否存在已知漏洞(CVE),与传统环境不同,这些依赖会直接打包进部署包。
- 身份与访问管理(IAM): 这是最核心、最易出错的安全边界。
- 函数执行角色(Execution Role): 函数在运行时能调用哪些云资源(如读写S3、写入DynamoDB)。原则:最小权限。 如果权限过大(如给了一个
AdministratorAccess的角色),攻击者通过一个SSRF漏洞就能拿下整个账户。 - 调用方权限: 谁(用户、其他函数、API网关)可以调用这个函数,需要设置细粒度的资源策略。
- 函数执行角色(Execution Role): 函数在运行时能调用哪些云资源(如读写S3、写入DynamoDB)。原则:最小权限。 如果权限过大(如给了一个
- 配置安全(Misconfiguration):
- API Gateway: 是否启用了认证?CORS(跨域资源共享)配置是否过于宽松?是否开启了公网访问?
- 环境变量: 数据库密码、API密钥是否明文硬编码在环境变量中?虽然环境变量本身是加密的,但函数内代码可以读取。建议使用KMS加密或Secrets Manager动态获取。
- 事件源绑定: S3桶的事件通知是否自动触发一个处理函数?如果S3桶是公开写权限,任何人都可以往桶里放文件,从而导致函数被恶意触发(恶意文件上传、拒绝服务)。
- 数据安全(Data Security):
- 函数处理的数据(如用户上传的文件、数据库记录)在传输中(TLS/SSL)和静态存储(加密)是否被保护?
- 函数内部数据处理: 是否在日志中不小心打印了敏感信息(如信用卡号、密码)?日志(CloudWatch等)本身是否被正确保护?
- 业务逻辑与输入验证:
- 事件源注入: 攻击者可以通过修改事件(如API Gateway请求体、DynamoDB Streams记录)来操纵函数逻辑。
- 功能滥用: 一个生成图像缩略图的函数,如果没有限制输入文件大小,攻击者可以传入巨大图片,导致函数执行超时或消耗巨额费用(资源耗尽攻击或成本攻击)。
- 日志与监控: 函数是否开启了全面的日志记录?是否有告警机制检测异常行为(如大量未授权调用、异常的错误率)?
容易忽视的“灰色地带”和盲点
- 共享库 vs. 自定义运行时: 如果用户使用自定义运行时(Custom Runtime),例如自己打包了一个Debian镜像或自定义语言环境,那么操作系统补丁的责任就部分回到了用户身上,云厂商只保证基础沙箱的安全。
- 依赖下沉(Function Shredding): 无服务器函数通常很短命,但如果函数内使用了持久化连接(如数据库连接池)或缓存(如内存中的变量、
/tmp目录),这些状态在不同调用之间是共享的,攻击者如果控制了实例,可能窃取这些共享数据,用户需要确保/tmp目录不存储敏感数据,且连接池安全。 - 第三方服务集成: 函数可能会调用第三方API(如Stripe、Twilio、或用户自建的后端),这些第三方服务的认证凭据(API Token)存储在环境变量中。如果凭据泄露,攻击者可以直接以函数的身份访问第三方。 用户需负责管理这些凭据。
- 供应链安全(Software Supply Chain): 部署函数时,会打包所有依赖,如果一个上游包被恶意篡改(如
node_modules中的包被注入后门),用户发布的代码就天然带毒。用户需负责对依赖进行扫描和校验(如使用SBOM、Snyk、WhiteSource等工具)。 - 冷启动安全: 虽然云厂商会隔离实例,但用户需要保证函数在冷启动时的初始化代码(如连接数据库、加载密钥)是安全的,不要在初始化阶段加载所有权限的密钥,而是按需加载。
总结对照表
| 安全领域 | 云厂商负责 | 用户负责 |
|---|---|---|
| 物理与基础架构 | 数据中心、网络、硬件、虚拟机管理程序 | 无 |
| 运行时环境 | 底层OS补丁、容器隔离、沙箱安全 | 无(除非使用自定义运行时) |
| 函数代码 | 无 | 代码漏洞(注入、逻辑错误、输入验证) |
| 依赖与库 | 无(仅保证底层环境库稳定) | 第三方库漏洞扫描、版本管理、供应链安全 |
| 身份与访问控制 | 提供基本的IAM框架(角色、策略引擎) | 设计细粒度IAM角色、权限策略、调用方验证 |
| 配置 | API Gateway等服务的默认安全设置 | 禁用非必要功能(如CORS宽松、公网暴露)、加密环境变量 |
| 数据 | 静态加密(可选)、传输层加密(TLS) | 加密密钥管理、日志脱敏、数据生命周期管理 |
| 监控与响应 | 提供审计日志(如CloudTrail) | 配置日志告警、事件响应(如检测异常成本)、自动化修复 |
| 成本安全 | 提供额度限制功能(如预算警报) | 防止成本滥用(如无限制的递归调用、资源耗尽攻击) |
给开发运维团队的建议
- 零信任架构: 哪怕函数是“同一个账户下的”,也要假设函数之间的调用是“不安全的”,每个函数只能拥有完成其功能所需的最小权限。
- 强制使用IAM角色,而非长期密钥: 绝不要在函数代码或配置文件里写死Access Key/Secret Key,只使用IAM执行角色。
- 实施输入验证与净化(Input Validation & Sanitization): 对来自API Gateway、数据库、S3事件的所有输入,在函数内部进行严格的校验和逃逸处理。
- 使用Secret Management服务: 使用AWS Secrets Manager、Azure Key Vault或GCP Secret Manager存储敏感信息,并配置自动轮换。
- 监控与成本保护: 设置函数并发限制(Reserved Concurrency)、账户预算和异常调用告警,攻击者可能通过大量调用耗尽你的账户额度。
- 代码与依赖扫描: 在CI/CD流水线中集成安全扫描工具(如Snyk、Checkmarx、AWS CodeGuru Security),检测高危依赖和代码漏洞。
- 日志隔离: 不要把函数产生的所有日志都发送到同一个日志组,并做好日志的访问控制(最小化读取权限)。
总结一句话: 在无服务器架构下,云厂商负责“硬件和底层系统的安全”,而你(用户)负责“你写出来的代码、你配置的策略、你引用的依赖以及你对数据的处理安全”。IAM权限配置和依赖供应链安全是用户最容易出问题、后果也最严重的领域。