Zum Inhalt springen

Suchen...

Secure by Design

Sicherheit landet oft als letzter Punkt auf der Agenda – und genau das ist das Problem. Was Defense in Depth, Bedrohungsmodellierung und sichere Defaults wirklich bedeuten.

9 Min. Lesezeit
Cover für Secure by Design

Security by Design bedeutet, Sicherheit von Beginn der Softwareentwicklung an als gleichwertige Anforderung zu behandeln, statt sie am Projektende nachzurüsten. Konkret heißt das: mehrschichtige Verteidigung aufbauen, keine eigene Sicherheitstechnologie erfinden, sichere Standardeinstellungen erzwingen und Bedrohungsmodellierung fest in den Entwicklungsprozess einbetten.

Das Wichtigste in Kürze

  • Sicherheitsmechanismen einzeln einzusetzen reicht nicht: Wer sich auf eine einzige Schicht verlässt, gibt Angreifern nach dem ersten Einbruch freie Bahn durch das gesamte System.
  • Eigene Verschlüsselungs- oder Authentifizierungslösungen zu bauen ist ein typischer Fehler, denn selbst professionell entwickelte Sicherheitstechnologie hat Schwachstellen, die erst intensive Tests aufdecken.
  • Bedrohungsmodellierung muss nicht kompliziert sein: Es genügt, das Team zusammenzurufen und strukturiert zu fragen, was wertvoll ist, wer es haben will und wie ein Angriff aussehen könnte.
  • Tester haben im Sicherheitsprozess eine natürliche Rolle, weil sie systematisch fragen, was schiefgehen kann, und Schwachstellen sichtbar machen, bevor sie zur Katastrophe werden.

Sicherheit gehört an den Anfang, nicht ans Ende

Sicherheit als nachgelagerte Aufgabe zu behandeln, ist der häufigste Fehler in der Softwareentwicklung. Wer erst in den letzten zehn Prozent eines Projekts über Sicherheit nachdenkt, bekommt auch nur zehn Prozent Sicherheit.

Sicherheit gehört zu derselben Klasse von Eigenschaften wie Leistung, Ausfallsicherheit und Verfügbarkeit. Diese Aspekte sind in der Theorie allen klar, in der Praxis verschiebt man sie auf später, und später kommt nie. Jeder Tester kann bestätigen, dass dieser Plan nicht aufgeht.

Das Interesse an Sicherheit hat sich verändert. Eoin Woods, der vor etwa zehn Jahren mit Vorträgen zum Thema begann, erinnert sich an Räume mit fünf Zuhörern, durchweg Sicherheitsleute. Heute sitzen dort Menschen aus der Softwareentwicklung, die sich tatsächlich für das Thema interessieren. Diese Verschiebung ist die Basis dafür, Sicherheit überhaupt früh verankern zu können.

Warum Sicherheitsexperten und Entwicklungsteams aneinander vorbeireden

Der Bruch entsteht, weil beide Seiten unterschiedliche Sprachen sprechen. Softwareentwickler kennen Sicherheit oft nur abstrakt: Authentifizierung, Autorisierung, Auditierung als Begriffe, ohne konkrete Umsetzung.

Sicherheitsingenieure sind kluge Spezialisten, die genau das den ganzen Tag tun. Sie kommen aber häufig aus dem Infrastrukturbereich und wissen wenig über moderne Softwarebereitstellung. Treffen beide aufeinander, überfordert der Experte das Team schnell mit kompliziertem Material, das angeblich sofort umgesetzt werden muss, sonst drohe die Katastrophe.

Diese Alles-oder-nichts-Logik führt in die Irre. In der Sicherheit ist nichts absolut. Jede Entscheidung ist eine Abwägung, und die Aufgabe besteht darin, das richtige Gleichgewicht zu finden, nicht den maximalen Aufwand zu fordern.

Designprinzipien machen Sicherheit greifbar

