zurück zum Artikel

DevSecOps: Mit DevOps-Prinzipien kontinuierlich sicherer werden

Martin Reinhardt
DevSecOps: Mit DevOps-Prinzipien kontinuierlich sicherer werden

Gerade vor dem Hintergrund zunehmend kürzerer Releases durch Continuous Delivery wird häufig die Sicherheit vernachlässigt. Penetrationstests sind dabei als Sicherheitsmaßnahmen nicht ausreichend. Es bietet sich aber auch die Chance, schneller zu reagieren.

Der erste Teil dieser Artikelserie hat sich mit grundlegenden Informationen zur Sicherheit in der Softwareentwicklung auseinandergesetzt. Der zweite gab einen Überblick über die Werkzeuge von Hackern. Im dritten Teil werden nun Aspekte beleuchtet, um kontinuierlich Sicherheit in den Softwareentwicklungsprozess zu verankern.

Mehr Infos

DevSecOps – die Serie

Neben klassischer Java-Architekturen gilt es in vielen Softwareprojekten mittlerweile, die derzeit populären JavaScript-Umgebungen miteinzubeziehen. Deren Schnelllebigkeit bringt dabei eine weitere Dimension in die Betrachtung, die aber damit auch eine Chance bietet. Es sollten jedoch nicht nur technische Maßnahmen etabliert werden, wichtig ist, dass auf Entwicklerseite mehr Sicherheitsbewusstsein entsteht.

In vielen Fällen kann Nachlässigkeit selbst ausgefeilte Abwehrmaßnahmen zunichte machen. So kann die Nutzung ungesicherter Hotspots schnell in Datendiebstahl enden. Es gilt generell zu beachten: Interne Netzwerke sind nicht per se sicher [3]. Auch in einem internen Netzwerk sind Absicherungsmaßnahmen zu treffen. Außerdem sollte man bei Sicherheitsbetrachtungen den Testcode nicht vernachlässigen, so lassen sich Test-Tools für Exploits im CI-Server nutzen.

Continuous Delivery Pipeline mit Security (Abb. 1)

Continuous Delivery Pipeline mit Security (Abb. 1)

Ein essenzieller Bestandteil sind um so mehr Authentifizierungsstrategien und pragmatische Rollenkonzepte. Eine Modellierung, die den konkreten Schutzbedarf berücksichtigt, kann helfen:

Modellierung nach Schutzbedarf (Abb. 2)

Modellierung nach Schutzbedarf (Abb. 2)

In der Praxis werden zwar häufige Passwortwechsel immer noch stark propagiert, aber sie schaffen dabei mehr Probleme, als sie lösen. Ein ereignisbezogener Passwortwechsel neben einem jährlich eingeplanten helfen dabei mehr. So lassen sich Konten eher auf Exploits überwachen, zum Beispiel über Dienste wie "have I been pwned? [4]" oder ähnliche Angebote.

Auch das Sperren sollte nicht dauerhaft erfolgen, sondern temporär, um nicht anfällig für Denial-Of-Service-Attacken zu sein. Überdies sollten Passwörter immer sicher, das heißt ausreichend verschlüsselt abgelegt werden. Bei technischen Konten helfen lange, generierte Passwörter, sodass ein Wechsel erst anlassbezogen nötig ist, zum Beispiel bei Personalwechsel, Abteilungswechseln oder bekannten Datenabflüssen.

Lediglich bei Administrationskonten sollten weitere Schutzmaßnahmen mit einem weiteren Authentifizierungsmechanismus ergriffen werden. Ein durchgängiges Rollen- und Rechtekonzept, das nur die erforderlichen Rechte hat, hilft in der Praxis meist mehr, um Angriffsvektoren zu minimieren.

Audits, Penetrationstests und Security-Monitoring sorgen bei Entwicklern eher nicht für Begeisterung: Aber letztlich sind das die Tests für die Security und sie haben damit die gleiche Bedeutung wie die in der Entwicklung. Dabei ist es wichtig, regelmäßig Rechtevergaben zu überprüfen: In Jenkins gibt es etwa mittlerweile ein Plug-in [5], um bei Audits die konkreten Rechte von Nutzern stichprobenartig zu prüfen.

Abseits von Tools können Projekte den Entwicklungsprozess anpassen, indem sie "Threat Modeling" einsetzen [6]. Nicht zuletzt wegen der DSGVO ist das ein essenzieller Aspekt der Anforderungsanalyse, auch in agilen Projekten. Dabei versucht man letztlich Sicherheitsziele auf Risiken und Eintrittswahrscheinlichkeiten zu mappen. Ein guter Ausgangspunkt sind die STRIDE-Kategorien [7]:

