Das Wissensportal für IT-Professionals. Entdecke die Tiefe und Breite unseres IT-Contents in exklusiven Themenchannels und Magazinmarken.

SIGS DATACOM GmbH

Lindlaustraße 2c, 53842 Troisdorf

Tel: +49 (0)2241/2341-100

kundenservice@sigs-datacom.de

„Secure By Design“ in Java

Die steigende Anzahl der mit dem Internet verbundenen Systeme und die ständig wachsende Bedrohungslandschaft haben zu einer – aus Sicherheitssicht – feindseligen Umgebung für Softwareprodukte geführt, die früher hinter Unternehmens-Firewalls geschützt waren. Diese neue Realität bedeutet, dass Sicherheit jeden Beteiligten am Software-Lebenszyklus betrifft. Um dieses Problem zu adressieren, haben wir eine Reihe grundlegender Prinzipien formuliert, die Teams als Leitfaden zur Verbesserung der Anwendungssicherheit verwenden können. Es gibt 10 Design-Prinzipien, die wir in diesem Artikel erläutern, und zwei von diesen machen wir im Kontext von Java greifbar.
Author Image
Vlad Calmic

Author

Author Image
Eoin Woods

Author


  • 29.03.2019
  • Lesezeit: 19 Minuten
  • 126 Views

Was können wir tun, damit Entwickler das Thema Sicherheit auf dieselbe Stufe wie funktionale Anforderungen stellen? Der Ausdruck der „OWASP Top 10“ ist nicht die Antwort. Die eigentliche Herausforderung ist, dass das Thema Sicherheit für viele Entwickler mit seiner eigenen Sprache und seinen eigenen Normen, speziellen Technologien und der inhärenten Komplexität im Entwicklungsalltag eine Herausforderung darstellt.

Um dieses Problem im Kern zu adressieren, haben wir eine Reihe grundlegender Prinzipien festgelegt, die unsere Teams als Leitfaden zur Verbesserung der Sicherheit ihrer Anwendungen verwenden können. Wir definieren ein Sicherheits-Design-Prinzip (kurz „Prinzip“) als eine deklarative Aussage, Designentscheidungen im Softwareentwicklungsprozess treffen zu können, hier mit dem Ziel, die Sicherheit eines Systems zu garantieren oder zu verbessern.

Wir haben 10 Prinzipien definiert, die wir im Rahmen unseres „Secure Software Development Lifecycles“ vermitteln (s. Kasten).

Die 10 Sicherheits-Design-Prinzipien

1 Weise nur so viele Zugriffsrechte wie nötig zu
Beschränke Zugriffsrechte auf ein Minimum, weil weitreichende Rechte einem Angreifer leichter bösartigen und unbeabsichtigten Zugriff einräumen können.

2 Trenne Verantwortlichkeiten eindeutig
Trenne und verteile Verantwortlichkeiten und Privilegien auf unterschiedliche Rollen, weil dies zu mehr Kontrolle sowie Abgrenzung des Handlungsspielraums führt.

3 Vertraue – aber nur mit Zurückhaltung und Umsicht
Vertraue keinen unbekannten Entitäten und definiere einen Prozess, Vertrauen zu etablieren, weil viele Sicherheitsprobleme dadurch entstehen, dass bösartige Dritte sich in einem als sicher angenommen Kontext etablieren.

4 Setze die einfachste Lösung um
Vermeide unnötige Features, implizites Verhalten und komplexe Fehlerzustände, weil ein einfaches System auch hinsichtlich der Sicherheit besser zu analysieren ist.

5 Überwache sensible, sicherheitskritische Ereignisse
Zeichne alle sicherheitskritischen Ereignisse unveränderbar auf, weil wir die Vergangenheit rekonstruieren können, es uns Kontrolle
gibt und eine Form von Abschreckung darstellt.

6 Nutze sichere Standardeinstellungen und „Fail Securely!“
Gib sichere Default-Einstellungen vor oder erzwinge das Setzen von sicheren Einstellungen und definiere mögliche Fehlerszenarien, weil schwache Voreinstellungen (Passwörter, Ports) zu ungewollten „Offenen Türen“ führen und weil die inkorrekte Abarbeitung von Fehlerszenarien (Neustarts, Ausnahmebehandlungen) unbeabsichtigt zu unsicheren Systemen führen kann.

