计划执行与检查节点
executing-plans
按既定实施计划完成工作,保持过程检查和反馈。
securing-serverless-functions【效率与协作】本技能涵盖 AWS Lambda、Azure Functions 和 Google Cloud Functions 等无服务器计算平台的安全加固,涉及最小权限 IAM 角色、依赖漏洞扫描、密钥管理集成、输入验证、函数 URL 认证以及运行时监控,以防范注入攻击、凭证窃取和供应链攻击。
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
不适用于:基于容器的计算安全(参见 securing-kubernetes-on-cloud)、API Gateway 配置(参见 implementing-cloud-waf-rules),或无服务器架构设计决策。
为每个 Lambda 函数分配独立的 IAM 角色,权限仅限于其实际访问的特定资源。切勿跨函数共享 IAM 角色。
# 为特定 Lambda 函数创建最小权限角色
aws iam create-role \
--role-name order-processor-lambda-role \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "lambda.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}'
# 附加范围化策略(而非 AmazonDynamoDBFullAccess)
aws iam put-role-policy \
--role-name order-processor-lambda-role \
--policy-name order-processor-policy \
--policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["dynamodb:PutItem", "dynamodb:GetItem"],
"Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/Orders"
},
{
"Effect": "Allow",
"Action": ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"],
"Resource": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/order-processor:*"
},
{
"Effect": "Allow",
"Action": ["secretsmanager:GetSecretValue"],
"Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:order-api-key-*"
}
]
}'
将环境变量中的明文凭证替换为密钥管理服务的引用。使用 Lambda 扩展或 SDK 调用在运行时获取密钥。
# 不安全的做法:硬编码凭证存储在环境变量中
# DB_PASSWORD = os.environ['DB_PASSWORD'] # 以明文存储在 Lambda 配置中
# 安全的做法:从 AWS Secrets Manager 获取并缓存
import boto3
from botocore.exceptions import ClientError
import json
_secret_cache = {}
def get_secret(secret_name):
if secret_name in _secret_cache:
return _secret_cache[secret_name]
client = boto3.client('secretsmanager')
response = client.get_secret_value(SecretId=secret_name)
secret = json.loads(response['SecretString'])
_secret_cache[secret_name] = secret
return secret
def lambda_handler(event, context):
db_creds = get_secret('production/database/credentials')
db_host = db_creds['host']
db_password = db_creds['password']
# 安全地使用凭证
# 为 Lambda 环境变量启用静态加密
aws lambda update-function-configuration \
--function-name order-processor \
--kms-key-arn arn:aws:kms:us-east-1:123456789012:key/key-id
在 CI/CD 流水线中集成自动化依赖扫描,在部署前发现存在漏洞的包。
# 针对 Node.js Lambda 函数的 npm audit
cd lambda-function/
npm audit --audit-level=high
npm audit fix
# CI/CD 流水线中的 Snyk 扫描
snyk test --severity-threshold=high
snyk monitor --project-name=order-processor-lambda
# 针对 Python Lambda 函数的 pip-audit
pip-audit -r requirements.txt --desc on --fix
# 使用 Trivy 扫描 Lambda 部署包
trivy fs --severity HIGH,CRITICAL ./lambda-package/
# GitHub Actions CI/CD 安全扫描
name: Lambda Security Scan
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: npm ci
- name: Run npm audit
run: npm audit --audit-level=high
- name: Snyk vulnerability scan
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
- name: Scan with Semgrep for code vulnerabilities
uses: returntocorp/semgrep-action@v1
with:
config: p/owasp-top-ten
对所有事件输入数据进行验证和清洗,防止通过 Lambda 事件源进行的 SQL 注入、命令注入和 NoSQL 注入攻击。
import re
import json
from jsonschema import validate, ValidationError
# 定义预期的输入 Schema
ORDER_SCHEMA = {
"type": "object",
"properties": {
"orderId": {"type": "string", "pattern": "^[a-zA-Z0-9-]{1,36}quot;},
"customerId": {"type": "string", "pattern": "^[a-zA-Z0-9]{1,20}quot;},
"amount": {"type": "number", "minimum": 0.01, "maximum": 999999.99},
"currency": {"type": "string", "enum": ["USD", "EUR", "GBP"]}
},
"required": ["orderId", "customerId", "amount", "currency"],
"additionalProperties": False
}
def lambda_handler(event, context):
# 验证 API Gateway 事件 body
try:
body = json.loads(event.get('body', '{}'))
validate(instance=body, schema=ORDER_SCHEMA)
except (json.JSONDecodeError, ValidationError) as e:
return {
'statusCode': 400,
'body': json.dumps({'error': '输入无效', 'details': str(e)})
}
# 验证通过后可安全继续
order_id = body['orderId']
# 对数据库操作使用参数化查询
为函数调用端点配置适当的认证。切勿在没有 IAM 或 Cognito 认证的情况下暴露 Lambda 函数 URL。
# 使用 IAM 认证保护 Lambda 函数 URL(不使用 NONE)
aws lambda create-function-url-config \
--function-name order-processor \
--auth-type AWS_IAM \
--cors '{
"AllowOrigins": ["https://app.company.com"],
"AllowMethods": ["POST"],
"AllowHeaders": ["Content-Type", "Authorization"],
"MaxAge": 3600
}'
# 带 Cognito 授权器的 API Gateway
aws apigateway create-authorizer \
--rest-api-id abc123 \
--name CognitoAuth \
--type COGNITO_USER_POOLS \
--provider-arns "arn:aws:cognito-idp:us-east-1:123456789012:userpool/us-east-1_EXAMPLE"
配置 GuardDuty Lambda 网络活动监控和 CloudWatch 结构化日志,检测函数异常行为。
# 启用 GuardDuty Lambda 保护
aws guardduty update-detector \
--detector-id <detector-id> \
--features '[{"Name": "LAMBDA_NETWORK_ACTIVITY_LOGS", "Status": "ENABLED"}]'
# 配置 Lambda 使用结构化日志
aws lambda update-function-configuration \
--function-name order-processor \
--logging-config '{"LogFormat": "JSON", "ApplicationLogLevel": "INFO", "SystemLogLevel": "WARN"}'
| 术语 | 定义 |
|---|---|
| 冷启动(Cold Start) | 包含容器预配的初次函数调用,会增加延迟,并产生缓存密钥可能尚不可用的窗口期 |
| 事件注入(Event Injection) | 在来自 API Gateway、S3、SQS 或其他事件源的 Lambda 事件数据中嵌入恶意输入以利用函数的攻击方式 |
| 执行角色(Execution Role) | Lambda 在执行期间承担的 IAM 角色,定义函数可以使用的所有云 API 权限 |
| 函数 URL(Function URL) | Lambda 函数的直接 HTTPS 端点,可配置 IAM 认证或无认证(NONE 不安全) |
| 层(Layer) | 包含共享代码或依赖项的 Lambda 部署包,应独立进行漏洞扫描 |
| 预留并发(Reserved Concurrency) | 函数的最大并发执行数,用于防止资源耗尽攻击 |
| 预置并发(Provisioned Concurrency) | 预初始化的函数实例,降低冷启动延迟并确保密钥已缓存 |
场景背景:一个 Lambda 函数从 API Gateway 接收用户输入,并通过字符串拼接构造 SQL 查询,针对 RDS PostgreSQL 数据库执行。攻击者通过 API 注入 SQL Payload。
方法:
python.django.security.injection.sql 规则集部署 Semgrep常见陷阱:仅依赖 WAF 规则而不修复底层代码漏洞,攻击者可通过编码技巧绕过。不正确地使用 ORM 方法(原始查询)仍然允许注入攻击。
无服务器安全评估报告
=======================================
账户: 123456789012
已评估函数数: 47
评估日期: 2025-02-23
严重发现:
[SLS-001] order-processor: 通过字符串拼接实施的 SQL 注入
语言: Python 3.12 | 运行时: Lambda
漏洞代码: f"SELECT * FROM orders WHERE id = '{order_id}'"
修复建议: 使用 psycopg2 的参数化查询
[SLS-002] payment-handler: 环境变量中硬编码的 Stripe API 密钥
密钥: sk_live_XXXX...(未加密)
修复建议: 迁移到使用 KMS 加密的 AWS Secrets Manager
高危发现:
[SLS-003] 12 个函数共享同一个具有 s3:* 权限的 IAM 执行角色
[SLS-004] 8 个函数的函数 URL AuthType 为 NONE
[SLS-005] 23 个函数包含已知高危 CVE 的依赖项
依赖漏洞:
axios@0.21.1: CVE-2023-45857(高危)- 影响 5 个函数
jsonwebtoken@8.5.1: CVE-2022-23529(严重)- 影响 3 个函数
lodash@4.17.15: CVE-2021-23337(高危)- 影响 11 个函数
摘要:
严重: 2 | 高危: 5 | 中危: 12 | 低危: 8
具有最小权限的函数: 14/47 (30%)
使用 Secrets Manager 的函数: 19/47 (40%)
具有输入验证的函数: 22/47 (47%)