Angriff Vorgehen Verletztes Prinzip
Repudiation Ablehnung von Fakten Non-Repudiation
Information disclosure Unbefugter Zugriff auf Informationen Confidentiality
Denial of service Nutzung einschränken oder verhindern Availability
Elevation of privilege Erschleichung von höheren Privilegien Authenticity

Gerade bei Architekturentscheidungen ist es wichtig, das Thema Security auf dem Radar zu haben. Wem Stride zu trocken ist, dem kann Cornucopia von OWASP [8] als Kartenspiel weiterhelfen, um unter dem Aspekt der Gamification dem Thema mehr Schwung zu geben. Ein nächster Schritt, um technische Aspekte bei den Anforderungen sinnvoll zu beleuchten, können die OWASP Top Ten [9] sein: Dieses Awareness-Dokument zeigt, wo Application Security anfängt. Die letzte Aktualisierung von 2017 hat einige interessante Anpassungen erfahren [10]:

Veränderung in den OWASP Top 10 (Abb. 3)

Veränderung in den OWASP Top 10 (Abb. 3)

Diese zeigen, dass vor allem die Ausnutzung unzureichender Absicherung (A6 auf A3 vorgerückt, sowie A5 und A9) die größten Angriffsvektoren bieten. Der Punkt A10 zum Thema Logging ist neu hinzugekommen und vor allem in Microservice-Architekturen oft vernachlässigt. Mit DSGVO hat das Thema aber in den letzten Monaten mehr Beachtung bekommen.

Die OWASP Top 10 kann man insoweit als Best Practice für den Bereich Websicherheit ansehen, die in der Fachwelt großen Zuspruch bekommt. Ergänzend lässt sich das Proactive-Controls-Dokument [11] nutzen, um ein gewisses Maß an Basiswissen bezüglich Sicherheit zu vermitteln.

Außerdem können die Application Security Verification Standards (ASVS) [12] helfen, Akzeptanzkriterien zu definieren. Dabei legt ASVS drei Stufen fest, wobei der Risiko-Level abnimmt:

DevSecOps: Mit DevOps-Prinzipien kontinuierlich sicherer werden

ASVS Level (Abb. 4)

ASVS setzt auf den Top Ten auf: Stufe 1 deckt die Top Ten soweit ab. Damit eignet sich dieser Standard bestens, um seine Anforderungen zu verifizieren. Er beschreibt für 19 Kategorien, welche Punkte man abarbeiten muss. Zu den Kategorien gehören zum Beispiel Architektur, Authentifizierung und Zugangskontrolle. Es ist generell zu empfehlen, Stufe 2 umzusetzen. Die dritte Stufe ist eher für kritische Bereiche wie Flughäfen, Medizin oder andere streng regulierte Einsatzgebiete gedacht.

Gerade aufgrund der DSGVO haben Sicherheitsaspekte zunehmend mehr Einfluss auf die Architektur. So gibt es Konzepte wie "Crypto Delete", um die ausufernde Verwendung personenbezogener Daten zu vermeiden [13].

Static Application Security Testing (SAST) lässt sich als erster Schritt gut in eine Build Pipeline einbetten, um eine statische Analyse des Quellcodes durchzuführen. Man muss aber gar nicht mit kommerziellen Tools loslegen, um Security zu implementieren. Es gibt mittlerweile gute Open-Source-Werkzeuge: Das Node Security Project hat beispielsweise seinen Weg direkt in npm (setzt mindestens Version 6 voraus) gefunden, um die Prüfung der Abhängigkeiten auf bekannte Schwachstellen zu automatisieren:

$ npm audit
=== npm audit security report ===

# Run npm install --save-dev node-mock-server@0.23.5 to resolve 1 vulnerability
???????????????????????????????????????????????????????????
? High ? Remote Code Execution ?
???????????????????????????????????????????????????????????
? Package ? react-dev-utils ?
???????????????????????????????????????????????????????????
? Dependency of ? node-mock-server [dev] ?
???????????????????????????????????????????????????????????
? Path ? node-mock-server > react-dev-utils ?
???????????????????????????????????????????????????????????
? More info ? https://nodesecurity.io/advisories/695 ?
???????????????????????????????????????????????????????????
...

In den meisten Fällen genügt ein einfaches npm audit fix, um gepatchte Versionen der Abhängigkeiten zu installieren. Reicht das nicht aus, macht npm direkt Vorschläge (s. o.).

In der Java-Welt bietet sich das OWASP Dependency Check Plugin an. Es ist für Ant, Gradle und Maven verfügbar und prüft alle Abhängigkeiten gegen die CVE-Datenbank:

