Spring Boot vs. Security Vulnerabilities

Der Security-Scanner in eurer CI/CD-Pipeline hat eine kritische Security Vulnerability gefunden. In einer 3rd-Party-Bibliothek gibt es eine Schwachstelle.
Der Scanner kennt bereits die Lösung: ein Upgrade der Bibliothek.
Doch ist das wirklich immer die beste Idee?
Oder gibt es Aspekte wie Wartbarkeit und Stabilität zu beachten?

Security Scanner und Vulnerabilities

CI/CD-Pipelines mit Code-Scannern sind essenzielle Werkzeuge in der professionellen Softwareentwicklung. In meinem Projekt nutzen wir eine GitLab CI/CD-Pipeline mit diversen Scannern. Einer davon analysiert unsere Third-Party-Bibliotheken auf Sicherheitslücken, also veraltete Abhängigkeiten mit bekannten Schwachstellen. Diese werden in einem Report aufgelistet. Für jede Schwachstelle sind detaillierte Informationen abrufbar. 

Hier ein Beispiel aus einem Java-Projekt mit Spring Boot 3.4.2.

  • Titel und Beschreibung der Vulerability bzw. des Security Problems.
  • Severity: Kategorisiert die Kritikalität in fünf Stufen von "Info" bis "Kritisch" (im Beispiel "Hoch").
  • Location: Zeigt die betroffene Stelle, hier das Dependency-Management in der pom.xml.
  • Evidence & Solution: Nennen die betroffene Bibliothek und die gefixte Version.

Security Vulnerability gefunden - was nun?

Ist eine Sicherheitslücke gefunden, scheint die Lösung klar:
Upgrade der betroffenen Bibliothek auf die gefixte Version.
Doch ist das immer der beste Weg?

Wann ein direktes Upgrade notwendig ist

Ja - bei extrem kritischen Sicherheitslücken! Diese sollten so schnell wie möglich gefixt werden, da eine unmittelbare Bedrohung besteht (z. B. Remote Code Execution oder bekannte Exploits in der Wildnis).

Wann ein direktes Upgrade problematisch sein kann

In allen anderen Fällen müssen wir die Konsequenzen solcher Upgrades abwägen:

1. Auswirkungen auf die Stabilität

Unsere Software wurde mit den bestehenden 3rd-Party-Bibliotheken getestet. Wird eine Version geändert, können unerwartete Probleme auftreten. Deshalb sind nach einem Upgrade erneute, idealerweise automatisierte Tests notwendig, um Stabilitätsrisiken und neue Bugs auszuschließen.

2. Herausforderungen für die Wartbarkeit

Die meisten professionellen Software-Systeme setzen auf ein Framework wie Spring Boot, weil es das Dependeny- und Versions-Management übernimmt. Wird eine Dependency manuell aktualisiert, kann das zu Inkonsistenzen führen. Konkret stellt sich die Fragen:

  • Kann der Security-Fix später entfernt werden, wenn Spring Boot das Problem selbst löst?

  • Ist die neue Spring-Boot-Version kompatibel mit der gefixten Bibliothek?

Jede manuelle Änderung erhöht den Wartungsaufwand.

Konkretes Beispiel: Fix einer betroffenen Bibliothek

Zurück zur konkreten Security Vulnerability aus dem vorherigen Screenshot. Die Bibliothek json-smart ist betroffen und benötigt ein Upgrade. Mit IntelliJ analysiere ich die Maven-Konfiguration, um herauszufinden, dass json-smart von spring-boot-startet-test benutzt wird.

 
Der Fix der Dependency erfolgt in 2 Schritten:
  1. Die betroffene Bibliothek json-smart wird per "exclusion" aus der Bibliothek spring-boot-starter-test entfernt.
  2. Die Upgrade-Version der Bibliothek wird mit Versionsangabe "2.5.2" extra in die Liste der Dependencies aufgenommen.
 Konkret sieht es so in der pom.xml aus:
<dependencies>
<!-- other dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>json-smart</artifactId>
<groupId>net.minidev</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>net.minidev</groupId>
<artifactId>json-smart</artifactId>
<version>2.5.2</version>
<scope>test</scope>
</dependency>
</dependencies>
Ohne Security-Fix würden wir uns das Management von json-smart sparen, dann macht Spring Boot das.
<dependencies>
<!-- other dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

Praktischer Umgang mit Dependency-Vulnerabilities

Es gibt drei mögliche Strategien im Umgang mit Sicherheitslücken in Abhängigkeiten:

  • Direkter Fix (Upgrade der betroffenen Bibliothek)
    • Vorteile: Schnell umsetzbar
    • Nachteile: Erhöhter Wartungsaufwand, mögliche Stabilitätsprobleme
  • Indirekter Fix (Upgrade des Frameworks, z. B. Spring Boot)
    • Vorteile: Nachhaltiger, besser für Wartbarkeit
    • Nachteile: Weitere indirekte Updates, die getestet werden müssen,
      nicht immer sofort verfügbar
  • Ignorieren (wenn nicht relevant)
    • Vorteile: Kein zusätzlicher Aufwand
    • Nachteil: Risiko, wenn Schwachstelle doch kritisch ist

Wann ignorieren eine sinnvolle Option ist

Nicht jede gemeldete Schwachstelle ist relevant. Security Scanner haben oft False Positives. Ein typisches Beispiel ist eine Sicherheitslücke in einer Test-Dependency.

Im obigen Beispiel betrifft json-smart nur spring-boot-starter-test, das ausschließlich in automatisierten Tests verwendet wird (siehe scope="test"). Da es nicht produktiv genutzt wird, kann man den Fix ignorieren, insbesondere wenn die aktuellste Version von Spring Boot genutzt wird und kein indirektes Update verfügbar ist.

Indirekter Fix durch Upgrade des Frameworks

Ein indirekter Fix bedeutet, dass wir die Version unseres Frameworks (z. B. Spring Boot) aktualisieren. Dadurch erhalten wir nicht nur den Security-Fix, sondern modernisieren gleichzeitig unser System. Dabei werden auch weitere Bibliotheken aktualisiert, was zusätzliche Änderungen im System mit sich bringt. Dies kann zu unerwarteten Nebenwirkungen führen, weshalb Regressionstests notwendig sind. Dennoch ist dies die beste langfristige Lösung für die Wartbarkeit, da sie das System aktuell hält und zukünftige Sicherheitsrisiken reduziert.

Gerade in großen Projekten mit vielen Schwachstellen führen direkte Fixes zu einer Verschlechterung der Wartbarkeit. Daher sollte bevorzugt geprüft werden, ob eine Aktualisierung des Frameworks möglich ist.

Fazit

Security-Schwachstellen sollten ernst genommen werden, aber nicht blind gefixt werden.
Die richtige Strategie hängt vom konkreten Fall ab:

Extrem kritische Lücke? → Direktes Upgrade notwendig
Weniger kritische Lücke? → Indirektes Upgrade oder warten auf indirektes Upgrade
Nicht produktiver Code betroffen? → Ignorieren oder indirektes Upgrade

Im Idealfall fixt ihr Sicherheitslücken, indem ihr euer Framework aktualisiert.
Das sorgt nicht nur für Sicherheit, sondern hält euer Software-System langfristig wartbar und stabil.