Skip to main content

10 Best Practices für Serverless-Sicherheit

31. Mai 2019

0 Min. Lesezeit

In dieser Ausgabe unserer Cheat-Sheet-Reihe stellen wir Best Practices vor, mit denen Sie Ihre Serverless-Bereitstellungen absichern.

Dann legen wir gleich mit unserer Liste der 10 Best Practices für Serverless-Sicherheit los.

Falls Sie es noch nicht getan haben, laden Sie dieses Cheat Sheet jetzt herunter und hängen Sie es auf – damit Sie auch künftig sichere Entscheidungen treffen!

Viele Beispiele und Anwendungsfälle beziehen sich auf AWS Lambda, gelten aber ebenso für andere Cloud- und Serverless-Anbieter. Eine Referenzliste finden Sie in der CNCF Landscape.

Dann legen wir gleich mit unserer Liste der 10 Best Practices für Serverless-Sicherheit los.

1. Abhängigkeiten von Funktionen patchen

Function-as-a-Service-Plattformen (FaaS) übernehmen zwar das Patchen der Betriebssystem-Abhängigkeiten für Sie, sichern aber nicht Ihre Anwendungsabhängigkeiten ab, etwa jene aus npm, PyPI, Maven und ähnlichen Quellen. Diese Bibliotheken sind genauso weit verbreitet und anfällig wie Betriebssystem-Abhängigkeiten. Als Eigentümer der Anwendung sind Sie dafür verantwortlich, sie zu aktualisieren oder zu patchen, sobald eine Schwachstelle darin bekannt wird.

Verwenden Sie eine Lösung wie Snyk, um Serverless-Projekte auf bekannte Schwachstellen in Open-Source-Abhängigkeiten zu prüfen. Snyk erstellt nicht nur Berichte zu Schwachstellen, sondern gibt auch Empfehlungen zur Behebung und setzt Korrekturen automatisch durch Versions-Upgrades und Sicherheitspatches um.

Mit den Snyk-Tools schützen Sie Funktionen über den gesamten Entwicklungszyklus hinweg: angefangen in der integrierten Entwicklungsumgebung (IDE) mit unserem Plugin für VSCode oder IntelliJ, über die Integration mit der GitHub-App, mit der Snyk automatisch Pull Requests zur Behebung neu entdeckter Sicherheitslücken erstellt, bis hin zum Abbrechen von Continuous-Integration-Builds (CI), damit bei neu eingeführten Sicherheitslücken keine Bereitstellungen erfolgen.

Sichere Bereitstellungen für Funktionen durchsetzen

Neben der CI- und Quellcode-Repository-Überwachung sowie dem proaktiven Patchen von Sicherheitslücken sollte auch der Bereitstellungs-Workflow einer Funktion einer Sicherheitsprüfung unterzogen werden. Werden bei der Bereitstellung Schwachstellen in Funktionen gefunden, sollte die Bereitstellung abgebrochen werden.

Das Serverless Framework ist ein weit verbreitetes Toolkit zum Entwickeln und Bereitstellen von Serverless-Funktionen. Dank seiner Plugin-Architektur lassen sich benutzerdefinierte Workflows in den Lebenszyklus einer Funktion integrieren. Snyk bietet ein Open-Source-Serverless-Plugin, das sich nahtlos in das Framework einfügt.

Das folgende Bild zeigt, wie das Plugin aktiv verhindert, dass eine Funktion bereitgestellt wird, weil Sicherheitslücken in den Open-Source-Abhängigkeiten erkannt wurden:

Terminal mit den Ergebnissen eines Snyk-Scans des Serverless Frameworks, der Schwachstellen in mehreren Abhängigkeiten aufzeigt.

Weitere Informationen zur Einrichtung des Snyk-Plugins für das Serverless Framework sowie zum Erstellen von Projektsnapshots für CI/CD-Workflows und zur Überwachung Ihrer Projekte finden Sie in diesem Beitrag: Serverless-Framework-Plugin einrichten.

2. Das Prinzip der minimalen Berechtigungen anwenden

