Zum Inhalt springen

Services, Wiki-Artikel, Blog-Beiträge und Glossar-Einträge durchsuchen

↑↓NavigierenEnterÖffnenESCSchließen
Cloud-Sicherheit Glossar

Serverless Security - Sicherheit in FaaS-Umgebungen

Serverless Security bezeichnet die Absicherung von Function-as-a-Service (FaaS) Umgebungen wie AWS Lambda, Azure Functions und Google Cloud Functions. Angriffsvektoren: Event-Injection, überprivilegierte Rollen, unsichere Abhängigkeiten, Function-Level-Broken-Access-Control, Cold-Start-Timing-Angriffe und zu lange Timeouts. Schutz: OWASP Serverless Top 10, minimale IAM-Rechte, Layer-Validierung, Dependency-Scanning.

Serverless Security bezeichnet die Absicherung von Function-as-a-Service (FaaS) Umgebungen, in denen Code ohne Serververwaltung in kurzlebigen Containern ausgeführt wird. Das Serverless-Modell verändert die Angriffsfläche grundlegend: Kein OS-Patching, aber neue Risiken durch Event-basierte Trigger, IAM-Fehlkonfigurationen und die Komplexität vieler kleiner Funktionen.

Serverless Angriffsfläche

Typische Serverless-Architektur (AWS Lambda)

Eine typische Serverless-Architektur verbindet verschiedene Event-Quellen mit Lambda-Funktionen und nachgelagerten Services, beispielsweise:

  • API Gateway → Lambda-Funktion → DynamoDB
  • S3-Upload → Lambda-Funktion → SQS-Queue
  • IoT-Event → Lambda-Funktion → RDS
  • SNS-Message → Lambda-Funktion → SES (E-Mail)

Angriffsvektoren

  1. Event Injection: Bösartiger Input via API Gateway, S3 oder SQS
  2. IAM-Fehlkonfiguration: Lambda-Rolle mit zu vielen Rechten
  3. Unsichere Dependencies: npm/pip-Pakete mit bekannten Schwachstellen
  4. Secrets in Env-Vars: Zugangsdaten direkt in der Funktion hinterlegt
  5. Verbose Logging: Sensible Daten in CloudWatch-Logs
  6. ZIP-Path-Traversal: Manipulation des Deployment-Packages

OWASP Serverless Top 10

IDBezeichnung
SAS-1Function Event-Data Injection
SAS-2Broken Authentication
SAS-3Insecure Serverless Deployment Configuration
SAS-4Over-Privileged Function Permissions and Roles
SAS-5Inadequate Function Monitoring and Logging
SAS-6Insecure Third-Party Dependencies
SAS-7Insecure Application Secrets Storage
SAS-8Denial of Service via Reserved Concurrency
SAS-9Serverless Business Logic Manipulation
SAS-10Improper Exception Handling and Verbose Error Messages

SAS-1: Event-Data-Injection

Der Angriff nutzt aus, dass Lambda-Funktionen Daten aus externen Event-Quellen oft ungeprüft verarbeiten. Ein Angreifer sendet an API Gateway manipulierte Eingaben, die z.B. SQL-Injection enthalten:

POST /api/users
{"userId": "1 OR 1=1--"}

Eine unsichere Lambda-Funktion (Python) würde den Input direkt in die Query einbauen:

def handler(event, context):
    user_id = event['body']['userId']
    query = f"SELECT * FROM users WHERE id = {user_id}"
    # → SQL-Injection!
    result = db.execute(query)

Die sichere Version verwendet parameterisierte Queries:

def handler(event, context):
    user_id = event['body']['userId']
    query = "SELECT * FROM users WHERE id = %s"
    result = db.execute(query, (user_id,))

Weitere Injektionsvektoren sind S3-Event-Trigger (bösartige Dateinamen wie ../../../../etc/passwd, die Path-Traversal-Operationen auslösen - Schutz: os.path.basename()) und SNS/SQS-Nachrichten, bei denen bei SSRF in einem anderen Service eine interne Event-Injektion möglich ist.

SAS-4: Überprivilegierte Rollen

Ein häufig gesehenes problematisches Beispiel:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": "*",
    "Resource": "*"
  }]
}

Diese Konfiguration gibt der Lambda-Funktion vollen AWS-Admin-Zugriff. Bei einer RCE-Schwachstelle in der Funktion ist damit das komplette AWS-Konto kompromittiert. Der Angriff verläuft typischerweise so: Eine Injection-Schwachstelle wird gefunden, dann wird der AWS Metadata-Service abgefragt (bei IMDSv1 über http://169.254.169.254/latest/meta-data/iam/security-credentials/), worüber temporäre AWS Credentials der Lambda-Rolle extrahiert werden. Mit diesen Credentials können dann S3-Buckets geleert, EC2-Instanzen gestartet und weitere Ressourcen missbraucht werden.

Least-Privilege Beispiel

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["dynamodb:GetItem", "dynamodb:PutItem"],
      "Resource": "arn:aws:dynamodb:eu-west-1:123456789:table/users"
    },
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject"],
      "Resource": "arn:aws:s3:::my-bucket/uploads/*"
    }
  ]
}

Das Tool IAMzero analysiert CloudTrail-Logs, erkennt welche Rechte tatsächlich genutzt werden, und generiert daraus eine minimale IAM-Policy.

AWS-Empfehlung: IMDSv2 enforzen, um SSRF auf den Metadata-Service zu verhindern:

aws lambda put-function-configuration \
  --function-name my-function \
  --description "IMDSv2 required"
# Auch: Instance-Metadata-Hop-Limit = 1 in Lambda-Config

