Umgang mit Sicherheitslücken in Spring Boot
29. November 2023
0 Min. LesezeitIn der Softwareentwicklung gehört die Verwaltung von Abhängigkeiten zu den zentralen Aufgaben, wenn Sie robuste und sichere Anwendungen erstellen möchten. Spring Boot ist bei Java-Entwicklerinnen und -Entwicklern beliebt und erleichtert die Entwicklung von Anwendungen. Doch es gibt mehr zu beachten, als es zunächst scheint. Wenn Sie Ihre Abhängigkeiten im Blick behalten, laufen Ihre Spring-Boot-Projekte reibungslos und sind gegen sich ständig weiterentwickelnde Bedrohungen gewappnet.
Ein wichtiger Aspekt beim Verwalten von Spring-Boot-Abhängigkeiten ist die Sicherheit. Software-Schwachstellen werden häufig entdeckt. Wenn Sie die Abhängigkeiten Ihres Projekts aktuell halten, stärken Sie damit Ihren digitalen Schutz. Veraltete Abhängigkeiten sind wie unverschlossene Türen, die potenzielle Bedrohungen einladen – und genau das möchten wir vermeiden.
Sicherheitslücken in Spring Boot finden
Tools zur Software Composition Analysis (SCA) sind für Entwicklerinnen und Entwickler äußerst hilfreich. Sie erleichtern die Verwaltung von Abhängigkeiten, den Umgang mit Sicherheitslücken, die Klärung von Lizenzfragen und die Einhaltung von Compliance-Vorgaben in Ihren Softwareprojekten. Mit Snyk Open Source als SCA-Lösung finden Sie ganz einfach heraus, ob Ihre Spring-Boot-Pakete Sicherheitslücken enthalten.
In meinem Beispielprojekt habe ich mehrere Sicherheitslücken gefunden. Die erste ist eine schwerwiegende Sicherheitslücke in `netty-codec-http2`. Dabei handelt es sich um eine transitive Abhängigkeit, die von meinem `spring-boot-start-webflux` eingebunden wird, wie Sie unten sehen.

Die zweite Sicherheitslücke, auf die ich eingehen möchte, ist eine mittelschwere Schwachstelle, die eine beliebige Codeausführung ermöglicht und über das Paket `snakeyaml` eingebunden wird. Auch dies ist eine transitive Abhängigkeit, diesmal über `spring-boot-starter-security`.

Auf das konkrete Problem der einzelnen Sicherheitslücken gehe ich heute nicht näher ein. Weitere Informationen zum `snakeyaml`-Problem finden Sie in diesem speziellen Blogbeitrag. Konzentrieren wir uns darauf, das Problem zu lösen und die beste Lösung umzusetzen.
Sicherheitslücken in Paketen Ihrer Spring-Boot-Anwendung beheben
Für die erste Sicherheitslücke gibt es eine klare Lösung. Meine Anwendung basiert auf Spring Boot 2.7.16, daher hat auch `spring-boot-starter-webflux` die Version 2.7.16.
Ein Update des Webflux-Starters auf Version 2.7.17 sollte das Problem beheben. Dafür gibt es mehrere Möglichkeiten
– aber nicht alle sind empfehlenswert.
Das Spring-Boot-Manifest sieht normalerweise etwa so aus:
Maven:
Gradle:
Spring-Boot-Starter aktualisieren
Die Versionsnummern der einzelnen `spring-boot-starters` leiten sich vom `spring-boot-starter-parent` (Maven) oder vom Plugin `org.springframework.boot` in Gradle ab.
Der Hauptgrund dafür ist, dass all diese Starter-Pakete zur selben Spring-Version gehören und als solche getestet werden.
Für die erste Sicherheitslücke in meinem Projekt wird als Lösung vorgeschlagen, `spring-boot-starter-webflux` auf Version 2.7.17 zu aktualisieren. Damit soll die schwerwiegende Sicherheitslücke behoben werden. Das legt nahe, dass ich nur das Webflux-Paket aktualisieren muss. Dazu könnte ich eine bestimmte Version festlegen, wie unten gezeigt.
Maven:
Gradle:
Aber halt! Dies ist nicht der empfohlene Weg, das Problem zu lösen. Die angegebene Version 2.7.17 wird gegenüber der übergeordneten Version verwendet. Da es sich um ein Patch-Release handelt, funktioniert das möglicherweise. Es ist jedoch nicht die beste oder sicherste Lösung. Da Semver nicht garantiert, dass APIs unverändert bleiben, können wir nicht sicher sein, dass dies funktioniert. Noch wichtiger ist aber, dass es wahrscheinlich bereits ein neues Spring-Boot-Release gibt.
Denken Sie daran, dass diese Starter zusammengehören. Am besten aktualisieren Sie daher Ihre gesamte Spring-Boot-Distribution auf Version 2.7.17. Das ist bei Minor- oder Major-Releases eines Pakets besonders wichtig, da diese die API beeinträchtigen und dazu führen können, dass die Pakete nicht reibungslos zusammenarbeiten. Gehen Sie in diesem Beispiel also wie folgt vor: Aktualisieren Sie das Parent (Maven) oder das Plugin (Gradle), anstatt einzelne Starter zu aktualisieren.
Maven:
Gradle:
Ich empfehle allen, noch einen Schritt weiterzugehen und die gesamte Spring-Boot-Version auf die neueste geeignete Version zu aktualisieren. Welche das ist, erfahren Sie ganz einfach unter https://start.spring.io.