Funktionen sind klein, sodass sich die Berechtigungen für jede Funktion auf das absolute Minimum beschränken lassen – gewähren Sie nur den Zugriff, den die jeweilige Funktion für ihren ordnungsgemäßen Betrieb benötigt. Dadurch werden die möglichen Schäden eines erfolgreichen Angriffs erheblich begrenzt und die Angriffsfläche einer Integration aus mehreren Funktionen verkleinert. Die meisten Funktionen benötigen beispielsweise wahrscheinlich keinen Datenbankzugriff oder keine Berechtigung, sich mit externen Servern zu verbinden. Beides sind typische Aktionen, die Angreifer und böswillige Nutzer nach einem erfolgreichen Angriff ausführen.

Halten Sie sich an das Prinzip der minimalen Berechtigungen. Stellen Sie Ihre Funktionen mit genau den Berechtigungen bereit, die sie benötigen. So minimieren Sie die Angriffsfläche und sorgen für eine sichere Konfiguration.

Wenn versehentlich mehr Berechtigungen als nötig erteilt werden

Betrachten Sie die folgende Konfiguration in serverless.yml, die eine einzelne Berechtigungsrolle für alle Funktionen definiert, die mit diesem Projekt bereitgestellt werden:


service: hello-world
provider:
  name: aws
  runtime: nodejs6.10
  stage: ‘prod’
  region: us-east-1
  environment:
  profile: aws
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
      Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}*"

Ein auffälliger Fehler in der obigen Konfiguration: Die IAM-Rolle, die mit der Funktion bereitgestellt wird, gewährt Zugriff auf alle Lese- und Schreibaktionen in DynamoDB, die mit diesen Funktionen verknüpft sind. Tatsächlich müssen manche Funktionen aber nur lesen, während andere Daten löschen müssen. Diese naive Standardeinstellung für Serverless-Projekte vergrößert die Angriffsfläche. Besser wäre es, Funktionen einzeln bereitzustellen und ihre Berechtigungen bedarfsgerecht festzulegen.

Rollen und Zugriffsberechtigungen korrekt für jede Funktion festlegen

Das Serverless Framework unterstützt die Konfiguration von Rollen pro Funktion, wie das folgende Beispiel aus einer serverless.yml-Datei zeigt:


1 service: new-service
2
3 provider:
4   name: aws
5 
7 functions:
8   func0:
9     role: myCustRole0
11  func1:
12   role: myCustRole1

Ab Zeile 7 werden zwei Funktionen definiert: func0 und func1. Jede Funktion erhält eine eigene Rolle, die durch die role-Direktive in den Zeilen 9 und 12 festgelegt wird.

Mit unterschiedlichen Rollendefinitionen lässt sich der Zugriff deutlich feiner abstimmen, sodass jede Funktion nur die benötigten Berechtigungen erhält. Eine Funktion kann beispielsweise AWS-bezogene Protokollierungsfunktionen nutzen, während eine andere Zugriff auf einen Amazon-S3-Bucket erhält.

3. Funktionsgrenzen voneinander isolieren

Auch wenn mehrere Funktionen zusammen einen vollständigen Workflow bilden, sollte jede Funktion als eigene Sicherheitsgrenze behandelt werden. So wird verhindert, dass eine Schwachstelle in einer Funktion auf andere übergreift und auch diese gefährdet.

Sehen wir uns dazu folgendes Szenario an:

Die Funktion subscribeToEmailNotification bereinigt die Eingabe. Anschließend wird die Funktion sendNotification ausgelöst, um diese Eingabe zu verarbeiten und zu übermitteln. Vielleicht halten Sie es für unnötig, die Eingabe der zweiten Funktion zu bereinigen, nachdem dies bereits in der „subscribe“-Funktion geschehen ist. Wird später eine neue Funktion subscribeToSMSNotification erstellt, die die Eingabe nicht bereinigt, kann die Funktion sendNotification Ereignisdaten erneut verarbeiten, ohne sie zu bereinigen.

