אבטחת Serverless
ארכיטקטורות serverless מבטלות את ניהול השרתים אך מציגות אתגרים חדשים: הרשאות ברמת הפונקציה, event injection, פגיעויות בתלויות ומשטח תקיפה מורחב.
מודל האחריות המשותפת
הספק (AWS/Azure/GCP)
- אבטחה פיזית ותשתית
- Runtime environment
- בידוד בין functions
- טלאי מערכת ההפעלה
הלקוח (אתה)
- קוד ה-function
- תלויות וספריות
- הרשאות IAM
- הצפנת נתונים
- תצורת API Gateway
- Logging ו-monitoring
OWASP Serverless Top 10
- Injection Flaws: SQLi, command injection ב-event data
- Broken Authentication: ניהול לקוי של tokens, 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 ו-Least Privilege
לכל 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: לעולם אל תשתף roles בין functions
- Resource-level permissions: ציין ARNs מדויקים, לא wildcards
- Time-based access: השתמש ב-AWS STS עבור credentials זמניים
- Deny by default: אפשר במפורש רק את הנדרש
Secrets Management
- 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 עבור configs
- לעולם אל תקודד בקוד: Secrets בקוד או ב-repositories
דוגמה ל-AWS Lambda + Secrets Manager
import boto3
import json
def lambda_handler(event, context):
# אחזור secret מ-Secrets Manager
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
# ...
Input Validation ו-Sanitization
Events מ-API Gateway, S3, DynamoDB Streams וכו' חייבים להיות מאומתים באופן קפדני:
// 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 עבור reproducibility
- Private registries: אחסון תלויות מאושרות באופן פנימי
- SBOM: Software Bill of Materials עבור auditability
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 שניגשות למשאבים פרטיים צריכות לרוץ ב-VPC עם security groups מתאימים:
- Private subnets: Functions ללא גישה ישירה לאינטרנט
- NAT Gateway: עבור outbound internet access אם נדרש
- Security groups: Whitelisting של פורטים וכתובות IP
- VPC Endpoints: גישה פרטית לשירותי AWS (S3, DynamoDB)
Logging ו-Monitoring
- CloudWatch Logs: ריכוז לוגים מכל ה-functions
- CloudTrail: Audit trail של הפעלות ושינויים
- X-Ray: Distributed tracing עבור troubleshooting
- 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: Models ו-validators ב-API Gateway
- CORS: הגדרת origins מורשים
אבטחת Cold Start
Cold starts יכולים להיות מנוצלים עבור timing attacks. אמצעי הקלה:
- Provisioned concurrency עבור functions קריטיות
- צמצום package size לאתחול מהיר
- Lazy load של תלויות כבדות
- Warm-up schedules דרך CloudWatch Events
Runtime Security
- PureSec: Runtime protection עבור serverless
- Protego: Serverless security platform
- Twistlock: Prisma Cloud עבור serverless
- Snyk: Vulnerability scanning משולב ב-CI/CD
המלצות סופיות
Serverless אינו אומר "ללא אבטחה". יישם IAM של least privilege, אמת את כל הקלטים, נהל secrets כראוי ובצע ניטור מקיף. השתמש ב-IaC (Serverless Framework, SAM) לעקביות וסקירה. שלב security scanning ב-CI/CD. Serverless מרחיב את משטח התקיפה - כל event source ונקודת אינטגרציה הם וקטור פוטנציאלי.