7 Verschleierung ist keine Sicherheit
Nimm an, ein Angreifer hat das perfekte Wissen – dann hilft keine Verschleierung, weil es grundsätzlich schwer ist, Dinge zu verstecken: Wenn sie auch nicht absichtlich entdeckt werden, so ist es oft nur eine Frage der Zeit, wann es zufällig geschieht.

8 Verteidigung in der Tiefe – jede Ebene des Systems absichern
Verlass dich nicht auf eine einzelne Sicherheitsebene, benutze unterschiedliche Mechanismen und Ansätze und verhindere, dass Fehler sich ausbreiten, um die Auswirkungen von Angriffen, vorsätzlich oder unabsichtlich, einzugrenzen.

9 Entwickle Sicherheitslösungen nicht selbst
Benutze Komponenten, Algorithmen und Werkzeuge im Kontext „Sicherheit“, die sich am Markt bewährt haben, weil Sicherheitstechnologie ein komplexes, schwieriges Thema ist und das Schadenspotenzial (und damit der Gewinn für andere) hoch ist.

10 Verbessere das schwächste Glied der Sicherheitskette
Identifiziere das schwächste Glied in der Kette durch eine Bedrohungsanalyse und verbessere es, weil das schwächste Glied der erste Angriffspunkt ist. Ein Verständnis der Bedrohung ist wichtiger als die eingesetzte Sicherheitstechnologie.

Weitere Information zu den Sicherheits-Prinzipien finden sich unter [Woo16].


Diese Prinzipien sind zunächst unabhängig von der eingesetzten Technologie. Durch die Einhaltung dieser Prinzipien können wir unabhängig vom Technologie-Stack die Sicherheit von Anwendungen selbst und deren Anwendungsumgebung wesentlich verbessern.

Während unsere Prinzipien von einer breiten Anwendbarkeit profitieren, besteht die praktische Herausforderung für viele Teams darin, diese recht allgemeinen Prinzipien in ihrem spezifischen technischen und organisatorischen Kontext zu interpretieren. Wir zeigen die konkrete Anwendung zweier dieser Prinzipien aus der Sicht eines Java-Teams:

  • Verwendung von X.509-Zertifikaten zur Implementierung einer gegenseitigen Authentifizierung (Prinzip 3: „Vertraue – aber nur mit Zurückhaltung und Umsicht“); und
  • Nutzung einer Protokollierung, um sicherheitsrelevante Ereig-nisse sicherheitsbewusst zu erfassen (Prinzip 5: „Überwache sensible, sicherheitskritische Ereignisse“).

Für diese beiden Prinzipien zeigen wir eine mögliche Umsetzung unter Nutzung des Java-Technologie-Stacks. Die vollständigen Quelldateien der verwendeten Beispiele finden Sie unter [GitH].

Prinzip 3: Vertraue – aber nur mit Zurückhaltung und Umsicht

Das Konzept des „Vertrauens“ wird in der Informatik relativ breit verwendet. Es reicht vom Vertrauen gegenüber einer Informationsquelle, Vertrauen gegenüber einem Entwickler, zuverlässige Software zu erstellen, oder Vertrauen in einen Dienst, unsere persönlichen Daten zu schützen. Im Kontext dieses Beispiels verwenden wir Vertrauen als „das sichere Kommunizieren mit und das Akzeptieren von Daten aus Quellen, für die wir die Identität des anderen Teilnehmers und die Integrität der Daten überprüfen konnten“.

Häufig verbindet man diese Forderung nach Vertrauen mit der Nutzung externer, das heißt außerhalb seiner eigenen, kontrollierten Infrastruktur angebotenen, Dienste. Mit Hinblick auf Prinzip 8 führt eine einheitliche Behandlung von externen und internen Diensten jedoch dazu, Bedrohungen in der Tiefe, hier also innerhalb der als sicher angenommenen, internen Infrastruktur, zu reduzieren. Außerdem ist die Aufteilung „intern – extern“ nicht mehr so deutlich wie noch vor einigen Jahren und kann sich durch eingeführte Cloud-Dienste leicht verschieben.