Beachten Sie diese Richtlinien, um Funktionen innerhalb ihrer jeweiligen Sicherheitsgrenzen zu isolieren:

  • Verlassen Sie sich nicht auf die Reihenfolge von Funktionsaufrufen und Zugriffen: Gehen Sie nicht davon aus, dass eine Funktion nur über eine andere Funktion aufgerufen wird oder nicht über ein API-Gateway erreichbar ist. Reihenfolge und Zugriff auf Funktionen können sich im Laufe der Zeit ändern.

  • Jede Funktion bildet ihre eigene Sicherheitsgrenze: Jede Funktion sollte Eingaben aus Ereignissen als nicht vertrauenswürdige Datenquelle behandeln und ihre Eingaben immer bereinigen.

  • Verwenden Sie Sicherheitsbibliotheken: Investieren Sie Zeit in die Entwicklung oder Übernahme standardisierter Sicherheitsbibliotheken und schreiben Sie deren Nutzung für alle Funktionen vor.

4. Ereigniseingaben bereinigen, um Injection-Angriffe zu verhindern

Serverless-Architekturen erfordern oft unterschiedliche Arten der Datenaufnahme in Cloud-Funktionen: synchron, asynchron oder als Stream. Dabei können Nutzerdaten durch verschiedene Datenspeicher und Funktionen fließen.

Auch wenn sie durch API-Gateways, Firewalls und andere Proxys geschützt sind, verarbeiten Funktionen im Kontext von API-Services Nutzereingaben genauso wie herkömmliche API-Server. Funktionen, die Ereignisdaten aus Message Queues und anderen nicht öffentlichen Kommunikationskanälen verarbeiten, können ebenfalls indirekt Nutzereingaben verarbeiten. In diesem Fall sind Kontext und Herkunft der Daten jedoch weniger eindeutig und schwerer vorherzusagen.

Serverless-Architekturen sind meist ereignisgesteuert. Dadurch wird die Injection von Ereignissen zu einem wichtigen Angriffsvektor: Funktionen werden gezielt für kleine Aufgaben wie die Verarbeitung von Daten aus einer Event Queue erstellt. Gelingt es jedoch schädlichen Daten, eine Funktion zur Datenbereinigung zu umgehen und die Event-Payload zu erreichen, kann die verarbeitende Funktion für Injection-Angriffe anfällig sein, wenn sie die Daten nicht korrekt validiert.

Die folgenden Beispiele zeigen weniger traditionelle Datenquellen, die häufig Funktionen auslösen und denen Funktionen daher nicht vertrauen sollten:

  • Speicher: Dateinamen oder Verzeichnisse in Cloud-Speichern wie S3-Buckets können von Nutzern kontrolliert werden und Interpreter mit schädlichen Eingaben versorgen.

  • Messaging: Ereignis-Payloads asynchroner Nachrichten über Services wie SNS und SQS sollten bereinigt und als nicht vertrauenswürdig behandelt werden.

  • Datenbank-Streams: Datenbankänderungen, etwa das Hinzufügen oder Löschen eines Datensatzes, können Funktionen auslösen. Da solche Ereignisse potenziell von Nutzereingaben stammen, sollten sie bereinigt werden.

Wenden Sie die folgenden Best Practices auf alle Nutzereingaben an, die von einer Funktion verarbeitet werden, um Event-Injection-Angriffe einzudämmen:

  • Validieren Sie Daten anhand von Schemas und Data Transfer Objects. Prüfen Sie erwarteten Typ, Länge und Wertebereich, statt Datenobjekte ungeprüft zu serialisieren und deserialisieren und unverändert weiterzugeben.

  • Verwenden Sie immer ein ORM und korrektes Escaping, wenn Sie SQL- und NoSQL-Datenbanken nutzen, um diese Arten von Injection-Angriffen zu verhindern.

  • Vermeiden Sie es, Systemprozesse zu starten oder zur Laufzeit dynamischen Code auszuwerten, wenn die dafür verwendeten Daten aus Ereignissen stammen und potenziell von Nutzern eingegeben wurden. Achten Sie außerdem auf die Drittanbieter-Services, die Sie in Ihre Funktionen integrieren, denn Sie haben nur begrenzte Kontrolle und Einblicke in deren Datenquellen und den Umfang nutzergesteuerter Eingaben. Verwenden Sie beim Starten von Prozessen und bei dynamischem Code geeignete Gegenmaßnahmen wie Encoding beziehungsweise Sandboxing.

