Über unsMediaKontaktImpressum
Andreas Falk 27. September 2016

SecDevOps – Kontinuierlich sichere Software bauen

Es vergeht inzwischen kaum ein Tag ohne eine neue Meldung einer gehackten Webanwendung bzw. Datenbank, einhergehend mit dem Diebstahl von Kreditkartendaten oder Passwörtern. Mit dem Internet of Things hält die Software nun auch zunehmend Einzug in unsere physische Welt. Auch hier wurden erste Angriffsversuche bekannt wie u. a. ferngesteuerte Jeeps oder fremde Stimmen aus internetfähigen Baby-Phones. Gartner zählt daher Security inzwischen zu den Top 10 der Technologietrends für 2016.

DevOps und Continuous Delivery sind zusammen mit agilen Vorgehensmodellen aktuell weit verbreitet in der Softwareentwicklung. SecDevOps (Secure DevOps) ist eine relativ neue Bewegung als Reaktion auf die stetig wachsenden Sicherheitsanforderungen im Software-LifeCycle (Entwicklung, Deployment und Betrieb von Software). Dieser Artikel gibt eine Einführung in die Thematik und stellt die wichtigsten Konzepte vor.

Continuous Delivery wird erst durch die Kommunikation, Zusammenarbeit und Integration zwischen Entwicklung und Betrieb ermöglicht. Diese Prinzipien werden entsprechend in Kombination mit agilen Vorgehensmodellen wie Scrum oder Kanban in vielen Projekten heute schon praktiziert. Allerdings wird die Luft erheblich dünner, wenn es dann in Richtung Security geht. Häufig wird Software in kurzen Zeitabständen (Tage, Stunden oder Minuten) in Produktion gebracht, die dann allerdings nur sporadisch durch einen externen Penetrationstester unter die Lupe genommen wird und dann für die weitere Zukunft erstmal als sicher eingestuft wird.

In Abb.1 wird die Diskrepanz hinsichtlich der Zeitplanung der Angreifer und der Taktung von Deployments und Penetrationstests deutlich. Während die Angreifer praktisch rund um die Uhr versuchen, in das System einzudringen und bei lohnenswerten Zielen immer schwerere Geschütze auffahren, wird die Anwendung selbst nur vergleichsweise selten auf Sicherheitslücken getestet.

Aus diesem Grund muss die Sicherheit der Anwendung unbedingt mit der Deployment-Frequenz Schritt halten. Das bisherige Vorgehen, bei welchem kurz vor Produktivsetzung der Penetrationstester die Software einmal punktuell prüft, funktioniert damit nicht mehr. Stattdessen müssen Security-Aspekte auch in alle Aktivitäten innerhalb des Continuous Delivery mit integriert werden. Beginnend mit der Vision sollten schon erste konzeptionelle Überlegungen bezüglich der Sicherheit vorgenommen werden. Hier geht es eher um grundlegende Fragestellungen, wie Sicherheit und Datenschutz trotzdem mit einer entsprechenden Usability umgesetzt werden können. Dies geht dann, wie in Abb.2 mit Scrum als Vorgehensmodell dargestellt, über in das Refinement und die Priorisierung des Product Backlogs, die Entwicklung im Sprint bis hin zur Erstellung des fertigen sicheren Inkrements. Am Ende steht dann schließlich die automatisierte Produktivsetzung und Wartung/Monitoring durch den Betrieb.

Sicherheit von Anfang an

Bereits mit Entstehung der Produktvision und den ersten Anforderungen sollten Überlegungen hinsichtlich möglicher Sicherheitsrisiken und Angriffsszenarien vorgenommen werden. Als hilfreich hat sich hier das Threat-Modelling erwiesen. Hier wird auf Basis der vorhandenen Anwendungsarchitektur ein Angriffsmodell abgeleitet, welches u. a. durch Festlegung von Trust Boundaries zwischen den Komponenten hilft, potentielle Angriffspunkte und -typen zu identifizieren [1].

Aus den Diskussionen rund um das Threat-Modell ergeben sich dann entsprechende Anforderungen an die Sicherheit. Eine mögliche Kategorisierung von User Stories würde dann wie folgt aussehen:

  • User Stories für Security Features  (z. B. Authentifizierung und Rollenmodell)
  • AbUser Stories (s. u.)
  • User Stories mit sicherheitsrelevanten Akzeptanzkriterien
  • User Stories ohne jeglichen Security-Bezug

AbUser Stories (auch bekannt als "Evil User Stories" [2]) werden aus den fachlichen User Stories abgeleitet und beschreiben damit die verbundene gewünschte Funktionalität aus Sicht des Angreifers.

Dabei sollten analog wie bei fachlichen User Stories auch Personas verwendet werden, d. h. statt dem allgemeinen "Hacker" könnte z. B. ein Skript Kiddie, ein Firmen-Insider oder ein Wirtschaftsspion verwendet werden. In Abb.3 ist ein Beispiel für eine fachliche (Business) User Story mit einer abgeleiteten AbUser Story zu sehen. Durch die AbUser Stories können dann im weiteren Verlauf für die Entwicklung im Rahmen der Sprint-Planung entsprechende Tasks erstellt werden.

Sicherheit entsteht vor allem in der Entwicklung

