Dieses Projekt wurde im Rahmen der Vorlesung „Software Development for Cloud Computing“ umgesetzt.
Ausgangslage und Projektidee
Unser bisheriger Fokus im Studium lag hauptsächlich auf Themen der IT-Security und Machine Learning, weshalb wir beide bis auf die grundlegenden Vorlesungen zum Thema Software Entwicklung kaum Erfahrungen in diesem Bereich gesammelt haben. Aus diesem Grund haben wir uns das Ziel gesetzt, eine einfache Webanwendung zu implementieren und diese in einer geeigneten Cloud-Umgebung bereitzustellen. Dabei war es uns wichtig einen Bezug zur IT-Security zu behalten, weshalb schnell klar war, dass wir ein Tool zur Unterstützung bei der Analyse der Sicherheit von Software umsetzen möchten. Da wir beide bereits einige Erfahrungen im Bereich Penetrationtesting von Webanwendungen gesammelt haben, war unsere erste Idee ein Security-Scanner für Webanwendungen, mit dem man unter Eingabe einer URL eine Webseite auf potenzielle Sicherheitslücken oder Miskonfigurationen überprüfen lassen kann. Nach einigen Zeilen Code und weiteren Überlegungen haben wir uns allerdings gegen diese Art von Security Scanner entschieden, da wir Bedenken in Bezug auf das automatisierte Scannen fremder Webseiten hatten und im Allgemeinen die automatisierte Analyse von HTTP-Anfragen und Antworten sehr kontextabhängig sein kann und dementsprechend zu komplex für eine einfache Webanwendung.
Deshalb haben wir uns dazu entschieden die Idee des Security-Scanners leicht abzuwandeln und daraus ein Tool zur Analyse von sbom-Dateien zu machen. Das Ziel war es eine Webanwendung zu implementieren in der man eine sbom-Datei im JSON-Format hochladen kann, um anschließend eine Auswertung in Form einer Tabelle zu den enthaltenen Schwachstellen zu erhalten und so einen schnellen und einfach zu verstehenden Überblick über die Sicherheit der eigenen Anwendung zu erhalten.
Architekturentscheidungen und Technologie-Auswahl
Zu Beginn haben wir die folgenden Anforderungen an die Webanwendung definiert:
- Frontend:
- Simples Frontend mit der Funktion eine sbom-Datei im JSON-Format hochzuladen und direkt eine übersichtliche Auswertung über die enthaltenen Schwachstellen zu erhalten
- Das Ziel war es eine einfache Möglichkeit zu bieten, seine eigene Anwendung auf Schwachstellen zu überprüfenDas Frontend erhält die ausgewerteten Daten vom Backend als JSON und stellt diese in einer übersichtlichen Tabelle dar
- Klare Trennung vom Backend
- Backend:
- Das Backend sollte die über das Frontend hochgeladene sbom-Datei verarbeiten und dem Frontend das Ergebnis der Verarbeitung liefern
- Kurzer zustandloser Job, ideal für AWS Lambda
- Für die Analyse der sbom-Datei haben wir uns dafür entschieden eine API zu verwenden, die die enthaltenen Abhängigkeiten auf bekannte Schwachstellen überprüft
Technologien:
- Frontend
- React
- Node.js und npm für den Build
- JavaScript / JSX
- Fetch API für HTTP-Requests ans Backend
- AWS Amplify fürs Hosting
- Backend
- Python 3.11 (AWS Lambda Runtime)
- Python‑Bibliotheken: requests
- AWS Serverless Application Model (SAM) für das Deployment des Backends
- AWS Lambda Function für die Verarbeitung der sbom-Datei
- API-Gateway als Schnittstelle zwischen AWS Amplify und der Lambda Funktion
- Snyk SBOM API (REST‑Endpoint) für die Analyse der sbom-Datei
- AWS Secrets Manager für die Speicherung der API-Keys
Als Cloud-Architektur haben wir uns für eine Serverless Web Application Architektur in AWS entschieden. In der folgenden Abbildung 1 ist die grobe Struktur der Architektur dargestellt.