5. API-Gateways als Sicherheitspuffer einsetzen

Bereitgestellte Cloud-Funktionen sind häufig öffentlich zugänglich und über einen zufällig generierten HTTP-Endpunkt erreichbar, der Ereignis, Daten und den passenden Kontext zur Verarbeitung der Payload übermittelt. Eine bewährte Methode, Funktionen bereitzustellen, ist der Zugriff über API-Gateways. Sie fungieren als Reverse Proxys und schaffen eine Trennung zwischen Nutzern und Funktionen.

Als nach außen gerichtete API-Schnittstelle für Verbraucher lassen sich API-Gateways mit wenigen Konfigurationsschritten für verschiedene Sicherheitsmechanismen nutzen, die die Angriffsfläche von Funktionen verkleinern.

API-Gateway als Filter

Schalten Sie ein API-Gateway als Filter vor Ihre Funktionen, um Eingaben anhand einer Gateway-Richtlinie zu begrenzen. Je strenger die Richtlinie, desto geringer ist das Risiko, das über Ihre Funktionen eindringen kann. AWS API Gateway unterstützt die Definition von Request- und Response-Mappings, die Schemas entsprechen. Das ähnelt dem Muster der Data Transfer Objects. Bei Funktionen und Gateways können Mappings als strenge Regeln für eingehende Requests dienen.

Das folgende Beispiel zeigt ein Schema, das auf Gateway-Ebene für einen eingehenden JSON-Request definiert ist:


{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "GroceryStoreInputModel",
  "type": "object",
  "properties": {
      "Bin" : {
        "type": "object",
        "properties": {
            "category": { "type": "string" },
            "type": { "type": "string" },
            "price": { "type": "number" },
            "unit": { "type": "string" },
            "quantity": { "type": "integer" }
        }
      }
   }  
}

API-Gateway als Authentifizierungsschicht

HTTP-Requests abzufangen, bevor sie Ihre Cloud-Funktionen erreichen, ist entscheidend für die Zugriffskontrolle auf Anwendungen, etwa für Authentifizierung und Autorisierung. Konfigurieren Sie ein API-Gateway und überlassen Sie die von Funktionen verursachten Aufgaben dem Cloud-Anbieter und seiner Infrastruktur.

Sobald Nutzer am API-Gateway authentifiziert sind, können Gegenmaßnahmen wie Drosselung und Kontingente am Gateway greifen – und das alles, ohne Funktionsaufrufe auszulösen.

API-Gateway zur DDoS-Abwehr

Ein API-Gateway bietet auf Ebene des Cloud-Anbieters Schutz vor Denial-of-Service-Angriffen (DoS) und ermöglicht es Ihnen, alle an Ihre Funktionen gerichteten Requests zu drosseln. Die Ratenbegrenzung wird so aus Ihren Funktionen und der Geschäftslogik ausgelagert – wo sie ohnehin nicht hingehört – und vollständig von der Cloud-Infrastruktur übernommen. Mit einem API-Gateway beugen Sie einer Erschöpfung finanzieller Ressourcen vor.

6. Funktionen überwachen und protokollieren

Funktionen laufen nur sehr kurz. Wenn Sie viele Funktionen bereitstellen und deren Aufrufe mit zunehmender Skalierung immer weiter zunehmen, verlieren Sie leicht den Überblick über den Ereignisfluss und damit über die Ursache von Fehlern. Mit zunehmender Verbreitung von Serverless in einem Unternehmen wird es schwieriger, unsichere Abläufe und böswillige Versuche zu erkennen, mit denen Angreifer Funktionen auf unsichere Codepfade zwingen wollen.

AWS hat vor Kurzem die Möglichkeit eingeführt, Lambda-Funktionen mit Tags zu versehen, damit sie sich einfach nachverfolgen und gruppieren lassen. Mit dem Serverless Framework können wir Funktionen in ihren YAML-Dateien entweder global (für alle Funktionen in der Datei serverless.yml) oder einzeln taggen.