Gerade in der Entwicklung ist Security ein wichtiger Bestandteil. Hier sollte jede Entwickler zumindest ein gewisses Maß an Basiswissen besitzen. Durch geeignete Standardarchitekturen und Secure Coding Design Patterns [3] können hier von Anfang an Sicherheitslöcher minimiert werden. Unterstützend sollten auch gerade für die Security nur erprobte Standardbibliotheken wie beispielsweise Spring Security [4] oder Apache Shiro [5] eingesetzt werden. Versäumnisse in der Entwicklung sind später durch Security-Tests nur mit erheblichem Aufwand korrigierbar, sofern sie überhaupt rechtzeitig entdeckt werden. Auch auf der Clientseite hat sich in den Frameworks hinsichtlich Security sehr viel zum Guten gewendet. So ist beispielsweise in AngularJS (1 und inzwischen auch in Version 2) bereits ein sehr guter Schutz gegen Cross-Site-Scripting und CSRF-Angriffe standardmäßig integriert und unsichere API-Funktionen sind entsprechend benannt und in der Dokumentation deutlich hervorgehoben.

In der Entwicklung hat sich eine Continuous Integration (Commit) Stage wie in Abb.4 bewährt. Neben der automatisierten statischen Code-Analyse (z. B. mit FindBugs Security [6]) und Prüfung von 3rd-Party-Bibliotheken auf bekannte Sicherheitslöcher, ist gerade das manuelle Security Code-Review durch einen zweiten Entwickler integraler Bestandteil (hier z. B. mit Gerrit [7]).

An die Commit Stage schließt sich dann die Akzeptanztest Stage an. Dort wird automatisiert über UI- und API-Tests die Fachlichkeit getestet. Dies umfasst auch fachliche Sicherheitsanforderungen wie die Authentifizierung und Autorisierung auf Basis eines Rollenmodells. Auch hier gibt es z. B. mit Spring Security [4] inzwischen eine umfassende Testunterstützung.

Die nächste Stufe in der Deployment Pipeline kümmert sich nun um die qualitativen Anteile und beinhaltet u. a. Last- und Performancetests. In dieser Stufe werden dazu nun auch dynamische Sicherheitstests integriert (Abb.5). Hierfür gibt es inzwischen mit OWASP Zap [8] ein sehr gutes Open Source-Werkzeug. Dieses lässt sich über eine REST-API z. B. mit bestehenden UI-Tests (hier mit Selenium [9] in Kombination mit WebTester [10])  verbinden, um auf diesen Szenarien ein aktives Scanning durchzuführen. Dies kann dann nach manueller Prüfung (ggf. "False Positives") als Fehler in die Entwicklung weitergegeben werden.

Betrieb: Mehr als nur Netzwerksicherheit

In vielen Unternehmen kümmert sich der Betrieb häufig nur um die Absicherung der Netzwerke durch entsprechende Netzwerk- und Webanwendungsfirewalls sowie die Transportsicherung durch SSL bzw. TLS. Gerade bzgl. SSL/TLS werden häufig Konfigurationsfehler gemacht (SSLv1 oder unsichere Cipher-Suites). Dabei kann auch dieses mit automatischen Prüfservices wie z. B. von den SSL Labs [11] verbessert werden.

Daneben wird meist das Betriebssystem regelmäßig mit Sicherheitsupdates versorgt. Leider lässt die Patchfrequenz nach, je höher man den Stack hinauf geht (s. Abb.6). Applikationsserver werden nur ungern mit neuesten Patchleveln versehen, da man anschließend alle Anwendungen erneut testen muss. Neben dem eigenen Anwendungscode wird auch häufig das Monitoring der 3rd-Party-Bibliotheken von laufenden Produktivanwendungen vergessen. Gerade hier ist eine enge Zusammenarbeit zwischen Entwicklung und Betrieb immens wichtig. Meldet der Betrieb eine erkannte Schwäche an die Entwicklung, dann sollte dort die betroffene Komponente schnellstmöglich aktualisiert werden und das neue Softwareartefakt durch den Betrieb zeitnah produktiv gesetzt werden.

In der Cloud geht man z. B. bei CloudFoundry dazu über, die Angriffsfläche für Anwendungen durch weitere Infrastrukturmaßnahmen drastisch zu minimieren (s. "Rotate, Repair, Repave" in [12]). Dazu gehört die kontinuierliche Rotation von Zugangsdaten für Services, wie z. B. Datenbanken sowie das regelmäßige Neuaufsetzen von Laufzeitcontainern auf Basis geprüfter und mit Patches versorgter Images (und das ohne Downtime). Somit hat der Angreifer – selbst wenn er erfolgreich Zugriff auf das System erlangt hat – nur noch ein sehr kurzes Zeitfenster um dies auszunutzen zu können.

Fazit

In diesem Artikel wurden wesentliche Aspekte der SecDevOps dargestellt. Damit wird statt der punktuellen Einzelprüfung der Security durch externe Penetrationstester eine kontinuierliche Integration des Securityaspekts in jeden Bereich von DevOps erreicht. Dies führt gerade bei Continuous Delivery zu entsprechend sicheren auslieferbaren Inkrementen. Einen guten externen Penetrationstester kann man dann stattdessen sinnvoller als Trainer/Coach für die Entwicklung oder für das Testen von Härtefällen einsetzen.

Autor

Andreas Falk

Andreas Falk hat über 20 Jahre Erfahrung in der Entwicklung von Unternehmensanwendungen im Java-Umfeld. Seit fünf Jahren ist er als Managing Consultant bei der NovaTec Consulting GmbH tätig.
>> Weiterlesen
botMessage_toctoc_comments_9210