Originalartikel von David Fiser
Jenkins ist ein weit verbreiteter quelloffener Automatisierungsserver für Entwickler, vor allem in DevOps-Teams. Er erledigt vor allem Aufgaben wie Software-Projekt-Builds oder die automatisierte Integration von Komponenten ins Anwendungsprogramm. Der Einsatz von Jenkins bietet viele Vorteile und bringt auch eine gewisse Sicherheit mit. Doch entdeckten die Sicherheitsforscher auch potenzielle Security-Probleme, wie Missbrauch der Shell oder Remote-Code-Ausführung auf dem Master.
Der Server baut auf einer verteilten Architektur auf: Eine Master-Maschine verwaltet eine Gruppe von Agenten (auch Slaves genannt), Java Executables, die auf Remote-Maschinen laufen und Build-Jobs ausführen. Die modulare Architektur von Jenkins bringt es mit sich, dass die meisten Fähigkeiten in Plugins implementiert sind, die die Kernfunktionalität erweitern, so etwa nachgelagerte Build Aufgaben.
Jenkins unterstützt auch Sicherheitsaspekte über das Matrix-basierte Modell, und darüber hinaus ist es sehr einfach ein weiteres offizielles Jenkins-Image von Docker Hub zu ziehen. Es besteht jedoch die Gefahr, dass Entwickler bei der Nutzung mit den Standardeinstellungen und aktivierter Matrix-basierten Sicherheit davon ausgehen, in einem sicheren Setup zu arbeiten. Leider entdeckten die Sicherheitsforscher von Trend Micro, dass diese Einstellung möglicherweise zu Sicherheitsproblemen führt.
Die Analyse zeigte, dass ein Nutzerkonto mit weniger Privilegien Admin-Rechte für den Automatisierungsserver erlangen kann, wenn Jobs auf der Master-Maschine aufgesetzt werden (d.h. dem Haupt-Jenkins-Server). Dieses Setup ist standardmäßig aktiviert. Dafür könnte mithilfe von Shell Spawn – einem Standard-Build-Schritt — einfach ein Exploit geschrieben werden. Wird ein Exploit erfolgreich eingesetzt, kann ein Angreifer eine Remote Code Execution (RCE) auf dem Master durchführen und als Folge Jenkins vollständig überschreiben.
Trend Micro hat diese Ergebnisse dem Jenkins-Projekt bereits mitgeteilt. In ihrer Antwort stellte das Jenkins-Team fest, dass es sich dabei nicht um eine Sicherheitsschwachstelle handle und verweisen auf ihr Nutzerhandbuch und Wiki.
Jenkins Standard-Sicherheitseinstellungen
Der Sicherheitsseite von Jenkins zufolge sind viele Sicherheitsoptionen in der Version 2.0 standardmäßig aktiviert, es sei denn bestimmte Schutzmechanismen werden vom Admin explizit abgeschaltet. Sicherheit lässt sich über die Configure Global Security-Seite konfigurieren. Standardmäßig schützt Security Realm (Authentifizierung) die Jenkins-eigene Nutzerdatenbank. Es fällt auf, dass der Master die Nutzerdatenbank speichert und dass mit diesem Setting angemeldete Nutzer auf alles Zugriff haben.
Unter Authorization können Optionen wie Matrix-basierte Sicherheit und Projekt-basierte Matrix-Autorisierungsstrategie aktiviert werden. Somit kann der Admin den Zugriff auf bestimmte Jenkins-Fähigkeiten einschränken.
Ausführen von Shell Spawn dem Master
Ein lose konfiguriertes Setting erlaubt es einem böswilligen Akteur, diese zu seinem Vorteil zu missbrauchen. Die folgenden Schritte laufen bei der Durchführung eines Jobs ab:
- Build anstoßen
- Source Code Management (SCM) – Abfrage des Quellcodes
- Aufsetzen der Build-Umgebung
- Ausführen von Build-Schritten (Konfigurieren des Compilers etc.)
- Nachgelagerte Build-Aktionen (Tests, Inbetriebnahme etc.)
Die Scripting-Fähigkeiten von Build-Schritten lassen sich mit Plugins in Jenkins erweitern. Eine der Standardfunktionen innerhalb der Build-Schritte, Execute Shell, ist das riskante Thema.
Anstatt alle einzelnen möglichen Funktionen des Build-Skripts in der Webanwendung zu implementieren, lässt sich der Prozess durch das Skripting eines Build-Prozesses – eine gängige Praxis – beschleunigen. Die Ausführung von Shell Spawn innerhalb der Webanwendung birgt jedoch Sicherheitsrisiken, insbesondere wenn die Benutzerberechtigungen nicht korrekt zugewiesen sind.
Wenn Jenkins-Nutzer unnötige Berechtigungen erhalten, so kann das möglicherweise zur Kompromittierung der Sicherheit führen. Ein Plugin namens Script Security hilft beispielsweise, diesem Risiko entgegenzuwirken, da es die Ausführung von nicht vertrauenswürdigen Groovy-Skripts über eine Whitelist-basierte Sandbox einschränken kann. Groovy-Skript kann nur mit Admin-Genehmigung oder in einer Sandbox ausgeführt werden. Der Zweck der Sandbox liegt darin, Situationen zu vermeiden, wo der Benutzer die Jenkins-Instanz manipulieren kann und interne Funktionen aufruft, z. B. Jenkins.getInstance().
Im Gegensatz dazu ist die Execute-Shell-Funktionalität nicht beschränkt und bedarf keiner Genehmigung durch den Admin. Damit können Nutzer mit weniger Privilegien eine Shell spawnen und ihre Skripts ausführen. Dies kann riskant sein, wenn Jobs auf dem Master ausgeführt werden. Der Master speichert Jenkins-Konfigurationen, Anwendungs-Binaries, Job-Definitionen und die Nutzerdatenbank. Da Jobs unter demselben Nutzer ausgeführt werden wie die Jenkins-Anwendung und weil das Job-Working-Verzeichnis innerhalb von JENKINS_HOME liegt, ist der Zugriff auf die Konfigurationsdatei über einen relativen Dateipfad erlaubt, und Jenkins-Dateien dürfen gelesen, geschrieben und ausgeführt werden.
Angriffsszenarien
Wer sich auf Jenkins Standardeinstellungen verlässt, läuft Gefahr, Opfer des folgenden Angriffsszenarios zu werden. In einer solchen Konfiguration ist ein Nutzer mit nur geringen Privilegien mit folgenden Rechten angemeldet:
Mit obigen Rechten kann ein Angreifer einen bösartigen Job erstellen und/oder modifizieren, indem er Shell Script spawnt. Die Verfügbarkeit der Tools, die der Angreifer einsetzen kann, ist auf die Plattform beschränkt. Läuft Jenkins auf einer Linux-Plattform, etwa einem offiziellen Jenkins Docker Container, wo die Umgebung Binaries wie echo, sed, Python und wget enthält, hat der Akteur eine Vielzahl an Optionen um aus der Ferne Code auszuführen. Details zu den möglichen Aktionen sowie einen Machbarkeitsbeweis umfasst der Originalbeitrag.
Sicherheitsempfehlungen
Im Allgemeinen sollten Admins das Prinzip der Mindestprivilegien für den Zugriff auf Ressourcen anwenden, sodass Nutzer nur die benötigten Aufgaben ausführen können. Services und Software, die Nutzer nicht einsetzen, können limitiert, ersetzt oder gar ganz deaktiviert werden.
Die Risiken im Zusammenhang mit den Standard-Sicherheitseinstellungen sind nicht nur auf den Missbrauch der Shell beschränkt sondern schließen auch die Ausführung von bösartigem Code auf dem Master mit ein. Deshalb ist es zu empfehlen, die Ausführung von Jobs auf dem Master-Knoten zu deaktivieren. Shell Spawn, um Konfigurationen in den Slave-Umgebungen zu manipulieren, etwa Container, wird nicht funktionieren, weil sie vom Master isoliert sind. Das Jenkins-Projekt hat bereits eine Warnung und auch Empfehlungen bezüglich dieses Autorisierungsproblems veröffentlicht. Um die Rechte für die Ausführung von Jobs einzuschränken, empfehlen sie das Authorize Project-Plugin.
Des Weiteren sollte auch Shell, unter anderen Plugins, deaktiviert werden, wenn es nicht gebraucht wird. Die Shell-Ausführung lässt sich mithilfe der Einstellung von Shell Executable auf /bin/false auf der Configure System-Seite einschränken. Das /bin/false-Binary wird ausgeführt, doch ein Argument, das an das Shell Script weitergegeben wird, hat zur Folge, dass die App endet und keinen Input verarbeitet.
Unternehmen können sich auch mithilfe der Trend Micro DevOps Security-Lösungen schützen, die dazu beitragen, Sicherheit über APIs fest in den Entwicklungsprozess einzufügen. Damit verbessern sie den Entwicklungsprozess und reduzieren die Berührungspunkte und auch die Möglichkeit, Fehler zu begehen. Die Sicherheitslösungen tragen dazu bei, das Unterbrechungen in der Zeitplanung der Entwicklung und Workflows reduziert werden, denn sie bieten Schutz für Images, Container und Hosts, indem sie die Sicherheits-Feedback-Schleife schnell schließen.