Funktionen auf Sicherheitslücken überwachen

Snyk lässt sich in Ihren FaaS-Anbieter integrieren, um bereitgestellte Funktionen zu überwachen und sicherzustellen, dass sie geschützt sind. So können Sie bekannte Sicherheitslücken im gesamten Softwareentwicklungslebenszyklus beheben, die Funktionen und deren Nutzung von Open-Source-Abhängigkeiten betreffen.

Im folgenden Bild sehen Sie das GitHub-Projekt lirantal/bazz-serverless nach einem Scan mit mehreren Sicherheitslücken mit hohem, mittlerem und niedrigem Schweregrad. Dies ist der Quellcode meines Serverless-Projekts, das mehrere Funktionen bereitstellt. Unter dem GitHub-Projekt-Repository sehen Sie alle sechs AWS-Lambda-Funktionen, die ich bereitgestellt habe. Dabei handelt es sich um die tatsächlichen Funktionen, wie sie von AWS bereitgestellt und ausgeführt werden.

Snyk Projects-Dashboard mit AWS-Lambda- und GitHub-Repositories sowie der Anzahl von Problemen mit hoher, mittlerer und niedriger Schwere

Snyk hat alle diese einzelnen Funktionen auf bekannte Sicherheitslücken gescannt. Da sie alle denselben Abhängigkeitsbaum verwenden, sehen wir, dass sie jeweils mit Versionen anfälliger Bibliotheken bereitgestellt werden.

Cloud-Anbieter verfügen häufig über integrierte Überwachungsfunktionen für Anwendungen und Funktionsressourcen, die entsprechende Einblicke ermöglichen. Microsoft bietet Azure Monitoring und Amazon AWS X-Ray. Die X-Ray-Konsole von AWS zeigt beispielsweise den Datenfluss durch Funktionen und andere Cloud-Ressourcen sowie Messwerte wie die Ausführungszeit an.

7. Befolgen Sie sichere Programmierkonventionen für Anwendungscode

Ein großer Vorteil einer Serverless-Infrastruktur besteht darin, dass die Verantwortung für das zugrunde liegende Betriebssystem vom Anwendungsverantwortlichen auf den Cloud-Anbieter übergeht. Dieser ist dafür zuständig, das Betriebssystem zu warten und mit Sicherheitspatches auf dem neuesten Stand zu halten. Das bedeutet jedoch, dass Angreifer ihre Aufmerksamkeit auf die weiterhin exponierten Bereiche richten – allen voran den Anwendungscode selbst.

Anwendungscode ist nach wie vor anfällig. Entwickler sollten daher sichere Programmierkonventionen befolgen und sicherstellen, dass diese Richtlinien bei Tätigkeiten wie Code-Reviews eingehalten werden, damit Sicherheitsprobleme im Anwendungscode frühzeitig im Softwareentwicklungsprozess erkannt werden. Die verbindliche Nutzung gemeinsamer Sicherheitsbibliotheken in Entwicklerteams trägt zusätzlich dazu bei, dass sichere Programmierkonventionen eingehalten werden. Außerdem müssen Entwickler so das Rad nicht neu erfinden und riskieren keine Fehler bei Sicherheitsproblemen, für die es bereits standardisierte Lösungen gibt.