Eine überschaubare Menge von Designprinzipien hilft Teams mehr als eine vollständige Sammlung. Gute Prinzipien sind leicht zu verstehen, leicht zu merken und bringen Entwickler dazu, früher über Sicherheit nachzudenken.

Eoin Woods stieß bei seiner Suche auf Sammlungen, die von acht oder neun Punkten bis zu mehreren Hundert reichten. Sehr große Sammlungen sind alle inhaltlich korrekt, aber unbrauchbar: Niemand arbeitet im Alltag mit Hunderten von Regeln. Der praktikable Weg liegt in der Mitte, mit einem Set, das einen Großteil dessen abdeckt, was Softwareteams wissen müssen.

Ich bin fest davon überzeugt, dass Designprinzipien dabei helfen, Designentscheidungen zu treffen. Eoin Woods

Mehrschichtige Verteidigung

Verlasse dich nie auf einen einzigen Sicherheitsmechanismus. Angreifer sind heute raffiniert genug, um einen einzelnen Mechanismus auszuhebeln, sei es eine Verschlüsselung oder ein Authentifizierungssystem.

Fast jeder Mechanismus hat Schwachstellen, oder es passieren Fehler bei der Anwendung. Mehrere unabhängige Schichten sorgen dafür, dass ein Angreifer nicht das ganze System besitzt, sobald er eine Hürde überwunden hat. In stark gesicherten Systemen, etwa bei staatlichen Stellen, hat jede Ebene eigene Mechanismen. Wer eine Schicht durchbricht, steht vor der nächsten. Das Ziel ist, einen Einbruch teuer zu machen.

Erfinde keine eigene Sicherheitstechnologie

Eigene Sicherheitstechnologie zu bauen ist viel schwerer, als es aussieht. Viele weniger erfahrene Entwickler unterschätzen den Aufwand: Sie wollen einen eigenen Passwort-Tresor schreiben oder fragen sich, wie schwer Verschlüsselung schon sein kann.

Das Gleiche gilt für die Integration in Systeme wie OAuth zur Authentifizierung und Autorisierung. Such dir eine Bibliothek, die das übernimmt. Selbst von Profis gebaute Sicherheitstechnologie hat Schwächen. Erfahrene Sicherheitstester nehmen jedes neue Produkt sofort auseinander und finden immer etwas. Die Wahrscheinlichkeit, dass eine selbstgebaute Lösung sauberer ist, liegt nahe null. Dazu kommt der Mehraufwand, den ein Projekt nicht braucht.

Bei der Wahl zwischen Open Source und kommerziellen Bibliotheken gibt es keinen pauschalen Sieger. Open Source bietet Transparenz und viele unabhängige Forscher, die den Code prüfen. In bestimmten Märkten kann eine Closed-Source-Lösung die bessere Wahl sein, wenn du den Anbietern die richtigen Fragen stellst.

Sei vorsichtig, aber vertrauensvoll

Akzeptiere keine unautorisierten oder nicht authentifizierten Netzwerkverbindungen, und pass auf, was du in dein System hineinlässt. Das betrifft Verbindungen ebenso wie Daten und die Bausteine, aus denen du das System zusammensetzt.

Es gibt zahlreiche Sicherheitslücken, bei denen bösartige Daten eingeschleust werden. Genauso wichtig ist die Frage, woraus du baust: Open-Source-Komponenten, aber auch kommerzielle Bibliotheken und Plattformen. Wie sicher sind diese, und wie würdest du eine Schwachstelle überhaupt bemerken?

Sichere Standardeinstellungen und der Umgang mit Fehlern

Software muss mit sicheren Standardeinstellungen ausgeliefert werden und im Fehlerfall in einen sicheren Zustand fallen. Standardpasswörter sind ein altes, aber zählebiges Problem.

Frühere Oracle-Systeme kamen mit einflussreichen Konten und festen Standardpasswörtern. Das Klischee lautete: Wer Oracle hat, hat einen Scott-Tiger-Account, also einen Benutzer “Scott” mit dem Passwort “Tiger”. Über diesen Demo-Benutzer ließ sich praktisch jedes System öffnen. Das Muster lebt weiter: Open-Source-Software, Cloud-Demos und sogar Netzwerkhardware der Enterprise-Klasse werden mit voreingestellten Benutzern und Passwörtern ausgeliefert, weil es bequem ist. Bequem und unsicher zugleich.