SAS-7: Secrets-Management

Umgebungsvariablen in Lambda sind nur Base64-codiert, nicht verschlüsselt. Konsolen-Zugriff auf Lambda → Configuration zeigt Passwörter im Klartext. CloudFormation-Templates, die in Git landen, exponieren Secrets für alle mit Repository-Zugriff.

Ein schlechtes Muster ist das Hardcoden von Secrets:

def handler(event, context):
    DB_PASSWORD = "geheimespasswort123"  # Im Source-Code!
    API_KEY = os.environ['API_KEY']      # Sichtbar in Lambda-Console!

Gutes Muster 1 - AWS Secrets Manager:

import boto3

_cached_secret = None

def get_secret(secret_name):
    client = boto3.client('secretsmanager')
    response = client.get_secret_value(SecretId=secret_name)
    return json.loads(response['SecretString'])

def handler(event, context):
    global _cached_secret
    if _cached_secret is None:
        _cached_secret = get_secret('myapp/production/database')
    db_password = _cached_secret['password']

Das Caching beim Cold Start ist wichtig, damit nicht bei jedem Funktionsaufruf ein API-Call an Secrets Manager erfolgt.

Gutes Muster 2 - AWS Parameter Store (günstiger):

ssm = boto3.client('ssm')
password = ssm.get_parameter(
    Name='/myapp/database/password',
    WithDecryption=True  # KMS-verschlüsselt!
)['Parameter']['Value']

Mittelmäßig - Encrypted Environment Variables: KMS-Key für Lambda konfigurieren verschlüsselt Env-Vars im Ruhezustand, sie sind jedoch im Klartext sichtbar, wenn die Funktion ausgeführt wird.

Denial-of-Service via Reserved Concurrency

AWS Lambda hat standardmäßig ein Limit von 1000 simultanen Ausführungen pro Account (erhöhbar). Wird dieses Limit erreicht, werden alle anderen Lambdas im Account throttled. Ein Angreifer kann durch Senden von 1000+ parallelen Requests an eine Funktion ohne Concurrency-Limit einen “Account-weiten DoS” auslösen, bei dem alle anderen Dienste offline gehen.

Schutzmaßnahmen

# Reserved Concurrency setzen:
aws lambda put-function-concurrency \
  --function-name api-handler \
  --reserved-concurrent-executions 100

Zusätzlich helfen Provisioned Concurrency für kritische Funktionen, API Gateway Throttling-Limits (z.B. 1000 RPS, Burst 5000), und eine WAF vor dem API Gateway für Rate-Limiting pro IP.

Monitoring und Audit

CloudWatch und Lambda Insights

Metriken wie Duration, Memory, Cold Starts und Error Rate überwachen. Alarme bei ungewöhnlichen Mustern einrichten, z.B. Duration-Spikes als Indiz für einen laufenden Angriff.

CloudTrail

Lambda:CreateFunction und Lambda:UpdateFunctionCode überwachen: Wer deployed? Lambda:InvokeFunction: Ungewöhnliche Aufrufer?

Powertools for Lambda (AWS)

from aws_lambda_powertools import Logger, Tracer, Metrics

logger = Logger(service="api-handler")
tracer = Tracer(service="api-handler")

@logger.inject_lambda_context(log_event=True)
@tracer.capture_lambda_handler
def handler(event, context):
    user_id = event.get('requestContext', {}).get('authorizer', {}).get('principalId')
    logger.info("Processing request", extra={"user_id": user_id})
    # Structured logs → CloudWatch → SIEM

Falco für Serverless (Runtime Security): Erkennt unerwartete Syscalls und Netzwerkverbindungen aus Lambda, Integration über Lambda-Layer.

SBOM für Dependencies: cyclonedx-python für Python-Lambdas, @cyclonedx/cyclonedx-npm für Node.js-Lambdas - automatisch bei jedem Deploy scannen (Snyk, OWASP Dependency-Check).

Serverless Security Checkliste

IAM

  • Least-Privilege-Rolle pro Funktion (nie AdministratorAccess!)
  • IAMzero oder Access Analyzer nutzen um ungenutzte Rechte zu finden
  • Keine Wildcard-Actions (*) in IAM-Policies
  • Kein Resource: "*" wenn spezifische ARNs möglich sind
  • IMDSv2 enforzen (Token-basiert, verhindert SSRF)

Secrets

  • Kein Secret in Environment Variables im Klartext
  • Kein Secret im Source Code oder CloudFormation-Template
  • Secrets Manager oder Parameter Store (SecureString) verwenden
  • Secrets regelmäßig rotieren (Secrets Manager kann automatisch rotieren)

Code-Sicherheit

  • Input-Validierung aller Event-Daten (API Gateway Events, S3 Events etc.)
  • Parameterized Queries für DB-Zugriffe
  • Dependency-Scanning (Snyk, npm audit) in CI/CD
  • SAST im Pull-Request-Workflow

Deployment

  • ZIP-Integrität prüfen (Code-Signing für Lambda aktivieren)
  • VPC-Konfiguration wenn DB-Zugriff nötig (nicht öffentlich!)
  • Reserved Concurrency setzen (DoS-Schutz)
  • API Gateway WAF aktivieren (AWS WAF)

Monitoring

  • CloudTrail in allen Regionen (Lambda-Management-Events)
  • Alarme für Fehlerrate, Duration, Throttling und Cold-Start-Spikes
  • Structured Logging ohne PII in Logs
  • Dead Letter Queue (DLQ) für fehlgeschlagene Invocations konfigurieren

Cookielose Analyse via Matomo (selbst gehostet, kein Tracking-Cookie). Datenschutzerklärung