Die 15 Sicherheitsprinzipien der Softwareentwicklung (Teil 2)

Dienstag, 8.11.2022

Wir setzen unsere Blogreihe zu den 15 Prinzipien der sicheren Softwareentwicklung fort. Bei der Planung und anschließenden Umsetzung eines Software-Systems besteht der Anspruch, ein sicheres System zu entwickeln. Was jedoch zu tun ist, um diesem Anspruch gerecht zu werden, ist in der Praxis leider zu oft unklar. Im ersten Teil unserer Serie ging es um die Prinzipien Keep it simple, stupid, das positive Sicherheitsmodell, das Ursachenbehebungsprinzip, das Least-Privilege-Prinzip, das Vermeidungsprinzip und das Minimalprinzip. Im zweiten Teil beschäftigen wir uns mit den Prinzipien sieben bis zehn.

Blogserie-Sicherheitsprinzipien-Software-Teil2

Inhaltsübersicht:
  1. KISS - Keep it simple, stupid (in Teil 1 der Blogserie
  2. Positives Sicherheitsmodell (in Teil 1)
  3. Ursachenbehebungsprinzip (in Teil 1)
  4. Least Privilege (in Teil 1)
  5. Vermeidungsprinzip (in Teil 1)
  6. Minimalprinzip (in Teil 1)
  7. Secure by Design
  8. Misstrauensprinzip
  9. Defense in Depth
  10. Fail Secure
  11. Kenne deinen Gegner (in Teil 3 der Blogreihe)
  12. Kerckhoffs'sches Prinzip (in Teil 3)
  13. Indirektionsprinzip (in Teil 3)
  14. Konsistente Sicherheit (in Teil 3)
  15. Nutzerfreundliche Sicherheit (in Teil 3)

 

Secure by Design: Berücksichtige Sicherheit im Entwurf

Security-by-Design-symbolbild

Sicherheitsrelevante Designentscheidungen werden zu Beginn der Softwareentwicklung festgelegt und sollen durch den Entwicklungsprozess umgesetzt werden. So wird sichergestellt, dass die Informationssicherheit ein wesentlicher Bestandteil für die Software ist und über alle Ebenen des Systems berücksichtigt wird. Somit bezieht sich dieses Prinzip nicht nur auf Designentscheidungen wie bspw. ein:e Benutzer:in authentifiziert wird oder welche Systeme besonders stark geschützt werden müssen, sondern auch auf grundlegendere Themen wie ein Secure Code Review durchgeführt werden sollte und Copy & Paste Code zu Sicherheitsproblemen führen kann.

WARUM SOLLTE ICH DIESES PRINZIP KENNEN / BERÜCKSICHTIGEN?

Beim Entwurf auf die Sicherheit zu achten und diese nicht erst am Ende der Softwareentwicklung zu betrachten (bspw. Penetrationstests) verhält sich vergleichbar mit dem Vorgehen zum Ende der Entwicklung Qualität in das Produkt "reinzutesten". Dieses Vorgehen birgt das Risiko nachträglich teure Änderungsmaßnahmen für einen sicheren Betrieb durchführen zu müssen.

BEISPIELE FÜR Secure by design

Ein aktuelles und als äußerst positives Beispiel zu benennendes sicheres Softwaredesign ist die Corona-Warn-App. Die frühe Berücksichtigung von Sicherheits- und Datenschutzproblematiken hat dazu geführt, dass es für die Bundesregierung vom Konzept her nicht möglich ist herauszufinden, wer einem hohen Ansteckungsrisiko ausgesetzt war und wo sich der Benutzer aufgehalten hat. Selbst bei einem "bad actor" in der Nähe des Handys wird die Genauigkeit und Effektivität nicht geschmälert. Diese gelungenen Designentscheidungen in der Corona-Warn-App stehen im Kontrast zu den gut gemeinten, aber nur leidlich wirkungsvollen Schutzmaßnahmen der LUCA-App, welche mittlerweile die Kontaktverfolgung eingestellt hat.

Ein weiteres lehrreiches Beispiel ist die Umsetzung von digitalen Schulzeugnissen mithilfe von Blockchain-Technologien durch die Bundesdruckerei. Innerhalb kurzer Zeit wurden nach dem Start eklatante Sicherheitsprobleme gefunden, welche sogar das Schreiben von falschen Daten in die fälschungssichere Blockchain ermöglichten. Damit ist die hier als Absicherung gedachte Kernidee der Blockchain ad absurdum geführt. Hier wurde offensichtlich die Sicherheit im Entwurf nicht ausreichend berücksichtigt.

 

Vertraue niemanden ("Misstrauensprinzip")

misstrauen

Das Misstrauensprinzip kann auch als "Zero Trust" oder "Reluctance to Trust" bezeichnet werden. Kerngedanke ist es, bei der Softwareentwicklung immer davon auszugehen, dass sich das System in einer nicht vertrauenswürdigen Umgebung befindet. Mit bösartigem Verhalten anderer Systeme wird gerechnet. Dies umfasst sowohl das sorgfältige Prüfen von Benutzereingaben als auch bspw. die Authentifizierung zwischen Server und Datenbank, welche ausschließlich intern erreichbar ist.

WARUM SOLLTE ICH DIESES PRINZIP KENNEN / BERÜCKSICHTIGEN?

Software ist und wird niemals zu 100 % sicher sein. Software mit diesem Prinzip im Hinterkopf zu entwickeln, verringert die Möglichkeiten der Angreifer:innen sich nach dem erfolgreichen Angriff auch auf weitere Systeme Zugriff zu verschaffen. Damit steigt die Wahrscheinlichkeit, ohne größere Schäden davonzukommen.

BEISPIELE FÜR das Misstrauensprinzip

Nach außen hin wird eine API zur Verfügung gestellt, welche von dem eigens entwickelten Client verwendet wird. Hier muss man unter anderem damit rechnen, dass die API nicht ausschließlich durch den offiziellen Client genutzt wird. Auch in diesem Fall muss die API weiterhin sauber arbeiten, weshalb bspw. der Server in jedem Fall eine Input-Validierung durchführen muss. Diese Eingaben auf korrekte Berechtigungen zu prüfen, ist 2021 der Wahlkampf-App der CDU zum Verhängnis geworden.

Ein weiteres Beispiel ist es, sich im selben Netzwerksegment nicht automatisch zu vertrauen. Hier sollte weiterhin auf sichere Verbindungen, Authentifizierung und Validierung gesetzt werden. Selbst wenn es nun den Angreifern:innen gelingt, sich Zugang zu dem Netzwerksegment zu verschaffen, müssen diese weitere Hürden überwinden.

 

Defense in Depth: Implementiere Sicherheit mehrschichtig

defense-in-depth

Für mehrschichtige Sicherheit werden mehrere Security Controls (Kontrollmechanismen) durchgesetzt, welche den Risiken auf verschiedenen Wegen entgegentreten. Selbst beim Aushebeln einer Kontrollebene greift die nächste und verhindert eine Kompromittierung der Systeme durch eine einzelne Schwachstelle.

Worin besteht nun der Unterschied von "Defense in Depth" und dem Misstrauensprinzip "Zero Trust"?
"Defense in Depth" zielt darauf ab, Angriffe auszubremsen, indem die Anzahl von Hürden für den Zugang zum Sicherheitsbereich erhöht wird. Wohingegen "Zero Trust" sich auf das Verhindern von Angriffen konzentriert, unabhängig davon, wo man sich im System aufhält. Somit ergänzen sich beide Prinzipien bei der Abwehr von Angriffen.

WARUM SOLLTE ICH DIESES PRINZIP KENNEN / BERÜCKSICHTIGEN?

Ein erfolgreicher Angriff benötigt damit mehrere Schwachstellen, um Schaden anrichten zu können. Damit hilft dieses Prinzip dabei die Wahrscheinlichkeit eines Single Point of Failure im System zu reduzieren.

BEISPIELE FÜR das "Defense in Depth"

Ein übliches Beispiel für dieses Prinzip sind mittelalterliche Burgen mit Befestigungsringen in Form von Wassergräben und Burgmauern. Diese Ringe sind mit genügend Zeit und Aufwand nicht unüberwindbar. Ziel ist es, dass ein:e Angreifer:in an die Grenzen der verfügbaren Ressourcen ankommt, bevor die böswilligen Ziele erreicht wurden. Auf IT-Systeme übertragen bestehen diese Ringe bspw. aus Firewalls, VPNs, Intrusion Detection Systemen, starken Authentifizierungsmechanismen und Prüfung von Nutzereingaben. Keine dieser Techniken ist unüberwindbar, jedoch in Kombination erhöhen diese den Angriffsaufwand signifikant.

 

 

 Fail Secure: Gewährleiste einen sicheren Zustand

fail-secure

Im Falle eines Fehlers darf das System nicht in einen Zustand übergehen, welcher die Sicherheit gefährdet. Dies ist von "Fail safe" zu unterscheiden, denn dort soll das System im Falle eines Fehlers bspw. ohne Datenkorrumpierung weiterarbeiten oder herunterfahren. Bei "Fail secure" ist zwischen zwei Fällen zu unterscheiden.

Fehlerfall während der Durchführung einer:

  1. sicherheitsrelevanten Operation
  2. nicht sicherheitsrelevanten Operation

Im ersten Fall darf der Fehler kein Verhalten ermöglichen, welches bei der fehlerfreien Durchführung der sicherheitsrelevanten Operation nicht möglich wäre.

Im zweiten Fall muss anschließend derselbe Ausführungspfad gewählt werden, als wenn diese Operation unautorisiert ausgeführt worden wäre.

WARUM SOLLTE ICH DIESES PRINZIP KENNEN / BERÜCKSICHTIGEN?

Eine saubere und einheitliche Behandlung von Fehlerfällen macht es einfacher vorherzusehen, wie sich ein System verhalten wird und es in einem definierten und sicheren Zustand zu halten. Damit ist der Nutzen dieses Prinzips nicht auf Sicherheit allein beschränkt.

BEISPIELE FÜR das "Fail safe"

Man stelle sich vor, dass der ID-Provider ausfällt und dadurch auch unauthentifizierte Benutzer mit den Schnittstellen kommunizieren können. Hier stehen Fail Safe und Fail Secure im Gegensatz. Trotz Ausfall des ID-Providers können weiterhin alle Systeme weiterverwendet werden, jedoch sind die Systeme jetzt für jeden offen.

Hier ein Codebeispiel, für eine schlechte Fehlerbehandlung innerhalb einer sicherheitsrelevanten Operation:

isAdmin = true; 
try {
codeWhichMayFail();
isAdmin = isUserInRole( “Administrator” );
}
catch (Exception ex)
{
log.write(ex.toString());
}

Im Fehlerfall bleibt isAdmin auf "true". Fail Secure würde damit starten, dass isAdmin mit "false" initialisiert wird und erst bei erfolgreicher Überprüfung auf "true" gesetzt wird.

 

15 Sicherheitsprinzipien der Softwareentwicklung CTA zum Download

 

Unsere Blogserie 15 Sicherheitsprinzipien der Softwareentwicklung

Addon: Laden Sie sich kostenlos unsere Übersicht über die 15 Prinzipien herunter.

Unsere Angebote und Schulungen zu IT-Sicherheit.


zurück zur Blogübersicht

Diese Beiträge könnten Sie ebenfalls interessieren

Keinen Beitrag verpassen – viadee Blog abonnieren

Jetzt Blog abonnieren!

Kommentare

Florian Kretschmer

Florian Kretschmer

Florian Kretschmer ist seit 2022 als IT-Berater und Softwareentwickler für die viadee IT-Unternehmensberatung tätig. Über die Entwicklung von maßgeschneiderten Softwarelösungen hinaus engagiert er sich im Kompetenzbereich Security. Florian Kretschmer bei Xing   Florian Kretschmer