Der zweite Teil betrifft das Verhalten im Fehlerfall. Ein Datenbankanbieter, bekannt für Leistung und Verfügbarkeit, baute auf Kundenwunsch einen manipulationssicheren Prüfpfad ein. Die Ingenieure deaktivierten die Protokollierung jedoch, sobald der Speicher voll war oder eine Fehlfunktion zeigte, und verarbeiteten einfach weiter. Erst ein Beta-Kunde stoppte das: Der Prüfpfad war voll, die Verarbeitung lief ohne Audit weiter. Aus Sicht von Durchsatz und Verfügbarkeit erschien das Audit verzichtbar. Es war es nicht.

Ähnliche Fragen stellen sich bei nachrichtengesteuerten Systemen nach einem komplexen Ausfall. Beim Neustart: Wartet das System, bis alle Sicherheitsdienste verfügbar sind und durchgängige Authentifizierung gewährleistet ist? Oder beginnt es, nach Gelegenheit zu verarbeiten? Die zweite Variante öffnet ein Fenster, das niemand öffnen wollte.

Typisierte Schnittstellen gegen den kleinsten gemeinsamen Nenner

Der einfachste Weg, Daten zwischen Systemen zu bewegen, ist auch der gefährlichste: alles in eine Zeichenkette umwandeln. Diese Methode lehnt nichts ab und ist deshalb verlockend.

Genau darin liegt die Lücke. Angreifer schicken fehlerhafte Zeichenketten, die der String-Prozessor durchwinkt. Erst bei der Übersetzung in ein anderes Format entsteht der Schaden, von einem Denial-of-Service bis zu Exploits für Fernbefehle. Wer große Mengen unformatierter Daten einliest, ohne sie sorgfältig zu prüfen, schafft sich ein erhebliches Risiko.

Stark typisierte Schnittstellen sind die sicherere Antwort, haben aber einen Preis. Sie sind aufwändiger zu entwickeln, weniger flexibel und schwerer weiterzuentwickeln. Diese Abwägung gehört bewusst getroffen, gerade in Landschaften mit vielen verbundenen Anwendungen und APIs, in denen sich ein eingeschleustes Problem sonst durch alle Systeme zieht.

Wie Sicherheit in den Entwicklungsprozess kommt

Designprinzipien richten sich an die Personen, die entwerfen. Die größere Frage ist, wie das ganze Team gemeinsam sichere Software ausliefert. Die Antwort heißt: ein sicherer Software-Lieferzyklus über den gesamten Lebenszyklus.

Du musst diesen Zyklus nicht selbst erfinden. Es gibt etablierte Modelle, etwa von OWASP, einer Organisation mit umfangreichen Ressourcen und einem ausgearbeiteten, vielfach genutzten sicheren Entwicklungszyklus. Auch Behörden bieten solche Modelle an. Starte mit einem erprobten Modell und passe es an deinen Kontext an, statt bei null zu beginnen.

Sicherheit gehört zu den nicht-funktionalen Anforderungen, und genau hier liegt die Falle: Wenn User Stories bereits geschrieben sind, ist es oft zu spät. Deshalb gehören Sicherheits-Stories früh in den Prozess.

Täterberichte und Bedrohungsmodellierung

Eine vereinfachte Form der Sicherheitsanalyse sind Täterberichte: Wie könnte jemand dieses System angreifen? Sie sind die zugängliche Variante der Bedrohungsmodellierung, die in jedem sicheren Entwicklungszyklus vorkommt.

Bedrohungsmodellierung klingt kompliziert, ist es aber nicht. Das Team setzt sich zusammen und arbeitet drei Fragen strukturiert durch:

  • Was haben wir, das wertvoll ist? Eine Information, eine Finanztransaktion oder eine Aktion, die jemand aktivieren oder deaktivieren will.
  • Wer würde das für wertvoll halten?
  • Wie würde dieser Angreifer vorgehen, um an das Wertvolle zu kommen?