Die OWASP Top 10 bieten einen guten Überblick über Bereiche des Anwendungscodes, die besondere Aufmerksamkeit in puncto Sicherheit erfordern. Dazu gehören:

  • Injection-Angriffe, bei denen Daten nicht korrekt gefiltert oder kontextgerecht kodiert werden und dadurch als Teil einer vertrauenswürdigen Ausführung interpretiert werden. Das betrifft beispielsweise SQL-Injections, die Ausführung von Systembefehlen sowie die Ausführung von CSS- und JavaScript-Code. Um böswillige Injection in jedem Kontext zu verhindern, sollten Sie Benutzereingaben nach Möglichkeit vollständig unterbinden, andernfalls eine sichere Whitelist verwenden und alle von Benutzern bereitgestellten Daten kontextgerecht kodieren.

  • Die Offenlegung sensibler Daten, bei der Angreifer unsichere Kommunikationswege ausnutzen können, um sensible Informationen abzugreifen, oder unsichere kryptografische Algorithmen in Sicherheitskontexten verwenden. Zu den Gegenmaßnahmen gehören TLS als sichere Kommunikationsmethode sowie Passwörter und andere Zugangsdaten, die stets mit geeigneten kryptografisch sicheren Algorithmen verschlüsselt oder gehasht werden.

  • Fehlerhafte Zugriffskontrollen ermöglichen Angreifern den Zugriff auf Ressourcen, für die sie keine Berechtigung haben. Um dieses Problem einzudämmen, sollten Sie geeignete Zugriffskontrollmechanismen implementieren, etwa den Zugriff standardmäßig verweigern und ein restriktives Autorisierungsmodell verwenden. Setzen Sie bei Bedarf außerdem Ratenbegrenzungen ein, um Brute-Force-Versuche und den Missbrauch des Dienstes zu minimieren.

Hinweis: Eine vollständige Liste finden Sie im Leitfaden OWASP Top 10 2017.

8. Daten während der Übertragung schützen und verifizieren

Wie sich dem httparchive zum Stand der HTTPS-Nutzung entnehmen lässt, setzt sich die sichere Webkommunikation zunehmend als Best Practice durch. Laut Bericht entfallen 77 % des vom Dienst überwachten Traffics darauf. Funktionen und die damit integrierten Dienste – unabhängig davon, ob sie von Drittanbietern stammen oder sich innerhalb der Cloud-Umgebung befinden – sollten ebenfalls ausnahmslos sichere Kommunikationswege verwenden.

Befolgen Sie diese Richtlinien, um eine sichere Datenübertragung zu gewährleisten:

  • Verwenden Sie HTTPS als sicheren Kommunikationsweg – sowohl innerhalb Ihrer internen Umgebung für aufgerufene Funktionen oder Dienste als auch für Cloud-Dienste und Drittanbieterdienste außerhalb der Cloud des Anbieters.

  • Überprüfen Sie SSL-Zertifikate, um die Identität Ihres Kommunikationspartners zu bestätigen. Unterbrechen Sie die gesamte Kommunikation, wenn Identität und Authentizität des Servers nicht mit dem Zertifikat übereinstimmen.

  • Aktivieren Sie signierte Anfragen bei Cloud-Anbietern, die diese Funktion unterstützen.

  • Behandeln Sie Antworten von Drittanbieterdiensten wie nicht vertrauenswürdige Benutzereingaben und bereinigen Sie sie.

Sichere Kommunikation mit Cloud-internen Diensten

Dienste und Ressourcen, auf die lokal innerhalb der Infrastruktur des Cloud-Anbieters zugegriffen wird, sollten nach Möglichkeit über einen sicheren Kommunikationsweg kommunizieren. Wenn beispielsweise eine AWS-Lambda-Funktion SNS integriert, sollte sie die Kommunikation über SSL aktivieren:

var sns = new AWS.SNS({apiVersion: '2010-03-31', sslEnabled: true});

Signierte Anfragen

Wenn Sie Tools von Cloud-Anbietern wie das AWS SDK und die AWS CLI zum Erstellen von HTTP-Anfragen verwenden, fügen diese automatisch eine Signatur im HTTP-Header oder in den Abfrageparametern ein. Sie übermittelt die Identität der aufrufenden HTTP-Anfrage und schützt so zusätzlich die Daten während der Übertragung. Außerdem werden HTTP-Replay-Angriffe abgewehrt.

Ein Beispiel für eine signierte AWS-Anfrage, bei der die Signatur als Authorization-Header in die HTTP-Nachricht eingefügt wird:


GET https://iam.amazonaws.com/?Action=ListUsers&Version=2010-05-08 HTTP/1.1
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/iam/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=5d672d79c15b13162d9279b0855cfba6789a8edb4c82c400e06b5924a6f2b5d7
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: iam.amazonaws.com
X-AMZ-Date: 20150830T123600Z

