サーバーレスセキュリティ
サーバーレスアーキテクチャはサーバー管理を不要にしますが、新たな 課題をもたらします:関数レベルの権限、event injection、依存関係の脆弱性、そして 拡大した攻撃対象領域です。
責任共有モデル
プロバイダー(AWS/Azure/GCP)
- 物理セキュリティとインフラストラクチャ
- Runtime environment
- functions 間の分離
- オペレーティングシステムのパッチ適用
お客様(あなた)
- function のコード
- 依存関係とライブラリ
- IAM 権限
- データ暗号化
- API Gateway の構成
- Logging と monitoring
OWASP Serverless Top 10
- Injection Flaws: event data 内の SQLi、command injection
- Broken Authentication: token の不適切な管理、脆弱な authn
- 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 と最小権限
各 function には、必要最小限の権限を持つ専用の 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: functions 間で roles を決して共有しない
- Resource-level permissions: wildcards ではなく正確な ARNs を指定する
- Time-based access: 一時的な credentials には AWS STS を使用する
- Deny by default: 必要なものだけを明示的に allow する
Secrets Management
- AWS Secrets Manager: 自動ローテーション、encryption at rest
- Azure Key Vault: Managed HSM、access policies
- Environment variables encryption: env vars を暗号化するための KMS
- Parameter Store: 構成には AWS SSM Parameter Store
- 決してハードコードしない: コードや repositories 内の 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 を使用して DB に接続
# ...
入力検証とサニタイズ
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 の構成
プライベートリソースにアクセスする functions は、適切な security groups を持つ VPC で実行する必要があります:
- Private subnets: 直接のインターネットアクセスを持たない functions
- NAT Gateway: 必要に応じて outbound internet access のため
- Security groups: ポートと IP の whitelisting
- VPC Endpoints: AWS サービス(S3、DynamoDB)へのプライベートアクセス
Logging と Monitoring
- CloudWatch Logs: すべての functions のログを集中管理する
- 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: OWASP Top 10 に対する保護のための AWS WAF
- Request validation: API Gateway 内の models と validators
- CORS: 許可する origins を構成する
コールドスタートのセキュリティ
コールドスタートは timing attacks に悪用される可能性があります。緩和策:
- 重要な functions のための provisioned concurrency
- 高速な startup のための 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
最終的な推奨事項
サーバーレスは「セキュリティがない」という意味ではありません。最小権限の IAM を実装し、すべての 入力を検証し、secrets を適切に管理し、包括的に監視してください。一貫性とレビューのために IaC(Serverless Framework、SAM)を使用してください。security scanning を CI/CD に統合してください。サーバーレスは 攻撃対象領域を拡大します - すべての event source と統合ポイントが潜在的なベクトルです。