Gegenseitiges Vertrauensmodell mit vertrauenswürdiger Zertifizierungsstelle
Wir zeigen die Umsetzung von Prinzip 3 am Beispiel einer internen Client-Server-Kommunikation. Der erste Schritt ist die gegenseitige Authentifizierung, das heißt, wir stellen sicher, dass sich sowohl der Client als auch der Server gegenseitig eine kryptografisch überprüfbare Identität präsentieren, und dass der jeweilige Empfänger diese überprüfen kann. Das hört sich komplex an? Das Java-Ökosystem bietet jedoch Tools und Bibliotheken, sodass unter Einhaltung von Prinzip 9 eine Umsetzung dieses Verfahrens auch für interne 9 Verbindungen überschaubar realisiert werden kann.

Es gibt zwei Ansätze, um vertrauenswürdige Beziehungen aufzubauen: Entweder tauschen beiden Parteien (hier Client und Server) „Geheimnisse“ zur Identifikation und Verschlüsselung direkt miteinander aus oder beide Parteien verlassen sich auf die Zusicherung eines Dritten, diese Identifikation zu gewährleisten.

Bei einer großen Anzahl von Vertrauensbeziehungen skaliert die direkte Überprüfung nicht. Wir werden daher in diesem Beispiel ein 3-Parteien-Vertrauensmodell mit einem zentralen, vertrauenswürdigen Dritten etablieren. Die Zusicherung des Vertrauens erfolgt durch kryptografische Zertifikate und eine zentrale Zertifizierungsstelle (CA = Certificate Authority). Die Rolle der Zertifizierungsstelle besteht darin, die Parteien zu identifizieren und digitale Zertifikate für die öffentlichen Schlüssel der Parteien auszustellen, die mit dem privaten Schlüssel der Zertifizierungsstelle signiert sind.

Durch den öffentlichen Schlüssel der Zertifizierungsstelle lässt sich so überprüfen, ob das von einem Kommunikationspartner bereitgestellte digitale Zertifikat von der Zertifizierungsstelle signiert wurde und somit echt ist. Hierdurch sichern wir den Schutz der Vertraulichkeit, die Authentizität und die Integrität in der Kommunikation zu.

Eine Zertifizierungsstelle kann intern etabliert werden, oder es kann sich um eine öffentliche Zertifizierungsstelle wie „Let's Encrypt“ handeln. Für die Absicherung einer rein internen Kommunikation können wir eine eigene, lokale Zertifizierungsstelle einrichten. Die Verwendung eines öffentlichen Zertifizierungsstellenmodells ist fast immer dann notwendig, wenn Sie mit Parteien außerhalb Ihrer Umgebung kommunizieren müssen oder wenn Sie die Verwaltungsaktivitäten, wie das Sperren von Zertifikaten und die Schlüsselrotation, scheuen.

Wir etablieren die sichere Kommunikation auf der Basis von TLS [IETF] durch das SSL-Handshake-Protokoll (s. Abb. 1):

Abb. 1: Gegenseitige Authentifizierung über TLS

  • (1) Der Client fordert eine HTTP-Verbindung mit dem Server an.
  • (2) Der Server gibt sein Zertifikat zur Überprüfung an den Client zurück und fordert das Client-Zertifikat an. Das Server-Zertifikat wurde durch eine Zertifikatsignierungsanforderung (CSR = Certificate Signing Request) von der Zertifizierungsstelle signiert.
  • (3) Der Client überprüft erfolgreich das Zertifikat, unter Nutzung der Signatur der vertrauenswürdigen Zertifizierungsstelle auf Korrektheit und Gültigkeit.
  • (4) Der Client sendet sein Zertifikat zurück, zusammen mit dem Pre-Master-Schlüssel, der für die Generierung eines symmetrischen Sitzungsschlüssels benutzt wird. Das Client-Zertifikat wurde auch bereits von der Zertifizierungsstelle signiert.
  • (5) Der Server führt eine Zertifikatsüberprüfung des Clients, ähnlich zu Schritt 3, erfolgreich durch.
  • (6) Der Server generiert den Sitzungsschlüssel und wechselt zur symmetrischen Verschlüsselung. Alle weiteren Anfragen und Antworten werden über einen sicheren Kanal mit dem Sitzungsschlüssel auf Basis symmetrischer Verschlüsselung abgewickelt.

Wir wollen nun dieses gegenseitige Vertrauensmodell unter Verwendung einer vertrauenswürdigen Zertifizierungsstelle in Java umsetzen. Für das Beispiel verwenden wir eine eigene Zertifizierungsstelle „Java4Spektrum CA“. Wir verwenden deren privaten Schlüssel zum Signieren der Zertifikate für den Client und den Server. Diese beiden Parteien werden wiederum den öffentlichen Schlüssel der „Java4Spektrum CA“ nutzen, um die jeweiligen Client- und Serverzertifikaten zu validieren.