Aus den folgenden Gründen haben wir uns für diese Architektur entschieden:
- Unregelmäßigen und kurzen Workloads der Webanwendung:
- Es gibt Phasen ohne Anfrage und es entsteht nur Anfragen, wenn ein Scan gestartet wird. Mit Lambda/API Gateway fallen nur Kosten pro Aufruf und Ausführungszeit an (Pay-per-use), in Leerlaufphasen entstehen keine Kosten
- Automatische Skalierung:
- Lastspitzen, wie beispielsweise mehrere Scans gleichzeitig, skaliert AWS automatisch horizontal
- Kurze, zustandslose Jobs (sbom verarbeiten à Ergebnisse zurückliefern):
- AWS Lambda ist, aufgrund der maximalen Laufzeit von 15 Minuten und der Zustandslosigkeit, genau darauf ausgelegt kurze, zustandslose und in sich geschlossene Aufgaben zu übernehmen
Eine alternative Überlegung war es das Backend als Container-Service mit ECS/Fargate bereitzustellen, allerdings haben wir uns aufgrund der genannten Vorteile der Serverless-Architektur und der folgenden Nachteile der Container-Services dagegen entschieden:
- Kosten bei Leerlauf
- Höherer Ops-Aufwand durch Container Build und Patch, Load Balancer und Skalierung
- Höhere Komplexität für diesen einfachen Use-Case
Herausforderungen:
Zeitmanagement:
Eine Herausforderung bei diesem Projekt war das Zeitmanagement, insbesondere aufgrund der Entscheidung für eine andere Projektidee im Laufe der Vorlesung. Wir haben uns zu Beginn der Vorlesung schnell für die Idee des Security Scanners entschieden, ohne uns weitere Gedanken über die möglichen Probleme wie das Scannen fremder Webseiten zu machen. Im Nachhinein war es die richtige Entscheidung sich für die andere Idee zu entscheiden, allerdings hätten wir mit einer besseren Planung der Anforderungen und des Umfangs der Idee schon im Vorhinein die Probleme erkennen können und so mehr Zeit für die wirkliche Umsetzung des Projekts haben können.
Deployment mit AWS SAM:
AWS SAM (Serverless Application Model) ist ein Open-Source-Framework von AWS zum Definieren, Entwickeln, Testen und Deployen von Serverless-Anwendungen. Es erweitert AWS CloudFormation um eine vereinfachte Syntax in Form eines Templates für Ressourcen wie beispielsweise AWS Lambda oder API Gateway. Mit der SAM CLI lassen sich Funktionen lokal (Docker-basiert) ausführen und debuggen, Builds erstellen, sowie das Deployment in die Cloud einfach und wiederholbar ausführen. Zu Beginn fiel es uns etwas schwierig die Dokumentation zu diesem Tool nachzuvollziehen, insbesondere in welchem Umfang man die für unser Projekt nötigen Cloud-Ressourcen mithilfe des AWS SAM Templates definieren kann. Die Definition der Backend-Ressourcen wie AWS Lambda und das API-Gateway konnte sehr schnell umgesetzt werden. Im folgenden Codeausschnitt sieht man die Definition der Lambda Funktion in der template.yaml Datei.
Resources:<br> SbomFunction:<br> Type: AWS::Serverless::Function<br> Properties:<br> Environment:<br> Variables:<br> SNYK_API_TOKEN: "Pfad zu AWS Secrets Manager"<br> SNYK_ORG_ID: " Pfad zu AWS Secrets Manager "<br> CodeUri: sbom_lambda/<br> Handler: app.lambda_handler<br> Runtime: python3.11<br> Architectures:<br> - x86_64<br> Events:<br> Analyze:<br> Type: Api<br> Properties:<br> Path: /analyze<br> Method: POST<br> RestApiId: !Ref SbomApi
Erläuterung zu den einzelnen Attributen:
Type: Über diese Attribute kann man die Cloud-Ressource, in diesem Fall eine Lambda
Funktion, definieren
Variables: Hier kann man Umgebungsvariablen angeben, welche dann beim Deployment verschlüsselt in die Lambda Konfiguration geschrieben werden. Zur Laufzeit stehen diese Variablen als String im Prozess zur Verfügung, wodurch wir in der Lambda Funktion darauf zu greifen können. Wir haben diese Variablen genutzt, um die API-Keys der SNYK-API zur Laufzeit zu setzen.
Handler: Einstiegspunkt der Lambda-Funktion im Code
Runtime: Die Ausführungsumgebung für die Lambda-Funktion
Events: Definiert Trigger, der die Funktion auslöst
Analyze: Logischer Name des Events.
Type: Anbindung an API Gateway
Path: API-Ressourcenpfad.
Method: HTTP-Methode.
RestApiId: Verknüpft die Methode/Route mit einer bestehenden/anderen API-Gateway
Ressource im Template (hier: SbomApi). Ohne dieses Feld würde SAM automatisch eine implizite API anlegen.
Mit dem Befehl sam local konnten wir die Anwendung lokal testen und debuggen. Das Deployment in die Cloud konnte mit dem Befehl sam deploy wiederholbar durchgeführt werden. Allerdings haben wir keine Möglichkeit gefunden, mithilfe des AWS SAM Templates die Ressourcen für das Frontend zu definieren, weshalb wir uns dafür entschieden haben für das Frontend AWS Amplify zu verwenden. Diese Lösung ist nicht optimal, da wir so nicht die gesamten Cloud-Ressourcen in einem Template verwalten können, aber für den Umfang des Projekts ist die Lösung ein geeigneter Kompromiss. AWS Amplify erlaubt es den Build des Frontends als ZIP-Datei hochzuladen und unter einer URL bereitzustellen, sodass wir mit dem Befehl npm run build einen Build des Frontends erzeugen und anschließend manuell in AWS Amplify hochladen konnten. Um API-Keys nicht im Repository oder in der template.yaml abzulegen, haben wir die sensiblen Werte im AWS Secrets Manager gespeichert und im SAM-Template per dynamischer Referenz eingebunden. Dadurch werden die API-Keys erst zur Deploy-Zeit von CloudFormation aufgelöst und als verschlüsselte Umgebungsvariablen in die Lambda-Konfiguration geschrieben.
Einbindung der SNYK-API:
Eine weitere Herausforderung war die Einbindung der SNYK-API zur Analyse der sbom-Datei. Zu Beginn des Projekts haben wir nach geeigneten APIs von Dritten zur Analyse von sbom-Dateien recherchiert, wodurch wir auf den Anbieter SNYK gestoßen sind. SNYK bietet eine REST-API zur Analyse von sbom-Dateien an, welche exakt zum Anwendungsfall unserer Anwendung passt, weshalb wir uns dafür entschieden haben diese in unser Projekt einzubinden. Die API von SNYK ist so aufgebaut, dass man eine sbom-Datei sendet und eine Job-ID als Antwort erhält, da SNYK die Anfrage asynchron verarbeitet und das Ergebnis anschließend mit der Job-ID abgerufen werden kann. Dies führte dazu das wir im Backend genau diesen Ablauf abbilden mussten, sprich erst die sbom-Datei senden und anschließend das Ergebnis über die Job-ID abrufen. Um die Interaktion mit der API nachzuvollziehen haben wir die Debug-Funktion von AWS SAM verwendet, mit der wir die Lambda Funktion lokal testen konnten und so den Ablauf genau nachvollziehen und abbilden konnten. Zu Beginn gab es Probleme mit der Authentisierung von SNYK, da wir bei jeder Anfrage ein 401 Unauthorized Fehler zurückerhalten haben, obwohl wir die API-Keys der Dokumentation entsprechend angeben haben. Nach vielen fehlgeschlagenen Versuchen haben wir uns dazu entschieden einen weiteren Account bei SNYK anzulegen und die API-Keys neu zu generieren. Mit den neuen API-Keys haben die Anfragen dann direkt funktioniert, wodurch wir den Ablauf vollständig abbilden konnten. Die Gründe für das vorherige Fehlschlagen können wir bis heute immer noch nicht nachvollziehen. Ein weiteres Problem war, dass die SNYK API für POST-Anfragen zwingend den Content-Type application/vnd.api+json verlangt, bei GET-Anfragen darf kein Content-Type gesendet werden. Weil wir anfangs überall den gleichen Header mitschickten, bekamen wir einen 400-Fehler, was wir durch getrennte Header für die POST- und GET-Anfragen gelöst haben. Im Nachhinein betrachtet war die Einbindung einer externen API zur Analyse der sbom-Datei trotzdem die richtige Entscheidung, da die API von SNYK schnell gute Ergebnisse liefert, die wir direkt weiterverarbeiten konnten.
Fazit und Learnings:
Insgesamt sind wir zufrieden mit dem Ergebnis des Projekts. Wir haben es geschafft eine Webanwendung zu implementieren die den zu Beginn definierten Anforderungen von uns entspricht. Die Anwendung bietet eine einfache Analyse von sbom-Dateien und eine übersichtliche Darstellung der Ergebnisse, was genau dem entspricht, was wir uns vorgenommen haben. Selbstkritisch betrachtet, gibt es jedoch einige Punkte, die wir im Nachhinein besser hätten machen können. Insbesondere das Zeitmanagement war ein großes Problem. Am Ende haben wir uns auf die nötigsten Funktionen beschränkt und beispielsweise auf weitere Optimierungen der Codequalität oder Automatisierung des Deployments verzichtet, was wir durch ein besseres Zeitmanagement deutlich besser hätten umsetzen können. Trotz des überschaubaren Umfangs des Projekts haben wir sehr viele neue Erkenntnisse und Erfahrungen gesammelt, wodurch wir insgesamt zufrieden mit dem Ergebnis des Projekts sein können.
Learnings:
- Cloud- und AWS-Grundlagen:
- Serverless-Grundidee: Code als kurze, zustandslose Lambda Funktionen ausführen, Skalierung & Betriebsaufwand übernimmt AWS.
- API-Bereitstellung: API Gateway als Schnittstelle zwischen Frontend und Backend, Lambda Funktion für die Datenverarbeitung, AWS Amplify fürs Frontend-Hosting
- Lokal entwickeln: Mit AWS SAM Local Lambdas und API Gateway lokal starten, Requests testen, Logs sehen
- Architektur-Entscheidungen:
- Warum Serverless: Pay-per-use, automatische Skalierung, kein Leerlauf, weniger Entwicklungsaufwand
- Alternativen verstanden: ECS/EC2 wären dauerhafte Infrastruktur (Grundkosten, mehr Betriebsaufwand) was für unseren Use-Case nicht sinnvoll gewesen wäre
- Trennung von Frontend und Backend: Frontend (Amplify) per fetch an Backend (API Gateway)
- Entwicklungsprozess:
- Externe API´s in die eigene Anwendung einbinden
- Umgang mit Secrets im Code
Authors
- Tim Ruff
- Magnus Arnold

Leave a Reply
You must be logged in to post a comment.