[ERROR] Failed to execute goal org.owasp:dependency-check-maven:1.4.0:check (default) ...
[ERROR]
[ERROR] Dependency-Check Failure:
[ERROR] One or more dependencies were identified with vulnerabilities
that have a CVSS score greater then '5.0':
[ERROR] commons-httpclient-3.1.jar: CVE-2014-3577
[ERROR] mysql-connector-java-5.1.37.jar: CVE-2014-0001, CVE-2013-2378, ....
[ERROR] tomcat-embed-core-8.0.33.jar: CVE-2016-3092, CVE-2013-2185, CVE-2002-0493

Neben Ausnahmen kann man einen Schwellwert (CVSS Score) festlegen, ab dem der Build fehlschlagen soll. Hier bietet es sich an, gegebenenfalls mit höheren Werten zu arbeiten. Zwar ist ein niedriger CVSS Score erstrebenswert, da dann weniger gefährliche Schwachstellen erlaubt sind, aber gerade am Anfang sollte man sich langsam herantasten, um nicht den Frust auf Entwicklungsseite zu hoch zu schaukeln. Gerade in modernen Microservice-Architekturen ist Docker mittlerweile unverzichtbar geworden. Deswegen sollten auch Docker-Images auf Schwachstellen gescannt werden. Dazu lassen sich Werkzeuge wie Clair [14] nutzen. Sie lassen sich auch direkt in Docker Registries integrieren.

In weiteren Schritten können Analysewerkzeuge wie Sonar mit FindBugs beziehungsweise SpotBugs inklusive des Find-Security-Bugs-Plug-ins [15] genutzt werden, um weitere Sicherheitsaspekte zu prüfen:

Secure Continuous Delivery Pipeline (Abb. 5)

Secure Continuous Delivery Pipeline (Abb. 5)

Im letzten Schritt lässt sich nun Dynamic Application Security Testing (DAST) umsetzen: Dazu wird die Anwendung deployt und mit Tools wie OWASP ZAP im Ganzen auf Schwachstellen geprüft. ZAP kann genutzt werden, um die Anwendung auf Verwundbarkeit durch unter anderem Cross-Site Scripting und SQL-Injection zu testen. Das Tool läuft dabei als Proxy zum Beispiel in Selenium-Tests mit und kann die HTTP-Requests überprüfen. Zusätzlich lassen sich Tools wie Nessus und OpenVAS nutzen, um im Rahmen von Integrations-Tests auf Schwachstellen zu scannen. Um ein einheitliches Reporting aller sicherheitsrelevanten Informationen in JIRA zu ermöglichen, können Entwickler ThreadFix verwenden. Es kann diverse Sicherheitsergebnisse aggregieren, unter anderen OWASP Dependency Check, ZAP, Sonatype Nexus und die BurpSuite.

Gerade bei agil arbeitenden Teams ist es wichtig, verschiedene Kontrollpunkte mit automatischen Sicherheitstests zu etablieren. Ein sinnvoller erster Schritt können statische Codeanalysen sein, die im Rahmen der Build-Pipeline ausgeführt werden. Zusätzlich sollten sinnvolle Techniken zum Verwalten technischer Log-ins wie Spring Vault [16] berücksichtigt werden.

Im Rahmen der Definition of Done (DoD) können aber auch bestimmte Sicherheitsüberprüfungen berücksichtigt werden. Für Continuous Delivery gibt es Tools, um bekannte Schwachstellen zu erkennen. Setzen Entwickler diese im Rahmen von Continuous Integration ein, erhalten sie einen ersten Kontrollpunkt, der sicherstellt, dass sich bekannte Sicherheitslücken nicht ausnutzen lassen.

Neben statischen Analysewerkzeugen wie Sonar und FindBugs ist es durchaus sinnvoll, die Abhängigkeiten in umfangreichen Java-Anwendungen kontinuierlich auf bekannte Schwachstellen zu prüfen. Dabei kann das OWASP-Dependency-Check-Maven-Plug-in [17] helfen. Neben der klassischen Java-Architektur gilt es bei einer solchen Betrachtung aber auch, die gerade populären JavaScript-Umgebungen miteinzubeziehen. Deren Schnelllebigkeit bringt eine weitere Dimension in die Betrachtung. Deswegen ist es gut zu wissen, dass es mit dem Node-Security-Projekt (NSD) [18] auch im JavaScript-Bereich ein geeignetes Tool gibt. Beide Werkzeuge gleichen die jeweiligen Abhängigkeiten nach bekannten Schwachstellen ab. GitHub bietet für NSP eine direkte Integration, sodass Prüfungen auch in Pull Requests stattfinden. Außerdem bietet sich für Open-Source-Projekte CodeClimate an, das die generelle Codequalität berücksichtigt.