Diese kryptografischen Schlüssel und Zertifikate müssen wir sicher ablegen. Wir verwenden das Standard-Schlüsselverwaltungssystem Java Keystore (JKS), um zwei Schlüsselspeicher zu erstellen, einen Keystore und einen Truststore. Im Keystore werden die privaten Schlüssel verwaltet, die zum Signieren unserer und zum Entschlüsseln der an uns gerichteten Nachrichten genutzt werden. Der Truststore verwaltet alle öffentlichen Schlüssel, denen wir vertrauen und die wir zur Verifikation der Identität und zum Verschlüsseln der Nachrichten an diese Parteien nutzen. Wir vertrauen nur Verbindungen mit Parteien, deren Schlüssel in unserem Truststore enthalten sind.

Um als Java-Entwickler eine eigene Zertifizierungsstelle und ein Paar signierter Identitäten für unseren Client und Server zu erstellen, verwenden wir das Dienstprogramm keytool [Ora]:

  • Wir generieren ein java4spektrum_ca-Schlüsselpaar und ein X.509-Zertifikat (X.509 ist ein Standard für die Erstellung digitaler Zertifikate [Wiki]) für die Zertifizierungsstelle „Java4- Spektrum-CA“. Damit werden wir unsere X.509-Zertifikate für den Client und den Server signieren. Wir importieren den privaten Schlüssel und das Zertifikat in den Keystore der CA.
  • Wir generieren ein server („javaspektrum.com“)-Schlüsselpaar und ein X.509-Zertifikat, signieren es mit dem privaten Schlüssel der Java4Spektrum-Zertifizierungsstelle und importieren den privaten Schlüssel und das Zertifikat in den Keystore des Servers.
  • Analog generieren wir ein client („java_spektrum“)-Schlüsselpaar und ein X.509-Zertifikat, signieren es mit dem privaten Schlüssel der Java4Spektrum-CA und importieren den privaten Schlüssel und das Zertifikat in den Keystore des Clients. - Wir importieren das CA-Zertifikat in die Truststores von Client und Server.
  • Anschließend bleibt nur noch der Import der jeweiligen Zertifikate java_spektrum.crt beziehungsweise java4spektrum.com in den jeweiligen Truststore von Server und Client.

Server und Client
Sobald wir unsere Zertifizierungsstelle und die Zertifikate erstellt und wie oben beschrieben verwaltet haben, können wir den Server und den Client implementieren. Hierbei müssen wir unter Nutzung der kryptografischen Identitäten die folgenden Vertrauensregeln gewährleisten:

  • Der Server akzeptiert Verbindungen von einem Client, der sich mit einem von der Java4Spektrum-CA signierten X.509-Zertifikat als „java_spektrum“ identifiziert.
  • Der Client kommuniziert nur mit einem Server, der sich mit ei-nem von der Java4Spektrum-CA signierten X.509-Zertifikat als „java4spektrum.com“ identifiziert.

Wir nutzen das Java-Framework SpringBoot [Spria], wobei Spring Security (weitere Informationen unter [Sprib]) verwendet wird, um die Sicherheits- und Vertrauensaspekte der Anwendung zu implementieren. Wir beschränken uns in der folgenden Beschreibung auf die Umsetzung der obigen Schritte in Java.

Um die HTTP Security in Spring zu aktivieren, müssen wir den WebSecurityConfigurerAdapter erweitern, um eine Default-Konfiguration zu definieren, die von der Methode configure (HttpSecurity http) zurückgegeben wird, um die in Schritt 2 in Abbildung 1 erforderliche TLS-Kommunikation zu aktivieren. Diese Konfigurationsklasse aktiviert X.509 für http, was dazu führt, dass Spring Security die Properties des Abschnitts server.ssl.* verwendet, die wir in der Spring-Konfigurationsdatei application.properties hinterlegt haben, um die Keystores zu finden, die für den Zugriff auf die privaten Schlüssel erforderlich sind. Um die Client-Authentifizierung in Schritt 5 in Abbildung 1 zu erzwingen, müssen wir auch die Property server.ssl.client-auth=need in der Konfigurationsdatei angeben.

Ein Beispiel für unsere von WebSecurityConfigurerAdapter abgeleiteten Klasse zum Aktivieren einer sicheren http-Verbindung zeigen wir in Listing 1.

