关于 performing-serverless-function-security-review
面向云安全人员的无服务器函数安全审查技能,指导盘点函数、检查权限与机密、审阅代码并运行自动化扫描。内容覆盖 AWS、Azure 和 Google Cloud 的相关审查流程。
主要功能
- 01盘点无服务器函数配置
- 02审查执行角色和访问控制
- 03检查环境变量中的机密
- 04分析函数代码安全问题
- 05使用 Checkov 和 Prowler 扫描
适用场景
- 01生产部署前审计无服务器应用
- 02调查函数配置或日志中的数据暴露
- 03评估执行角色被攻陷后的影响范围
- 04记录合规审查中的安全控制
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill performing-serverless-function-security-review安装后在 Claude Code 中输入/performing-serverless-function-security-review确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEreferences/api-reference.mdscripts/agent.py详细介绍
执行无服务器函数安全审查
适用场景
- 在生产部署前审计无服务器应用
- 调查是否通过函数环境变量或日志泄露了数据
- 评估无服务器函数执行角色遭到入侵后的影响范围
- 合规审查要求记录无服务器安全控制措施
- 构建默认安全的无服务器部署模板
请勿用于容器或虚拟机安全评估(请使用容器扫描工具)、API 安全测试(请在 API Gateway 层使用 DAST 工具),或无服务器威胁实时检测(请使用搭载安全 Agent 的 AWS Lambda Extensions)。
先决条件
- 已配置 AWS CLI、Azure CLI 和 gcloud CLI,并具有适当的权限
- 可读取函数配置、策略和执行角色
- 用于自动扫描无服务器安全问题的 Prowler 或 Checkov
- 用于本地分析函数的 SAM CLI 或 Serverless Framework
- 已启用 CloudTrail、Azure Monitor 或 Cloud Audit Logs,以监控函数调用
工作流
步骤 1:枚举所有无服务器函数及其配置
列出所有云服务提供商中的函数及其运行时、内存、超时和网络设置。
# AWS Lambda: List all functions with key security attributes
aws lambda list-functions \
--query 'Functions[*].[FunctionName,Runtime,MemorySize,Timeout,Role,VpcConfig.VpcId,Layers[*].Arn]' \
--output table
# Check for functions using deprecated runtimes
aws lambda list-functions \
--query 'Functions[?Runtime==`python3.7` || Runtime==`nodejs14.x` || Runtime==`dotnetcore3.1`].[FunctionName,Runtime]' \
--output table
# Azure Functions: List all function apps
az functionapp list \
--query "[].{Name:name, Runtime:siteConfig.linuxFxVersion, ResourceGroup:resourceGroup, HttpsOnly:httpsOnly}" \
-o table
# GCP Cloud Functions: List all functions
gcloud functions list \
--format="table(name, runtime, status, httpsTrigger.url, serviceAccountEmail, vpcConnector)"
步骤 2:审计执行角色权限
检查分配给函数的 IAM 角色是否存在权限过于宽泛的策略。
# AWS: Check each Lambda function's execution role
for func in $(aws lambda list-functions --query 'Functions[*].FunctionName' --output text); do
role_arn=$(aws lambda get-function-configuration --function-name "$func" --query 'Role' --output text)
role_name=$(echo "$role_arn" | awk -F'/' '{print $NF}')
echo "=== $func -> $role_name ==="
# List attached policies
aws iam list-attached-role-policies --role-name "$role_name" \
--query 'AttachedPolicies[*].[PolicyName,PolicyArn]' --output table
# Check for wildcard actions
for policy_arn in $(aws iam list-attached-role-policies --role-name "$role_name" --query 'AttachedPolicies[*].PolicyArn' --output text); do
version=$(aws iam get-policy --policy-arn "$policy_arn" --query 'Policy.DefaultVersionId' --output text)
aws iam get-policy-version --policy-arn "$policy_arn" --version-id "$version" \
--query 'PolicyVersion.Document' --output json | python3 -c "
import json, sys
doc = json.load(sys.stdin)
for stmt in doc.get('Statement', []):
actions = stmt.get('Action', [])
if isinstance(actions, str): actions = [actions]
resources = stmt.get('Resource', [])
if isinstance(resources, str): resources = [resources]
if '*' in actions or any(a.endswith(':*') for a in actions):
print(f' WARNING: {stmt[\"Effect\"]} {actions} on {resources}')
" 2>/dev/null
done
done
步骤 3:检查环境变量中的密钥
扫描函数环境变量,查找硬编码凭据、API 密钥和数据库连接字符串。
# AWS Lambda: Extract environment variables
for func in $(aws lambda list-functions --query 'Functions[*].FunctionName' --output text); do
envvars=$(aws lambda get-function-configuration --function-name "$func" \
--query 'Environment.Variables' --output json 2>/dev/null)
if [ "$envvars" != "null" ] && [ -n "$envvars" ]; then
echo "=== $func ==="
echo "$envvars" | python3 -c "
import json, sys, re
vars = json.load(sys.stdin)
sensitive_patterns = [
r'(?i)(password|secret|key|token|credential|api.?key)',
r'(?i)(aws.?access|aws.?secret)',
r'(?i)(database.?url|connection.?string|db.?pass)',
r'AKIA[0-9A-Z]{16}'
]
for key, value in vars.items():
for pattern in sensitive_patterns:
if re.search(pattern, key) or re.search(pattern, str(value)):
masked = value[:4] + '****' + value[-4:] if len(value) > 8 else '****'
print(f' SENSITIVE: {key} = {masked}')
break
"
fi
done
# Azure Functions: Check app settings
for app in $(az functionapp list --query "[].name" -o tsv); do
rg=$(az functionapp show --name "$app" --query "resourceGroup" -o tsv)
echo "=== $app ==="
az functionapp config appsettings list \
--name "$app" --resource-group "$rg" \
--query "[?contains(name,'KEY') || contains(name,'SECRET') || contains(name,'PASSWORD')].{Name:name}" \
-o table 2>/dev/null
done
步骤 4:审查函数触发器和访问控制
验证函数触发器是否具有适当的身份验证和授权机制。
# AWS: Check for unauthenticated Lambda function URLs
aws lambda list-function-url-configs \
--function-name FUNCTION_NAME \
--query 'FunctionUrlConfigs[*].[FunctionUrl,AuthType,Cors]' --output table
# Check for resource-based policies allowing public invocation
for func in $(aws lambda list-functions --query 'Functions[*].FunctionName' --output text); do
policy=$(aws lambda get-policy --function-name "$func" --query 'Policy' --output text 2>/dev/null)
if [ -n "$policy" ]; then
echo "$policy" | python3 -c "
import json, sys
doc = json.loads(sys.stdin.read())
for stmt in doc.get('Statement', []):
principal = stmt.get('Principal', {})
if principal == '*' or principal == {'AWS': '*'}:
print(f'WARNING: $func has public invoke policy: {stmt.get(\"Sid\", \"unnamed\")}')" 2>/dev/null
fi
done
# GCP: Check for unauthenticated Cloud Functions
gcloud functions list --format=json | python3 -c "
import json, sys
functions = json.load(sys.stdin)
for func in functions:
name = func.get('name', '').split('/')[-1]
trigger = func.get('httpsTrigger', {})
if trigger and func.get('ingressSettings') == 'ALLOW_ALL':
print(f'WARNING: {name} allows all ingress traffic')
"
步骤 5:分析函数代码中的安全漏洞
检查函数代码中常见的无服务器安全问题。
# Download Lambda function code for review
aws lambda get-function --function-name FUNCTION_NAME \
--query 'Code.Location' --output text | xargs curl -o function.zip
unzip function.zip -d function-code/
# Scan with Bandit (Python) or ESLint security plugin (Node.js)
# Python functions
pip install bandit
bandit -r function-code/ -f json -o bandit-results.json
# Node.js functions
npm install -g eslint @microsoft/eslint-plugin-sdl
eslint --ext .js function-code/
# Check for common serverless vulnerabilities:
# 1. SQL injection in database queries
# 2. Command injection via os.system or subprocess
# 3. Insecure deserialization
# 4. Event data injection (untrusted event parameters)
# 5. Excessive function permissions
grep -rn "os.system\|subprocess\|eval(\|exec(" function-code/ || echo "No obvious injection patterns"
grep -rn "pickle.loads\|yaml.load\b" function-code/ || echo "No deserialization risks"
步骤 6:运行自动化无服务器安全扫描
运行 Checkov 和 Prowler,对无服务器资源执行自动化合规性检查。
# Checkov scan for serverless frameworks
checkov -d ./serverless-project/ \
--framework serverless \
--output json > checkov-serverless.json
# Prowler Lambda-specific checks
prowler aws \
--checks lambda_function_no_secrets_in_variables \
lambda_function_url_auth_type \
lambda_function_using_supported_runtimes \
lambda_function_not_publicly_accessible \
-M json-ocsf \
-o ./prowler-lambda/
核心概念
| 术语 | 定义 |
|---|---|
| 执行角色 | 无服务器函数在执行期间担任的 IAM 角色,用于定义函数可以访问哪些 AWS/云资源 |
| 事件注入 | 无服务器环境特有的一种攻击:在事件触发负载中的不可信数据被函数逻辑不安全地使用 |
| 函数 URL | 用于调用 Lambda 函数的直接 HTTP(S) 端点,无需经过 API Gateway,且可能未配置身份验证 |
| 冷启动 | 函数首次执行时需要配置容器;期间安全 Agent 和扩展必须完成初始化 |
| 基于资源的策略 | 直接附加到函数的策略,用于定义哪些主体可以调用函数,与执行角色相互独立 |
| Secrets Manager 集成 | 从密钥管理服务获取敏感配置,而非将其存储在环境变量中的模式 |
工具与系统
- AWS Lambda:主要的无服务器计算平台,提供执行角色、层和资源策略
- Checkov:用于基础设施即代码静态分析的工具,提供无服务器专用安全策略
- Prowler:云安全工具,提供针对 Lambda 权限、公开访问和运行时版本的专用检查
- Bandit:用于检测函数源代码安全问题的 Python 静态分析工具
- OWASP Serverless Top 10:面向无服务器架构的安全风险框架
常见场景
场景:具有管理员角色的 Lambda 函数通过环境变量泄露机密
背景:安全审查发现一个 Lambda 函数使用 AdministratorAccess 执行角色,且数据库凭据以明文形式存储在环境变量中,可在 CloudWatch 日志中查看。
处理方法:
- 列举函数的执行角色,并发现
AdministratorAccess托管策略 - 检查环境变量,发现其中以明文形式存储了
DB_PASSWORD、API_KEY和STRIPE_SECRET_KEY - 查看 CloudWatch 日志,发现凭据被打印在调试日志语句中
- 创建范围受限的 IAM 策略,仅授予所需的特定 DynamoDB 和 S3 操作权限
- 将机密迁移到 AWS Secrets Manager,并更新函数以便在运行时获取机密
- 移除会输出敏感数据的调试日志
- 轮换所有已暴露的凭据,并使用 KMS 启用 Lambda 函数加密
注意事项:更改函数的执行角色可能会导致函数因新角色权限过于严格而无法正常运行。请先在暂存环境中进行测试。更改环境变量会触发新的函数版本,因此请确保更新别名和触发器。Secrets Manager 调用会增加延迟;请在执行上下文中缓存机密,避免每次调用都查询。
输出格式
Serverless Function Security Review
=======================================
Account: 123456789012
Functions Reviewed: 34
Review Date: 2026-02-23
CRITICAL FINDINGS:
[SRVL-001] Overly Permissive Execution Role
Function: payment-processor
Role: AdministratorAccess (full AWS access)
Required Permissions: DynamoDB:PutItem, S3:GetObject (2 actions)
Remediation: Create scoped policy with only required permissions
[SRVL-002] Secrets in Environment Variables
Function: payment-processor
Variables: DB_PASSWORD, STRIPE_SECRET_KEY, API_KEY
Risk: Visible in console, API, and CloudWatch logs
Remediation: Migrate to Secrets Manager, remove from env vars
SUMMARY:
Functions with admin roles: 3 / 34
Functions with secrets in env vars: 8 / 34
Functions with deprecated runtimes: 5 / 34
Functions with public access: 2 / 34
Functions without VPC: 28 / 34
Functions with wildcard permissions: 12 / 34
评论
支持 Markdown