9. Geheimnisse sicher speichern

Verwenden Sie einen sicheren Speicher für Ihre Geheimnisse und vertraulichen Zugangsdaten, der von den großen Cloud- und FaaS-Anbietern unterstützt wird. Alternativ können Sie eigene Lösungen wie Hashicorps Vault bereitstellen. Die Speicherung von Schlüsseln in einem Secret-Storage verringert das Risiko, dass vertrauliche Informationen in statischen Dateien eines Quellcode-Repositorys oder in Umgebungsvariablen gespeichert werden, und senkt die Wahrscheinlichkeit einer Offenlegung erheblich.

Das folgende Beispiel verwendet den AWS Simple Systems Manager, um Geheimnisse abzurufen, die mit dem AWS Parameter Store sicher verschlüsselt wurden. In unserem Beispiel greift die SSM-Variable auf einen zuvor erstellten Wert zu und stellt ihn einer Funktion über eine Umgebungsvariable zur Verfügung:


service:
 name: hello-world

provider:
  name: aws

functions:
  helloWorld:
    handler: helloworld.get
    environment:
      GITHUB_API_KEY: ${ssm:/github/api-key}

Beachten Sie, dass ${ssm:/github/api-key} den verschlüsselten Wert dieses Schlüssels zurückgibt. Wenn Sie stattdessen den tatsächlichen Wert entschlüsseln und zurückgeben möchten, müssen Sie ${ssm:/github/api-key~true} angeben.

Weitere Informationen zu Parameter Store und KMS finden Sie in der Dokumentation von Amazon: https://docs.aws.amazon.com/kms/latest/developerguide/services-parameter-store.html

Für noch mehr Sicherheit und Flexibilität beim Verwalten von Geheimnissen in Anwendungen sollten Sie Geheimnisse und andere Konfigurationsinformationen zur Laufzeit abrufen, anstatt Umgebungsvariablen zu verwenden, für deren Übernahme neuer Konfigurationen ein Prozessneustart erforderlich ist.

Die Verwendung eines Secret-Storage verringert zwar das Risiko, dass ein Schlüssel offengelegt wird, beseitigt es aber nicht vollständig. Wenn Sie in Ihrer Funktion Geheimnisse aus einem Secret-Storage verwenden, ist der Schlüssel selbst zum Glück nicht wichtig – Sie können ihn also regelmäßig rotieren! Sollte er offengelegt oder gestohlen werden, ist er dadurch nur für kurze Zeit nutzbar.

10. Funktionen möglichst granular bereitstellen

Funktionen sollten grundsätzlich klein sein, und entsprechend klein ist auch der mit ihnen bereitgestellte Code. Das verringert die Angriffsfläche und die Menge an Informationen, die bei einer Kompromittierung der Funktion offengelegt werden könnten. Funktionen gebündelt bereitzustellen und dabei mehr Code und Funktionen als nötig bereitzustellen, ist nicht empfehlenswert.

Funktionen desselben Serverless-Projekts verwenden standardmäßig dieselben Abhängigkeiten. So nutzen Node.js-Serverless-Projekte beispielsweise eine gemeinsame Datei package.json, deren Abhängigkeiten mit jeder einzelnen Funktion bereitgestellt werden, obwohl möglicherweise nicht alle Funktionen sie ausdrücklich benötigen.

Da Sie wahrscheinlich viel Boilerplate-Code wiederverwenden, kann es hilfreich sein, Vorlagen zum Gerüstaufbau von Projekten zu verwenden, zum Beispiel:


$ serverless create —-template-path my-repository/project-template —-path new-service-directory —-name my-new-service-name

Laden Sie den Spickzettel zu Best Practices für Serverless-Sicherheit als praktische Referenz herunter. Melden Sie sich bei Snyk für ein kostenloses Konto an und schützen Sie noch heute Ihren Code!

Starten Sie mit Capture the Flag

Erfahren Sie in unserem virtuellen On-Demand-Workshop für Einsteiger, wie Sie Capture-the-Flag-Herausforderungen lösen.