无服务器安全
无服务器架构消除了服务器管理,但也带来了新的 挑战:函数级权限、event injection、依赖漏洞以及 扩大的攻击面。
责任共担模型
提供商(AWS/Azure/GCP)
- 物理安全与基础设施
- Runtime environment
- 函数之间的隔离
- 操作系统补丁
客户(您)
- 函数代码
- 依赖与库
- IAM 权限
- 数据加密
- API Gateway 配置
- Logging 与 monitoring
OWASP Serverless Top 10
- Injection Flaws:event data 中的 SQLi、command injection
- Broken Authentication:token 管理不当、弱认证
- Sensitive Data Exposure:硬编码的 secrets、冗长的日志
- XML External Entities (XXE):不安全的 XML 解析
- Broken Access Control:过于宽松的 IAM
- Security Misconfiguration:默认配置、开放端口
- Cross-Site Scripting (XSS):不充分的 output encoding
- Insecure Deserialization:对不受信任事件的反序列化
- Using Components with Known Vulnerabilities:过时的依赖
- Insufficient Logging:缺乏 audit trail
IAM 与最小权限
每个函数都应拥有专用的 IAM role,并仅赋予所需的最小权限。
AWS Lambda - IAM Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem"
],
"Resource": "arn:aws:dynamodb:us-east-1:123456789:table/MyTable"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}
IAM 原则
- Function-specific roles:切勿在函数之间共享 roles
- Resource-level permissions:指定精确的 ARNs,而非 wildcards
- Time-based access:使用 AWS STS 获取临时 credentials
- Deny by default:仅显式允许必要的操作
Secrets 管理
- AWS Secrets Manager:自动轮换、encryption at rest
- Azure Key Vault:Managed HSM、access policies
- Environment variables encryption:使用 KMS 加密 env vars
- Parameter Store:使用 AWS SSM Parameter Store 存储配置
- 切勿硬编码:代码或仓库中的 secrets
AWS Lambda + Secrets Manager 示例
import boto3
import json
def lambda_handler(event, context):
# 从 Secrets Manager 获取 secret
session = boto3.session.Session()
client = session.client(service_name='secretsmanager')
get_secret_value_response = client.get_secret_value(
SecretId='prod/db/password'
)
secret = json.loads(get_secret_value_response['SecretString'])
db_password = secret['password']
# 使用 password 连接到数据库
# ...
输入验证与清理
来自 API Gateway、S3、DynamoDB Streams 等的 events 必须经过严格验证:
// Node.js Lambda example
import Joi from 'joi';
const schema = Joi.object({
userId: Joi.string().uuid().required(),
action: Joi.string().valid('create', 'update', 'delete').required(),
data: Joi.object().required()
});
export const handler = async (event) => {
try {
const body = JSON.parse(event.body);
const { error, value } = schema.validate(body);
if (error) {
return {
statusCode: 400,
body: JSON.stringify({ error: error.details })
};
}
// Process validated input
// ...
} catch (e) {
console.error('Validation error:', e);
return { statusCode: 400, body: 'Invalid input' };
}
};
依赖管理
- SCA tools:Snyk、npm audit、Dependabot
- Minimal dependencies:减少攻击面
- Lock files:package-lock.json、yarn.lock 以保证可复现性
- Private registries:托管内部批准的依赖
- SBOM:Software Bill of Materials 以保证可审计性
Timeout 与资源限制
# AWS Lambda configuration
Function:
Type: AWS::Serverless::Function
Properties:
Timeout: 30 # 秒 (default 3s, max 900s)
MemorySize: 512 # MB
ReservedConcurrentExecutions: 100 # limit concurrency
Environment:
Variables:
MAX_RETRY_ATTEMPTS: 3
CONNECTION_TIMEOUT: 5000
VPC 配置
访问私有资源的函数应在配置了适当 security groups 的 VPC 中运行:
- Private subnets:无直接互联网访问的函数
- NAT Gateway:在需要时用于 outbound internet access
- Security groups:端口和 IP 的 whitelisting
- VPC Endpoints:对 AWS 服务(S3、DynamoDB)的私有访问
Logging 与 Monitoring
- CloudWatch Logs:集中管理所有函数的日志
- CloudTrail:调用和变更的 audit trail
- X-Ray:用于 troubleshooting 的 distributed tracing
- Custom metrics:通过 CloudWatch 的业务逻辑指标
- Alerting:针对 errors、timeouts、throttles 的告警
Structured Logging
import { Logger } from '@aws-lambda-powertools/logger';
const logger = new Logger({ serviceName: 'userService' });
export const handler = async (event, context) => {
logger.addContext(context);
logger.info('Processing request', {
userId: event.userId,
requestId: context.requestId
});
try {
// Business logic
} catch (error) {
logger.error('Processing failed', { error });
throw error;
}
};
API Gateway 安全
- Authentication:Cognito、API Keys、Lambda Authorizers
- Rate limiting:Usage plans 与 throttling
- WAF integration:AWS WAF 用于防护 OWASP Top 10
- Request validation:API Gateway 中的 models 与 validators
- CORS:配置允许的 origins
冷启动安全
冷启动可能被利用进行 timing attacks。缓解措施:
- 为关键函数使用 provisioned concurrency
- 最小化 package size 以实现快速启动
- 对重量级依赖进行 lazy load
- 通过 CloudWatch Events 进行 warm-up schedules
Runtime Security
- PureSec:面向 serverless 的 runtime protection
- Protego:Serverless security platform
- Twistlock:面向 serverless 的 Prisma Cloud
- Snyk:集成于 CI/CD 的 vulnerability scanning
最终建议
Serverless 并不意味着"没有安全"。实施最小权限 IAM,验证所有 输入,妥善管理 secrets,并进行全面监控。使用 IaC(Serverless Framework、SAM)以确保一致性与可审查性。将 security scanning 集成到 CI/CD 中。Serverless 扩大了攻击面——每一个 event source 和集成点都是潜在的攻击向量。