Das Vorgehen ähnelt der Planung von Hochverfügbarkeit: Man setzt sich hin und arbeitet aus, was alles schiefgehen kann und was bei jedem dieser Fälle passiert. Wer diesen Prozess durchläuft, weiß danach deutlich besser, wie robust sein System wirklich ist. Adam Shostaks Buch gilt als Klassiker zum Thema, daneben gibt es weitere gute Werke. Der wichtigste Rat der Experten: Mach es nicht unnötig kompliziert.

Zero-Day-Schwachstellen lassen sich nicht wegdesignen

Gegen Zero-Day-Schwachstellen gibt es keinen einzelnen Designtrick, sondern nur das Zusammenspiel mehrerer Prinzipien. Wer sich auf eine einzige Komponente verlässt und diese eine Zero-Day-Lücke hat, wird angegriffen.

Hier zahlt sich die mehrschichtige Verteidigung direkt aus. Dazu kommt die operative Seite: Hast du eine Strategie, um deine Komponenten aktuell zu halten? Im Open-Source-Zeitalter ist das schwer. Manche Ökosysteme, etwa das von Node.js, bestehen aus sehr fein granulierten Teilen. Ohne automatisierte Unterstützung behältst du den Überblick über Schwachstellen nicht.

Vollständige Kontrolle über Zero-Days ist nicht möglich, weil es einen Schwarzmarkt für solche Exploits gibt und ihre Existenz schwer zu erkennen ist. Was bleibt, ist im eigenen Einflussbereich konsequent: zu wissen, was im System steckt, und automatisiert zu überwachen, ob die Komponenten Schwachstellen aufweisen.

Tester sind die natürlichen Fürsprecher der Sicherheit

Tester denken berufsbedingt darüber nach, was schiefgehen könnte. Das macht sie zu den wertvollsten Beteiligten, wenn es darum geht, Sicherheit im Projekt zu verankern, denn die meisten anderen tun genau das nicht.

Auch Softwarearchitekten denken über Risiken nach, stehen aber unter Druck, neue Funktionen zu liefern, oder konzentrieren sich für zwei, drei Sprints auf ein bestimmtes Qualitätsmerkmal wie Durchsatz. Sie wissen, dass Sicherheit wichtig ist, haben den Kopf gerade aber woanders. Genau dort springt der Tester ein, der bemerkt, dass eine neue Funktion die Sicherheitskontrolle umgeht.

Damit das funktioniert, müssen Teams Tester für solche Fragen ermutigen. Es besteht die Gefahr, dass der Tester sich unbeliebt fühlt, weil er die schwierige Frage stellt. Die richtige Reaktion ist nicht Abwehr, sondern Dank: Ohne diese Frage hätte das Team einen Fehler gemacht.

Der DevOps-Gedanke hilft dabei, weil Tester früher ins Team kommen. Früher sah der Tester die Software als Letzter und konnte nur noch feststellen, was angerichtet wurde.

Wen du noch früh einbindest

Neben dem Tester gehört der Sicherheitsingenieur an den Tisch, idealerweise jemand mit Erfahrung in Anwendungssicherheit und Infrastruktur. Lädst du ihn zur gemeinsamen Bedrohungsmodellierung ein und stellst die richtigen Fragen, bringt er Punkte ein, an die im Team niemand gedacht hat.

Ein internes Pen-Test-Team setzt du sinnvoll früh ein, nicht erst für die Abschlusstests. Frühe Penetrationstests decken auf, was alles schiefgeht. Im Moment mag das in Ordnung sein, doch plötzlich denken alle darüber nach, dass dieser Teil sicher sein muss und es noch nicht ist. Sogar der Product Owner erkennt dann mitunter, dass Sicherheit ein größeres Thema ist als gedacht.

Diese Seite teilen

Ähnliche Beiträge