Listing 1: WebSecurityConfig-Klasse

Nachdem wir jetzt einen Server-Dienst mit TLS- und Client-Authentifizierung anbieten, benötigen wir den Client, der diesen nutzen kann. Wir können den Client als separate Anwendung mit eigenem Truststore und Keystore implementieren. In diesem einfachen Beispiel entscheiden wir uns, den Client als automatisierten Test auf der Basis von RestTemplate zu realisieren, wobei der Truststore und der Keystore gemeinsam mit dem Server verwendet werden. Um einen gültigen SSL-Handshake auszuführen, muss der Client in der Lage sein, das vom Server in Schritt 2 in Abbildung 1 präsentierte Zertifikat zu überprüfen und zusätzlich sein eigenes Zertifikat zur Authentifizierung vorzulegen. Listing 2 zeigt ein Beispiel für den Test-Client. Da sich unser Client als „java_spektrum“ identifizieren muss, um vom Server autorisiert zu werden, verwenden wir die PrivateKeyStrategy in unserem Code, um den entsprechenden Schlüssel aus dem Keystore abzurufen.

Listing 2: Testfall für den Client-Request

Bei korrekter Implementierung und korrektem Schlüsselmanagement präsentiert der Client dem Server ein gültiges Zertifikat, damit der Server die Identität des Clients überprüfen kann. Dadurch wird eine gegenseitige TLS-Authentifizierung durchgeführt und eine sichere Kommunikation zwischen den Parteien etabliert, was in den Testergebnissen in Abbildung 2 zu sehen ist.

Abb. 2: Erfolgreiche Testausführung

Prinzip 5: Überwache sensible, sicherheitskritische Ereignisse

Beim Betrieb unserer Anwendungen können wir nur auf sicherheitskritische Probleme reagieren, wenn wir Kenntnis von sicherheitsrelevanten Ereignissen im Ablauf der Anwendung haben. Dies kann jeder Code-Block sein, der möglicherweise die Integrität, Verfügbarkeit oder Vertraulichkeit einer Anwendung kompromittiert. Der Fokus einer Log-Strategie sollte daher auch gerade die Protokollierung von sicherheitsrelevanten Ereignissen schwerpunktmäßig einbeziehen.

Das betrifft insbesondere Ausnahmebehandlungen oder Systemrandbedingungen (Neustart, Verbindungsverlust, vgl. Prinzip 6), die nicht häufig auftreten und leider auch nicht intensiv getestet werden. Gerade hier sollte eine Log-Strategie ansetzen. Darüber hinaus müssen wir jedoch sicherstellen, dass unser Protokollierung das System nicht kompromittiert. Für die Log-Aufzeichnung und das Log-Management selbst können wir uns auf etablierte Frameworks verlassen.

Protokollierung sicherheitsrelevanter Ereignisse
Der erste Schritt besteht darin, die Log-Niveaus und die Bedingungen, unter denen sie verwendet werden, eindeutig und anwendungsübergreifend festzulegen. Diese Vorgehensweise garantiert, dass wichtige Ereignisse protokolliert und nicht im „Log-Spam“ übersehen werden. Ein erfolgreicher Zugriff auf eine öffentliche Programmierschnittstelle sollte mit niedriger Priorität, ein wiederholt erfolgloser Authentifizierungsversuch dagegen mit höherer Priorität protokolliert werden. Das Log-Management muss dann sicherstellen, dass diese Ereignisse in einem Standardformat zentral gesammelt und korreliert abgelegt werden. So können diese Ereignisse im Kontext überwacht und ausgewertet werden.

In einer Java-Anwendung können wir auf bewährte Log-Frameworks wie Log4j oder Logback zurückgreifen. Vordefinierte Log-Niveaus (z. B. DEBUG, INFO und ERROR) helfen uns, Events zu klassifizieren und strukturiert zu protokollieren. Für unser einfaches Beispiel nutzen wir „log4j2“ (Version 2.x des Log4j-Frameworks [Apac]) und konfigurieren die Protokollierung auf die Konsole sowie in eine Datei mit größenabhängiger Log-Rotation, um einen sicherheitskritischen Überlauf des Dateisystems zu verhindern.