Durch die gerade im Java- und Node.js-Umfeld verbreitete Nutzung von Bibliotheken wird die zeitnahe Aktualisierung zu einer umfangreichen und ständig wiederkehrenden Aufgabe. Immerhin lässt sich die aufwendige Suche nach der neuesten Version und den darin gestopften Sicherheitslöchern mit dem OWASP Dependency Check und Node Security Project deutlich erleichtern. Diese Tools ersetzen keine Penetrationstests, aber sie helfen, einen Teil der Probleme früh zu erkennen. Es ist in zeitgemäßen Softwaresystemen daher unerlässlich, ein Sicherheitsbewusstsein aufzubauen, das schon in der Entwicklung greift.

Automatische Tests auf Schwachstellen stellen dabei nur den ersten Schritt dar, siehe die Artikel-Demo [19]. Das Sicherheitsbewusstsein ist bei den Entwicklern zu schärfen. Gerade mit dem "Selbsthacken" wird das Ganze mit sportlichem Ehrgeiz und Spaß verbunden. Es gibt dazu auch Online-Kurse, beispielsweise von PluralSight.

Im Rahmen von DevSecOps sollen Entwickler, Betrieb und Sicherheitsfachleute in einem Team zusammenarbeiten. Zunehmend mehr Betriebsaufgaben werden in Zukunft an die Entwicklung übergehen. Der Trend zur Cloud-Nutzung verstärkt das. Gerade die Cloud entlastet dabei die Mitarbeiter von den lästigen Systemverwaltungsaufgaben. Stattdessen können sie mit den Entwicklern und dem Security-Officer ein proaktives Monitoring aufsetzen. Erst so ist es möglich, Anwendungen zur Laufzeit mit Intrusion-Detection-Systemen zu verbinden. Damit lassen sich Angriffsmuster frühzeitig erkennen.

DevSecOps bedeutet, die Sicherheit in die App-Entwicklung von Anfang bis Ende zu integrieren. Diese Integration in die Pipeline erfordert eine neue organisatorische Denkweise ebenso wie neue Werkzeuge. Vor diesem Hintergrund sollten DevOps-Teams die Sicherheit automatisieren, um die gesamte Umgebung und die Daten sowie den kontinuierlichen Integrations- und Bereitstellungsprozess zu schützen – ein Ziel, das auch die Sicherheit von Microservices in Containern umfasst:

Martin Reinhardt
arbeitet als Architekt bei der Management- und IT-Unternehmensberatung Holisticon AG. Er beschäftigt sich dort mit der Architektur komplexer verteilter Systeme, moderner Webarchitekturen und Build-Management. Als Software Craftsman sind ihm pragmatische Lösung, gerade vor dem Aspekt von Sicherheit und Automatisierung in Continuous Delivery, wichtig.
(ane [20])


URL dieses Artikels:
https://www.heise.de/-4455535

Links in diesem Artikel:
[1] https://www.heise.de/hintergrund/DevSecOps-der-naechste-Hype-nach-DevOps-und-Containern-4325496.html
[2] https://www.heise.de/hintergrund/DevSecOps-selbst-hacken-und-dabei-lernen-4380292.html
[3] https://www.oreilly.com/library/view/zero-trust-networks/9781491962183/ch01.html
[4] https://haveibeenpwned.com
[5] https://plugins.jenkins.io/security-inspector
[6] https://blog.holisticon.de/2018/09/gdpr-no-data-to-the-rescue/
[7] https://docs.microsoft.com/en-us/previous-versions/commerce-server/ee823878(v=cs.20)
[8] https://www.owasp.org/index.php/OWASP_Cornucopia
[9] https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project
[10] https://www.heise.de/ratgeber/OWASP-Top-10-Kritischer-Blick-auf-die-Charts-3953648.html
[11] https://www.owasp.org/index.php/OWASP_Proactive_Controls
[12] https://www.owasp.org/index.php/Category:OWASP_Application_Security_Verification_Standard_Project
[13] https://blog.holisticon.de/2018/09/gdpr-no-data-to-the-rescue
[14] https://github.com/coreos/clair
[15] https://find-sec-bugs.github.io
[16] http://projects.spring.io/spring-vault/
[17] https://www.owasp.org/index.php/OWASP_Dependency_Check
[18] https://www.npmjs.com/advisories
[19] https://github.com/holisticon/web-security-sample
[20] mailto:ane@heise.de