Transitive Abhängigkeiten aktualisieren
Bei der zweiten Sicherheitslücke hat Snyk festgestellt, dass es in meiner Anwendung keine eindeutige Empfehlung zur Behebung gibt. Derzeit ist auch keine Version eines `spring-boot-starter` verfügbar, die diese unsichere transitive Abhängigkeit nicht enthält. Wir wissen jedoch, dass eine aktualisierte Version der transitiven Abhängigkeit verfügbar ist. Ein Update auf `snakeyaml` 2.0 behebt das Problem.
Noch einmal: Dies ist nur ein Beispiel. Möglicherweise ist bereits eine aktualisierte Version eines `spring-boot-starter` verfügbar, wenn Sie dies lesen. Prüfen Sie das also unbedingt. Weitere Informationen zur SnakeYaml-Sicherheitslücke finden Sie in unserem speziellen Blogbeitrag zu diesem Thema.
Versionsparameter aktualisieren
Prüfen Sie zunächst, ob die Version des Pakets, das Sie aktualisieren möchten, in Spring Boot als Property festgelegt ist. Die Spring-Boot-Dokumentation enthält einen Anhang mit den Abhängigkeitsversionen für das jeweilige Release. Dort finden Sie auch die Versionseigenschaften. Diese Properties lassen sich sowohl in Maven als auch in Gradle überschreiben, sodass eine neuere Version der transitiven Abhängigkeit verwendet wird.
In Maven können Sie im Abschnitt „properties“ eine Property hinzufügen.
In Gradle können wir diese Property in einer Datei `gradle.properties` bearbeiten:
Dies ist die bevorzugte Methode gegenüber dem Dependency Management, da `snakeyaml` nur eine einzelne Bibliothek ist. In vielen Fällen handelt es sich jedoch um mehrere Bibliotheken. Die Version kann sich auf eine BOM (Bill of Materials) beziehen – nicht zu verwechseln mit einer SBOM. Sie umfasst eine Gruppe von Paketen, die gemeinsam verwendet werden müssen und im Wesentlichen dieselbe Version haben, etwa ein API- und ein Implementierungspaket. Damit sie wie erwartet funktionieren, müssen beide dieselbe Version verwenden.
Dependency-Management-Deklaration
Alternativ können Sie die Mechanismen Ihres Build-Tools verwenden, um transitive Abhängigkeiten zu aktualisieren. Nutzen Sie diese Möglichkeit nur, wenn Sie die Property-Version nicht wie im vorherigen Abschnitt beschrieben aktualisieren können.
In Maven wird dies meist im Block `dependencyManagement` hinzugefügt. Dadurch wird sichergestellt, dass die dort angegebene aktualisierte Version jedes Mal verwendet wird, wenn die Bibliothek als transitive Abhängigkeit eingebunden wird.
Maven:
Da wir in unserer Gradle-Datei das dependency-management-Plugin für Spring verwenden, stehen uns in Gradle sehr ähnliche Funktionen zur Verfügung. Beachten Sie, dass dieses Plugin beim Erstellen meines Projekts vom Spring-Boot-Initializer eingefügt wurde.
Gradle:
Wenn Sie das Plugin `io.spring.dependency-management` nicht verwenden, können Sie in Gradle auch Constraints für transitive Abhängigkeiten hinzufügen, um eine solche Abhängigkeit wie unten gezeigt zu aktualisieren. Beachten Sie, dass diese Constraints nicht gut mit dem Spring-Plugin `dependency-management` zusammenspielen. Sie müssen sich also für eine der beiden Optionen entscheiden.
Spring-Boot-Anwendungen mit Snyk scannen
Das Scannen Ihrer Spring-Boot-Anwendung mit Snyk ist entscheidend für die Sicherheit und Stabilität Ihrer Software. Snyk hilft Ihnen dabei, Sicherheitslücken in den Abhängigkeiten Ihrer Anwendung zu erkennen, die von Angreifern ausgenutzt werden könnten, wenn sie nicht behoben werden. Nach der Lektüre dieses Artikels wissen Sie auch, wie Sie die von Snyk empfohlenen Maßnahmen am besten umsetzen.
Durch regelmäßige Scans Ihrer Codebasis können Sie Sicherheitsprobleme proaktiv angehen und das Risiko von Datenschutzverletzungen und anderen Sicherheitsvorfällen senken. Integrieren Sie Scans also in Ihren regulären Workflow und stellen Sie sicher, dass Sie wissen, wie Sie im Fall einer Sicherheitslücke reagieren müssen.
Unten habe ich meine Anwendung vor und nach der Behebung mit der Snyk CLI gescannt. Zur Behebung habe ich die allgemeine Spring-Boot-Version aktualisiert und die spezifische Versionseigenschaft für `snakeyaml` angepasst.
Vorher:

Nachher:

Wenn Sie also mit Snyk eine Sicherheitslücke in einer Abhängigkeit Ihrer Spring-Boot-Anwendung finden, gehen Sie folgendermaßen vor:
Aktualisieren Sie die allgemeine Spring-Boot-Version, anstatt nur einen bestimmten Starter zu aktualisieren.
Wenn Sie die Spring-Boot-Version aktualisieren, reicht es nicht aus, nur die Versionseigenschaften der Spring-Boot-Abhängigkeiten zu aktualisieren.
Verwenden Sie Dependency Management in Maven oder Gradle, um bestimmte transitive Abhängigkeiten zu aktualisieren.
Starten Sie mit Capture-the-Flag
Erfahren Sie in unserem virtuellen On-Demand-Workshop für Einsteiger, wie Sie Capture-the-Flag-Challenges lösen.