Die Log-Strategie für Log4j kann entweder mithilfe von Konfigurationsdateien oder programmatisch durch Konfigurationsklassen definiert werden. Das Log-Format und die Log-Ziele werden durch Appender von Log4j definiert. Für viele Log-Ziele (Datei, HTTP, JMS usw.) stehen bereits Appender zur Verfügung. Durch diesen deklarativen Ansatz sowie die umfangreiche Basisfunktionalität können wir unsere Anwendung weitgehend unabhängig von unserer Log-Management-Strategie entwickeln.

Listing 3 zeigt unseren Service, der jeweils ein Ereignis vom Niveau INFO, ERROR und DEBUG aufzeichnet. Die oben beschriebene Log-Konfiguration ist in einer XML-Datei log4j2.xml im classpath hinterlegt. Bei Ausführung des obigen Service erhalten wir eine Ausgabe wie in Abbildung 3.

Listing 3: Service-Implementierung mit Protokollierung

Abb. 3: Ausgabe auf der Konsole

Filterung der Protokollinformationen
Wir haben somit eine einfache, konfigurierbare Log-Strategie umgesetzt. Was passiert aber, wenn der Entwickler sensible persönliche Daten, wie E-Mail-Adresse oder Geschlecht, oder sicherheitskritische Daten, wie eine Kreditkartennummer, durch Protokollierung aufzeichnet? Dies wird dann zu einem Problem, wenn die Logs anderen Standards als die operativen Daten unterliegen, wie Verschlüsselung oder andere Zugriffsrechte (vgl. Prinzip 1).

In unserem Beispiel zeichnen wir eine Kreditkartennummer (CCNUM oder PAN) auf. Ein ganzer Industriestandard PCI DSS [PCI] beschäftigt sich mit der Verwaltung dieser Karteninhaberdaten und definiert auch akzeptable Formate für die Aufzeichnung von Kreditkartennummern. Die Ausgabe in Klartext ist in diesem Kontext kein akzeptables Format.

Wie können wir dieses Problem lösen? Mit Log4j ist es möglich, „Konverter-Plug-ins“ zu erstellen, um die Daten in der Nachricht zu verändern. Es gibt bereits eine große Anzahl von definierten Konvertern in der Log4j2-Bibliothek. Für unsere Zwecke erweitern wir den LogEventPatternConverter (s. Listing 4), um das Format der Kreditkartennummer über einen regulären Ausdruck zu erkennen und die Zahlen durch Sternchen zu verschleiern. Eine Teilmaskierung, wie sie der PCI DSS-Standard erlaubt, wäre hier auch möglich.

Listing 4: Log-Message-Konverter

Da unsere Plug-in-Klasse LogEventPatternConverter erweitert, mit der Log4j2-Annotation @Plugin versehen und im classpath verfügbar gemacht ist, lädt Log4j das Plug-in zur Laufzeit automatisch und wendet es an. Dadurch wird die Ausgabe der Kreditkartennummer (CCNUM), wie in Abbildung 4 dargestellt, durch Sternchen maskiert.

Abb. 4: Ausgabe auf der Konsole mit Maskierung

Wir haben beispielhaft gezeigt, wie man das Prinzip 5 konkret anwenden kann. Wir nutzen ein Standard-Framework Log4j (s. auch Prinzip 9), um strukturiert Ereignisse mit einer vorher festgelegten Log-Strategie aufzuzeichnen und zur Verfügung zu stellen. Wir stellen durch ein organisatorisches Verfahren wie Peer-Review in Verbindung mit domainspezifischem Training (Zahlungsdienstleistungen) sicher, dass Ereignisse im Rahmen unserer Log-Strategie keine sicherheitsrelevanten Daten preisgeben. Wir haben dies anhand eines Filters gezeigt, der sensitive Kreditkartendaten maskiert. Darüber hinaus sind natürlich andere Ansätze möglich, wie die Log-Verschlüsselung, die auch vom Framework Log4j angeboten wird.

Sicherheits-Prinzipien, ... ja aber ...

Der Einsatz von Architekturprinzipien erlaubt es uns, Aspekte einer Architektur, die wir bei ihrer Erstellung und Wartung zusichern möchten, knapp und prägnant zu formulieren. Die hier vorgestellten 10 Sicherheits-Prinzipien sind Architekturprinzipien, die Architekten und Entwicklern helfen, sicherheitsrelevante Fehler zu vermeiden und durch die Sicherheit des Produkts relativ zu verbessern. Wir hoffen, wir konnten durch die beiden konkreten Beispiele zeigen, wie man ein Bewusstsein für das Thema „Sicherheit“ entwickeln kann, ohne präskriptiv zu sein und dadurch das Interesse und die Kreativität unserer Entwickler zum Thema Sicherheit zu nutzen.

