Serverless / FaaS Security Cheat Sheet¶
Introduction / 介绍¶
Serverless computing (Functions as a Service — FaaS) platforms such as AWS Lambda, Azure Functions, and Google Cloud Functions simplify application development and scaling. However, the execution model (short-lived, event-driven functions running in managed environments) introduces unique security risks compared to traditional architectures.
无服务器计算(函数即服务 — FaaS)平台,如 AWS Lambda、Azure Functions 和 Google Cloud Functions,简化了应用程序的开发和扩展。然而,与传统的架构相比,其执行模型(在托管环境中运行短生命周期的、事件驱动的函数)引入了独特的安全风险。
This cheat sheet provides best practices to secure serverless applications and minimize attack surfaces.
本速查表提供了确保无服务器应用程序安全并最小化攻击面的最佳实践。
Key Risks / 主要风险¶
- Over-permissioned functions (broad IAM roles,
*policies).
中文:权限过高的函数(广泛的 IAM 角色,*策略)。 - Unvalidated event inputs (API Gateway, S3, Pub/Sub, IoT).
中文:未经验证的事件输入(API网关、S3、Pub/Sub、IoT) - Cold start data leakage (persistent state, side-channel timing).
中文:冷启动数据泄露(持久状态,旁路定时)。 - Function chaining abuse (compromised function invoking others).
中文:函数链滥用(受损害的函数调用其他函数)。 - Shared environment risks (multi-tenant leakage,
/tmpreuse).
中文:共享环境风险(多租户泄漏、/tmp重用) - Hardcoded secrets in code or platform config.
中文:代码或平台配置中硬编码的秘密。 - Excessive network access.
中文:过度网络访问。
Best Practices / 最佳实践¶
1. Principle of Least Privilege / 1. 最小权限原则¶
- Assign minimal IAM permissions to each function.
中文:为每个函数分配最少的 IAM 权限。 - Use role-per-function (avoid shared high-privilege roles).
中文:使用基于功能的角色(避免共享高权限角色) - Scope database/API keys to the smallest set of actions needed.
中文:将数据库/API密钥限制在所需的最小操作集。
Bad IAM Policy (too broad):
差的 IAM 策略(过于宽泛):
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
Good IAM Policy (scoped):
好的 IAM 策略(范围限定):
{
"Effect": "Allow",
"Action": ["dynamodb:GetItem", "dynamodb:PutItem"],
"Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/Orders"
}
2. Environment Isolation / 2. 环境隔离¶
- Disable default network access unless required (e.g. outbound internet access).
中文:除非需要,否则禁用默认网络访问(例如,出站互联网访问) - Place functions in private subnets with controlled egress.
中文:将功能放置在受控出口的私有子网中 - Isolate sensitive functions (e.g. payment, auth) from general-purpose ones.
中文:将敏感功能(例如,支付、认证)与通用功能隔离 - Separate production vs. staging environments with strict boundaries.
中文:通过严格的边界区分生产与测试环境
AWS Lambda VPC Config (restrictive):
AWS Lambda VPC 配置(限制性):
VpcConfig:
SubnetIds:
- subnet-123456
SecurityGroupIds:
- sg-restrict-outbound
3. Secure Function Invocation / 3. 安全函数调用¶
- Enforce authentication and authorization on all triggers (API Gateway, Pub/Sub, S3, IoT).
中文:在所有触发器(API网关、发布/订阅、S3、IoT)上强制执行身份验证和授权。 - Validate function-to-function calls with signed tokens or workload identities.
中文:使用签名令牌或工作负载身份验证验证函数间的调用。 - Apply rate limiting and throttling to mitigate DoS and abuse.
中文:应用速率限制和节流以减轻拒绝服务攻击和滥用。
API Gateway Authorizer Example (JWT validation):
API Gateway 认证器示例(JWT 验证):
{
"Type": "JWT",
"IdentitySource": "$request.header.Authorization",
"Issuer": "https://secure-idp.example.com/",
"Audience": "my-api-client"
}
4. Event Data Validation / 4. 事件数据验证¶
- Treat all event payloads as untrusted input.
中文:将所有事件有效负载视为不受信任的输入。 - Apply strong input validation & sanitization (length, type, format).
中文:应用强大的输入验证和清理(长度、类型、格式)。 - Protect against common injection attacks (SQLi, XSS, JSON injection, deserialization).
中文:保护常见注入攻击(SQL注入、XSS、JSON注入、反序列化) - Strip unnecessary fields and metadata before processing.
中文:在处理前删除不必要的字段和元数据
Example: Python input validation for Lambda
示例:Lambda的Python输入验证
import json
import re
def lambda_handler(event, context):
body = json.loads(event["body"])
email = body.get("email", "")
if not re.match(r"[^@]+@[^@]+\.[^@]+", email):
return {"statusCode": 400, "body": "Invalid email"}
# process safely
return {"statusCode": 200, "body": "OK"}
5. Cold Start & Execution Context Security / 5. 冷启动与执行上下文安全¶
- Do not assume function runtime context is clean between invocations.
中文:不要假设函数在调用之间运行时上下文是干净的 - Avoid storing secrets or temporary sensitive data in global/static variables.
中文:避免在全局/静态变量中存储密钥或临时敏感数据。 - Protect against side-channel leaks (timing differences, leftover files in /tmp).
中文:防止侧信道泄露(时间差异、/tmp中的残留文件)。 - For sensitive workloads, enforce single-use execution environments if the platform supports it.
中文:对于敏感工作负载,如果平台支持,强制执行单次使用的执行环境
Bad:
错误:
# Secret stays in global variable across invocations
SECRET_KEY = "hardcoded-secret"
Good:
正确:
import os
from my_secrets_lib import get_secret
def lambda_handler(event, context):
secret = get_secret("db-password") # fetch fresh each time
...
6. Secrets Management / 6. 密钥管理¶
See the Secrets Management Cheat Sheet for secret lifecycle controls.
查看密钥管理速查表以获取密钥生命周期控制信息。
- Fetch secrets at runtime from a vault or caching extension — not from platform-level function configuration (e.g. Lambda Environment Variables).
中文:在运行时从密钥库或缓存扩展中获取密钥,而不是从平台级功能配置(例如 Lambda 环境变量)中获取。 - Use ephemeral credentials (STS, workload identity federation).
中文:使用临时凭证(STS、工作负载身份联合)。 - Rotate secrets automatically.
中文:自动轮换密钥。
AWS Lambda Secret Fetch (Python via Parameters and Secrets Extension):
AWS Lambda 密钥获取(Python 通过参数和密钥扩展):
Note: Ensure that the AWS Lambda Parameters and Secrets Extension is added and enabled for your function (for example, as a Lambda layer). Otherwise, http://localhost:2773 will not be available and requests to it will fail.
注意: 确保已将 AWS Lambda 参数和密钥扩展添加并启用到您的函数中(例如,作为一个 Lambda 层)。否则,http://localhost:2773 将不可用,对其的请求将失败。
import os
import json
import urllib.request
import urllib.parse
def get_secret(secret_name):
"""
Retrieves a secret using the AWS Lambda Extension local endpoint.
This method is faster and more cost-effective due to local caching.
"""
# The extension provides a local HTTP endpoint on port 2773
encoded_name = urllib.parse.quote_plus(secret_name)
secrets_extension_endpoint = (
f"http://localhost:2773/secretsmanager/get?secretId={encoded_name}"
)
# Authenticate using the identity token provided by the Lambda environment.
# Fail fast if the token is missing to avoid confusing 4xx errors.
session_token = os.environ.get("AWS_SESSION_TOKEN")
if not session_token:
raise RuntimeError(
"Missing AWS_SESSION_TOKEN required for "
"Parameters and Secrets Extension authentication."
)
headers = {
"X-Aws-Parameters-Secrets-Token": session_token
}
request = urllib.request.Request(
secrets_extension_endpoint,
headers=headers,
method="GET"
)
with urllib.request.urlopen(request, timeout=3) as response:
if response.status != 200:
raise Exception(
f"Error retrieving secret: {response.read().decode('utf-8')}"
)
response_json = json.loads(response.read())
secret_string = response_json["SecretString"]
return json.loads(secret_string)
7. Monitoring & Logging / 7. 监控与日志记录¶
- Use centralized logging (CloudWatch, Azure Monitor, GCP Logging).
中文:使用集中式日志记录(CloudWatch、Azure Monitor、GCP Logging)。 - Mask secrets and PII.
中文:隐藏机密信息和PII。
Example: Redacting fields
示例:编辑字段
import logging
def log_event(event):
safe_event = {k: ("***" if "password" in k else v) for k,v in event.items()}
logging.info(safe_event)
8. Supply Chain Security / 8. 供应链安全¶
- Scan dependencies (
npm audit,pip-audit,safety).
中文:扫描依赖项(npm audit,pip-audit,safety)。 - Use minimal deployment packages.
中文:使用最小化部署包。 - Sign deployment packages and verify signatures against an approved publisher before deployment. A checksum alone does not authenticate the publisher.
中文:在部署前对部署包进行签名,并验证签名是否来自已批准的发布者。仅凭校验和不能验证发布者身份。
For AWS Lambda, use code signing configurations with allowed signing profiles and UntrustedArtifactOnDeployment set to Enforce; the default Warn setting allows deployments that fail expiry, publisher, or revocation checks. Layers added to functions with code signing enabled must also be signed by an allowed profile.
对于AWS Lambda,使用代码签名配置,允许的签名配置文件,并将UntrustedArtifactOnDeployment设置为Enforce;默认的Warn设置允许部署失败于过期、发布者或吊销检查。启用代码签名的函数中添加的层也必须由允许的配置文件签名。
Do’s and Don’ts / 做与不做¶
Do:
执行:
- Enforce least privilege per function.
中文:每个函数强制执行最小权限。 - Validate all event inputs.
中文:验证所有事件输入。 - Fetch secrets from vaults, not platform config.
中文:从密钥库中获取密钥,而不是平台配置。 - Restrict network egress.
中文:限制网络出口。 - Monitor invocations and logs.
中文:监控调用和日志。
Don’t:
不要:
- Hardcode secrets in code or configs.
中文:在代码或配置中硬编码密钥。 - Assume clean runtime between invocations.
中文:假设调用之间的运行时是干净的。 - Give
*IAM permissions.
中文:赋予*IAM 权限。 - Leave sensitive data in
/tmpor globals.
中文:不要将敏感数据留在/tmp或全局变量中。 - Trust event sources blindly.
中文:盲目信任事件源。
References / 参考¶
- AWS Lambda: Best practices) (AWS Lambda:最佳实践)
- Azure Functions: Security concepts) (Azure Functions:安全概念)
- Google Cloud Run: Security) (Google Cloud Run:安全)