Doch sind wir jetzt nicht wieder am Ausgangspunkt angekommen? Drucken wir unsere 10 Sicherheits-Prinzipien aus und hängen sie in den Büros unserer Entwickler auf, wie wir es nicht mit den „OWASP Top 10“ hätten tun sollen? Wie nutzen wir diese Prinzipien? Wir haben auf der Basis des „Train-the-Trainer“-Modells eine Gruppe von „Security Champions“ aufgebaut, die für die Wahrnehmung des Themas Sicherheit und dieser Prinzipien verantwortlich ist. Sie hilft den Teams bei der Ausgestaltung im jeweiligen Technologie-Stack. Mit unserem „S-SDLC“ (Secure Software Development Lifecycle) haben wir eine Variante unseres Entwicklungsprozesses etabliert, die über die 10 Sicherheits-Prinzipien hinaus schwerpunktmäßig sicherheitsrelevante Verfahren und Werkzeuge, wie Bedrohungsmodellierung, Pen-Tests usw., integriert. Dadurch wird Sicherheit Teil des Entwicklungsprozesses. Man kann ein Produkt eventuell kurz vor der Auslieferung um eine funktionale Anforderung erweitern, aber nicht um Qualitätsattribute wie Sicherheit.

Literatur und Links

[Apac] Apache Logging Services, Apache Log4j 2, https://logging.apache.org/log4j/2.x/

[GitH] Code-Beispiele zum Text, https://github.com/endava/javaspektrum-securebydesign.git

[IETF] Internet Engineering Task Force (IETF) RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3, https://tools.ietf.org/html/rfc8446

[Ora] Oracle, Java Platform, Standard Edition Tools Reference, keytool, https://docs.oracle.com/javase/9/tools/keytool.htm

[PCI] PCI Security Standards Council, Datensicherheitsstandard, https://de.pcisecuritystandards.org/minisite/env2/

[Spria] Spring, Spring Boot Reference Documentation, https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/ reference/html/

[Sprib] Spring, Spring Security, https://spring.io/projects/spring-security

[Wiki] Wikipedia, X.509, https://de.wikipedia.org/wiki/X.509

[Woo16] E. Woods, Secure by Design – Security Design Principles for the Rest of Us, GOTO London, 2016, https://de.slideshare.net/EoinWoods1/secure-by-designsecurity-design-principles-for-the-rest-of-us

. . .

Author Image

Vlad Calmic

Author
Zu Inhalten
Vlad Calmic ist Vice President, Security & Crypto bei Endava. Er hat mehr als 20 Jahre praktische Erfahrung im Design und in der Erstellung komplexer IT-Lösungen im E-Commerce und Finanzdienstleistungssektor, zuletzt als Lösungsarchitekt in großen Kundenprojekten. Er ist für alle Fragen zum Thema sichere Software global verantwortlich und hat den „Secure SDLC“ bei Endava maßgeblich mitentwickelt.
Author Image

Eoin Woods

Author
Zu Inhalten
Eoin Woods ist CTO von Endava. Er leitet die technische Strategie des Unternehmens und ist für die technologische Ausrichtung verantwortlich. Er ist Autor vieler Publikationen, darunter Mitautor von „Software Systems Architecture“. 2018 erhielt er den „Linda Northrop Award for Software Architecture“ des Software Engineering Institutes der CMU. Er ist regelmäßiger Sprecher auf Konferenzen. Seine Schwerpunkte liegen im Bereich Softwarearchitektur, verteilte Systeme und Computer-Sicherheit.
Author Image
Zu Inhalten
Thomas Behrens ist technischer Delivery Manager bei Endava, Deutschland. In dieser Rolle ist er für die Sicherung der Qualität der entwickelten Software verantwortlich. Nach vielen Jahren in der Softwareentwicklung in sicherheitskritischen Bereichen im Umfeld Embedded Systems und Investmentbanking liegen seine Interessen jetzt in der Zusicherung funktionaler Anforderungen sowie Qualitätsattributen in verteilten, agilen Entwicklungsprozessen.

Artikel teilen

Nächster Artikel
Rethinking Pizza Factory