10 Grundsätze für sichere Softwareentwicklung

Die Entwicklung moderner Software ist heutzutage so komplex, dass Fehler trotz intensiver Prüfung nicht oder nur schwer erkennbar sind. Dies hat eindrucksvoll die Heartbleed-Schwachstelle der älteren Version der Open-Source-Bibliothek OpenSSL gezeigt. Ein Großteil der Online-Dienste und Websites zeigte sich dadurch für Angriffe anfällig. Dieser Artikel nennt zehn Grundsätze für eine sichere Softwareentwicklung.

 

Grundsatz 1: Injektionen sowie XSS- und CSRF-Schwachstellen verhindern!

Zu den am meisten verbreiteten Sicherheitsschwachstellen in Web-Anwendungen gehören Injektions-, XSS- und CSRF-Verwundbarkeiten. Sie gelten als das am meisten genutzte Einfallstor für Cyber-Kriminelle. Schaffen Hacker aufgrund dieser Schwachstellen im System den Zugriff auf sensible Daten der Kunden, lassen sich diese manipulieren und schädigen im schlimmsten Fall dauerhaft die gesamte IT-Infrastruktur.

 

Injektionsschwachstellen

Injektionsschwachstellen entstehen, wenn Benutzereingaben zur Erstellung von Anweisungen oder Abfragen, z.B. SQL-Abfragen, verwendet und ohne ausreichende Überprüfung an einen Interpreter weitersendet werden. Durch Manipulation der Eingabesyntax kann ein Angreifer unerwünschte Befehle ausführen und unbefugten Zugriff auf sensible Daten erhalten. Zum Beispiel ermöglicht eine SQL-Injection in einer Web-Anwendung einen Datenbankzugriff im Backend.

 

Cross-Site-Scripting

Cross-Site-Scripting (XSS) ist eine Art HTML-Injection, die im Web-Browser des Benutzers stattfindet. XSS-Schwachstellen entstehen, wenn Web-Anwendungen Benutzereingaben annehmen und diese anschließend ohne Validierung an den Browser weiterleiten. Ein Beispiel dafür wäre, wenn ein Benutzer einen Suchbegriff in ein Formular eingibt und anschließend eine neue Seite mit Suchergebnissen im Browser angezeigt wird, auf der auch vom Benutzer gewählte Suchbegriff nochmals mit erscheint. Auf diese Weise können Angreifer Schadcode auf indirektem Wege im Browser des Opfers ausführen – häufig über bestimmte, gut vorbereitete URLs.

 

Cross-Site-Request-Forgery

Bei einem CSRF-Angriff (Cross-Site-Request-Forgery) führt ein Angreifer HTTP-Anfragen über den Web-Browser eines Anwenders aus. Aus Sicht der Anwendungen sehen die Anfragen legitim aus und werden im Kontext und mit den Rechten eines aktuell angemeldeten Benutzers bearbeitet. Die Anwendung unterscheidet nicht zwischen den Anfragen des rechtmäßigen Nutzers und den gefälschten Anfragen des Angreifers. Anwendungen ohne SSRF-Schutz stellen immer eine potentielle Bedrohung für Benutzer und deren Daten dar.

 

Tipps zur Programmierung

Zu den nützlichen Maßnahmen zählen Benutzereingaben, die nur im Bedarfsfall zum Einsatz kommen. Weiteren Schutz bieten Eingaben, die gefiltert und geprüft wurden, bevor der Entwickler sie erstmalig verarbeitet. Dieser First-Line-of-Defense-Ansatz schützt Anwendungen vor Injektionsangriffen. Alle modernen Programmiersprachen und Frameworks stellen in der Regel getestete Routinen zur Filterung von Benutzereingaben zur Verfügung und reduzieren damit das Risiko eines Angriffs deutlich. Bei der Entwicklung und Verwendung eigener Methoden besteht grundsätzlich die Gefahr etwas zu übersehen. Die Implementierung von Funktionen zum Anlegen, Lesen, Ändern und Löschen von Daten, sogenannte CRUD-Methoden[1], erfolgt am besten mit den integrierten Funktionen des jeweiligen Frameworks. Der Fachbegriff hierfür lautet Scaffolding und viele Frameworks bieten geeignete Methoden, um auf Knopfdruck die nötigen Eingabemasken inklusive Programmlogik auf Basis eines Datenmodells zu erzeugen.

Nachhaltige Systemschäden lassen sich unterbinden, wenn für den Zugriff von Web-Anwendungen auf Datenbanken ausschließlich definierte Befehle zugelassen werden, die für die Funktionalität der Anwendung notwendig sind. Sollte es einem Angreifer gelingen Schadcode zu injizieren, bleibt dieser auf Grund der Einschränkung auf bestimmte Schlüsselwörter wirkungslos und ein Systemschaden kann abgewendet werden.

 

Grundsatz 2: Trennung von Datenverarbeitung und Datendarstellung

Wichtig bei der Verarbeitung von Daten ist die Trennung von Darstellungslogik, z. B. Ausgabe im Web-Browser, und der internen Anwendungslogik. Dafür ist das Model-View-Controller-Pattern (MVC) prädestiniert, das vielen Java-Entwicklern noch von der GUI-Programmierung mit Java-Swing bekannt sein dürfte. Anwendungen die dem MVC-Pattern folgen, bestehen aus einem oder mehreren Datenmodellen (Model), Darstellungsschichten (Views) und Programmsteuerungen (Controller). Durch diese Trennung reduziert das MVC-Pattern den Aufwand für Anpassungen an einzelne Komponenten der Anwendung und erhöht die Wiederverwendbarkeit dieser Elemente. Das Datenmodell beschreibt die von der Anwendung verarbeiteten Daten, ihren Datentyp, ihren Wertebereich und ist unabhängig von der Darstellung und Steuerung innerhalb der Anwendung. Die Darstellungsschicht zeigt die Darstellung der Daten gemäß dem Datenmodell und nimmt Benutzerinteraktionen entgegen. Die Programmsteuerung verwaltet eine oder mehrere Darstellungen, nimmt Benutzerinteraktionen von ihnen entgegen, wertet sie aus und handelt entsprechend.

 

Trennung von Anwendungslogik und Darstellung

Durch die Trennung von Anwendungslogik und Datendarstellung vermeidet der Entwickler, dass sich wichtige und sicherheitsrelevante Funktionen versehentlich in die Darstellungsschicht auslagern und der Angreifer einfacher das Sicherheitssystem umgehen kann. Die Trennung erleichtert auch die Entwicklung von einem oder mehreren Frontends unabhängig von der Anwendungslogik oder dem Datenmodell. Insbesondere bei Anwendungen mit Responsive-Design werden verschiedene Frontends nicht mit dem eigentlichen Anwendungscode vermischt. Der Programmcode bleibt klar strukturiert, was auch die spätere Wartung und Weiterentwicklung der Anwendungen erleichtert. Darüber hinaus erhöht sich die Wiederverwendbarkeit einzelner Codekomponenten durch die strikte Trennung der Programmcodes. So greifen verschiedene Anwendungen auf ein Datenmodell zu oder ein Datenmodell lässt sich durch verschiedene Ansichten darstellen, wie z. B. eine Übersichtsansicht, eine Detailansicht, eine Ansicht zur Bearbeitung der Daten.

 

Tipps zur Programmierung:

Hilfreich bei der Programmierung erweisen sich Entwickler-Frameworks, die das MVC-Pattern unterstützen und Werkzeuge für die Erstellung von Controllers, Views und Models bereitstellen. Das Datenmodell beschreibt beispielsweise Datentyp und Wertebereiche, der Controller implementiert Routinen zur Steuerung der Anwendungslogik und der View-Bereich stellt die Daten dar.

 

Scaffolding zur Implementierung von MVC-Programm-Code

Entwickler-Frameworks unterstützen häufig die Erstellung von Programmcode für Models, Views und Controller durch Scaffolding. Die Vorlagen der Frameworks erzeugen standardisierte CRUD-Operationen. Das spart Zeit und reduziert den Stress während der Entwicklung. Und nicht nur das, diese Vorlagen sind oft sehr robust und der generierte Quellcode kapselt Variablen und Eingabeparameter mit Sicherheitsmechanismen ab, die das Framework bereitstellt. Bei der Entwicklung neuer Anwendungen bieten sich fertige Entwicklungsframeworks an, die das MVC-Pattern unterstützen und Scaffolding-Mechanismen anbieten.

 

Grundsatz 3: Daten vor der Verarbeitung immer validieren

Die konsequente Validierung, also die Verifizierung von Eingabe- und Ausgabedaten, stellt ein Grundprinzip für die Entwicklung von korrekt funktionierenden, stabilen und sicheren Anwendungen dar. Fehlerhafte Datenpools oder gar Sicherheitsschwachstellen entstehen oftmals aufgrund fehlerhafter Prüfung von Syntax und Semantik (siehe Grundsatz 1). Die fehlende Datenvalidierung und -filterung zählt dabei zu den häufigsten Hacker begünstigenden Umständen und ermöglicht umfangreiche Angriffe auf Web-Anwendungen, z.B. SQL-Injektionen für den Zugriff auf Datenbanken. Die Vertraulichkeit, Integrität und Verfügbarkeit der Daten unserer Nutzer ist daher unmittelbar gefährdet. Häufig erhalten Angreifer über solche Schwachstellen nicht nur Zugriff auf Daten, sondern auch auf die Server, auf denen diese Anwendungen laufen.

 

Gefahr von Verlust der Datenintegrität und niedriger Datenqualität

Die Integrität der Daten erweist sich neben der Vertraulichkeit und Verfügbarkeit als ein wichtiges Merkmal. Ohne ausreichende Validierung besteht die Gefahr der Unvollständigkeit oder sie erweisen sich als einfach falsch, z.B. negatives Alter einer Person. In diesem Fall spricht man auch von einer geringen Datenqualität oder einer Abweichung vom Datenmodell. Die Auswirkungen solcher fehlerhaften Datensätze breiten sich je Anwendungslogik weiter aus und verursachen Fehler in der Weiterverarbeitung innerhalb der Anwendung.

 

Tipps zur Programmierung:

Hauptsächlich geht es bei einer Softwareentwicklung um die Verteidigung in der Tiefe (Defense-in-Depth). Dies ist eine Methode, die Sicherheit durch mehrere Schutzmaßnahmen kennzeichnet. Sicher gewählte Anwendungen überprüfen die Korrektheit der Daten an verschiedenen Stellen während der Verarbeitung. Das heißt, umgeht der Angreifer einzelne Prüfroutinen, schlagen die übrigen Warnsysteme Alarm und die Anwender-Tools reagieren entsprechend. Im Datenmodell definieren sich die richtigen Datentypen und Wertebereiche. Die Anwendungslogik (im Controller) verarbeitet die Daten und überprüft, ob diese semantisch gültig sind.

 

Prüfung und Validierung von Daten

Der Softwareingenieur überprüft bei der Entwicklung von Funktionen zur Datenverarbeitung, beispielsweise zur Speicherung von Benutzereingaben in einer Datenbank oder zur Durchführung mathematischer Operationen, ob sich Werte als zuverlässig darstellen. Dies ist insbesondere bei Benutzereingaben und Übergabeparametern in Funktionen erforderlich. Einerseits sichert sich das Unternehmen dadurch die Datenqualität, andererseits verhindert es so Manipulationen oder gar Angriffe auf die Anwendung und Daten der Nutzer.

 

Grundsatz 4: Datenschutz zwischen Web-Browser und Anwendung vor externer Einsicht

Daten, die im Austausch stehen zwischen Servern und Web-Browsern, benötigen Schutz vor externer Einsicht. Eine sichere Datenübertragung zwischen Client und Server, z.B. über eine HTTP(S)-gesicherte Verbindung, ist wichtig, da die Bevölkerung zunehmend freie WLAN-Hotspots mit unverschlüsselten Verbindungen akzeptiert. Angreifer nutzen diese Lücke, um private und sensible Informationen wie Passwörter, Nutzersitzungen oder auch persönliche Daten einzusehen.

 

Einsicht von Fremden in übertragene Daten vermeiden

Erhält der Angreifer Einsicht in die Datenübertragung zwischen unseren Servern und den Nutzern, bekommt er möglicherweise Einblick in sensible und schutzwürdige Informationen. Die Vertraulichkeit der Daten ist damit nicht mehr gegeben, vor allem wenn Informationen wie Benutzernamen und Passwörter von Fremden einsehbar sind. So erhalten Unbefugte Zugang zu den Anwendungen und greifen unter vorgegebener Identität und mit den Rechten der betroffenen Nutzer auf die Daten zu und manipulieren diese. Ursachen hierfür liegen in der fehlerhaften Implementierung von Schutzmechanismen oder in der Verwendung veralteter und unsicherer Verfahren zur Verschlüsselung.

 

Verschlüsselung der Übertragung

Sichere Anwendungen verschlüsseln sensible Daten, beispielsweise mit TLS 1.2 oder TLS 1.3, sodass Angreifer keinen Zugang zu den Daten bekommen – auch dann nicht, wenn der Angreifer sich bereits in die Kommunikation zwischen Web-Browser und Anwendung eingeklinkt hat, zum Beispiel durch einen Man-in-the-Middle-Angriff. Über das HTTP(S)-Protokoll verschlüsselte Internetverbindungen liefern dabei einen hohen Sicherheitsstandard. Dasselbe gilt für die Datenübertragung über das Internet. Auch hier bieten sich verschlüsselte Protokolle an. In diesem Zusammenhang stellt der SFTP einen enormen Vorteil gegenüber dem unverschlüsselten FTP dar, so wie SSH anstelle von Telnet.

Die Sicherheitsschwachstellen POODLE, Heartbleed und BEAST zeigen deutlich, dass die verwendete Übertragungsverschlüsselung immer auf dem neuesten Stand der Technik sein muss, um die Vertraulichkeit sensibler Daten zu gewährleisten und dauerhafte Schäden an den Systemen der Nutzer zu vermeiden.

 

Verschlüsselung nicht selbst entwickeln, sondern Standardlösungen verwenden

Grundsätzlich bieten alle modernen Programmiersprachen und Frameworks Möglichkeiten zur Implementierung von bereits erprobten Verschlüsselungsverfahren für die Übertragungsverschlüsselung, z.B. TLS mit Perfect-Forward-Secrecy, die bereits mit aufwendigen Standardisierungsprozessen eingeführt wurden. Bei eigens entwickelten Verschlüsselungsverfahren besteht immer die Gefahr, etwas zu übersehen. Ein einprägsames Zitat von Brian Hatch zu diesem Thema lautet: „Jeder Programmierer versucht irgendwann, einen eigenen Verschlüsselungsalgorithmus zu entwickeln. Kurz gesagt: Lassen Sie das!“

 

Grundsatz 5: Die Nutzer der Anwendung im Auge behalten

Fehler in der Nutzer- und Sitzungsverwaltung von Web-Anwendungen führen oftmals zu Sicherheitsschwachstellen. Beispielsweise durch Authentifizierungsfehler, unzureichende Prüfroutinen während des Zurücksetzens des Passworts oder durch unvollständige Prüfungen der jeweiligen Berechtigungen bei der Ausführung von Aktionen innerhalb der Anwendung (Datenzugriff, Änderungen, Datensätze löschen). Daher ist es wichtig, den Nutzer und seine Berechtigungen innerhalb einer Sitzung in den Anwendungen jederzeit im Auge zu behalten. Dies gilt insbesondere für die Prüfung von Berechtigungen bei der Ausführung von CRUD-Operationen.

Es ist wichtig, Nutzersitzungen ausreichend zu sichern, um Fremden den Zugriff auf die Anwendungen oder Cookies mit Sitzungsinformationen, z.B. SessionID, zu verwehren. Ebenso führen Fehler bei der Implementierung von Funktionen zum Passwort zurücksetzen häufig dazu, dass Fremde Einblick in Nutzerkonten erhalten. Sichere Anwendungen und Verfahren stellen daher einen wichtigen Schutz vor Bedrohungen dar.

Wichtig ist die vollständige und robuste Implementierung von Berechtigungsprüfungen, um Angreifern keine Chance für Manipulierung oder Löschung der Daten zu geben. Der unbefugte Zugriff auf Daten oder Funktionen innerhalb unserer Anwendungen gefährdet unmittelbar die Vertraulichkeit, Integrität und Verfügbarkeit der Daten unserer Nutzer und stellt eine Bedrohung für die IT-Infrastruktur dar.

 

Tipps zur Programmierung:

Für die sichere Implementierung von Nutzer-An- und -Abmeldefunktionen erweisen sich Standardverfahren, die Entwicklungs-Frameworks, als sehr hilfreich. Je nach Bedarf bieten sich auch zusätzliche Sicherheitsprüfungen durch einen zweiten Entwickler an.

Bei der Implementierung von CRUD-Operationen in den Anwendungen stellen die obligatorischen Berechtigungsprüfungen eine weitere Regel dar. Zu Beginn einer jeden CRUD-Operation ist zu prüfen, ob der aktuell angemeldete Benutzer berechtigt ist, den jeweiligen Vorgang für den betroffenen Datensatz durchzuführen. Die mithilfe von Scaffolding erstellten Frameworks, die bei CRUD-Verfahren zum Einsatz kommen, enthalten in der Regel diese Berechtigungsprüfungen und dienen während der Entwicklung als Ressourcen.

 

Grundsatz 6: Über die geeignete Protokollierung von Ereignissen nachdenken

Während des normalen Betriebs der Anwendungen kommen eine Vielzahl von Ereignissen und Aktionen von Nutzern vor. Treten in der Anwendung Fehler auf oder hat sich ein sicherheitsrelevanter Vorfall, wie ein Hackerangriff ereignet, ist es für eine erfolgreiche Post-Mortem-Analyse unerlässlich, die Ereignisse nachhaltig zu betrachten. Hierzu braucht es eine ausführliche Protokollierung (Logging) der Anwendungen, Ereignisse und Benutzerinteraktionen. Dabei sind insbesondere die Datenschutzbestimmungen zu berücksichtigen.

Tritt ein Sicherheitszwischenfall ein oder kommt es zur Manipulation von Daten, sind detaillierte Analysen unerlässlich. Andernfalls lassen sich Vorfälle nicht nachvollziehen und Angreifer nicht zuordnen. Treten Fehler in unseren Anwendungen auf und kontaktieren uns Kunden, sind Support- und Entwicklungsteams auf möglichst detaillierte Informationen angewiesen, um die Fehlerursache schnell zu identifizieren (Ursachenanalyse). Log-Einträge stellen bei der Fehlersuche eine wichtige Informationsquelle dar und ermöglichen es, das Problem schneller zu analysieren.

 

Tipps zur Programmierung:

Prüfprotokoll

Wichtig für die Fehleranalyse ist es festzustellen, welcher Nutzer wann welche Aktionen in unseren Anwendungen durchgeführt hat. Dies gilt insbesondere für mandantenfähige Anwendungen und SaaS-Services.

Folgende Ereignisse benötigen mindestens eine Protokollierung:

  • Anmeldeversuche mit falschen Zugangsdaten
  • Administratoranmeldungen und -aktivitäten
  • Änderungen an Benutzerkonten und Berechtigungen
  • Fehler in der Sitzungsverwaltung
  • Fehler bei der Eingabewertprüfung
  • Fehler innerhalb der Anwendung (z. B. Ausnahmen)
  • Schreibzugriffe auf Daten innerhalb der Anwendung
  • Herunterfahren, Starten und Neustarten von Anwendungen oder Systemen

Protokolleinträge brauchen ein einheitliches Format und nach Möglichkeit weitere Attribute, die für eine spätere Auswertung oder automatisierte Auswertung durch SIEM-Systeme (Security-Information-and-Event-Management) wichtig sind:

  • Schwere (z.B. niedrig, mittel, hoch, kritisch, Sicherheit, Debuggen)
  • Kunden-ID
  • Zeitstempel
  • Nutzer-ID
  • IP-Adressen, HTTP-Methoden und angeforderte URLs (inkl. Parameter)

Bei der Protokollierung gelten die aktuellen Datenschutzbestimmungen (EU-DSGVO) und deren Anforderungen. Hierzu zählt auch das Informieren und das Anzeigen eines Datenschutzhinweises. Sensible und personenbezogene Daten bleiben bei der Protokollierung außen vor.

Dazu gehören z. B.:

  • Passwörter
  • Verschlüsselungs-Codes
  • Gesundheitsdaten
  • Finanzdaten (z. B. Bankverbindung, Kreditkartendaten)

In Ausnahmefällen und nach Klärung des rechtlichen Rahmens dürfen Protokolle sensible und personenbezogene Daten aufzeichnen, jedoch nur unter Berücksichtigung der Pseudonymisierung oder der Verwendung von kryptografisch sicheren Hash-Methoden.

 

Grundsatz 7: APIs und REST-Schnittstellen sichern

Häufig stellen Web-Anwendungen auch APIs sowie Teile ihrer Funktionalität über sogenannte REST-Schnittstellen bereit. Diese Schnittstellen implementieren und sichern Entwickler genauso robust wie die übrige Anwendung. Dazu gehören das Filtern und Validieren von Ein- und Ausgaben sowie das sichere und zuverlässige Abrufen und Verifizieren von Nutzern und deren Rechten. Je nachdem, welche Datenformate diese Schnittstellen verwenden, z.B. JSON oder XML, benötigen sie Filterroutinen, die spezifische Sicherheitsfunktionen für das jeweilige Format ergänzen. Wenn APIs oder REST-Schnittstellen für Fremde zugänglich und nicht vollständig und robust in Anwendungen implementiert sind, können nicht autorisierte Nutzer Daten manipulieren oder löschen. Der unbefugte Zugriff auf Daten oder Funktionen über solche Schnittstellen kompromittiert unmittelbar die Vertraulichkeit, Integrität und Verfügbarkeit der Nutzerdaten und stellt eine Bedrohung für unsere IT-Infrastruktur dar.

 

Tipps für die Entwicklung:

Um Angriffe über manipulierte Client-Anfragen oder manipulierte Parameter zu verhindern, filtern und prüfen Programmierer anhand einer Whitelist (Liste legitimer Werte) alle Daten eingehend. Eine restriktive Whitelist enthält nur zulässige Werte und Zeichenketten. Viele Frameworks bieten APIs und REST-Schnittstellen zum Filtern oder Whitelisting, häufig in Verbindung mit Scaffolding und der automatisierten Erstellung von Quellcode für APIs und REST-Schnittstellen. Entwickler prüfen sicherheitshalber erneut die vom Framework erstellten Filterregeln und Whitelists. TLS insbesondere mit PFS stellen sicher, dass Server und Client Daten, insbesondere wichtige Token, Anmelde- oder Sitzungsdaten, immer verschlüsselt austauschen und Dritte diese nicht abfangen oder manipulieren. Die Übertragungsverschlüsselung trägt damit wesentlich zur Vertraulichkeit und Integrität der Kundendaten bei.

Die Implementierung von TLS braucht ausreichend Zeit, da eine Fehlkonfiguration und andere Szenarien bewirken, dass Angreifer durch Downgrade-Angriffe auf TLS oder aufgrund fehlender Zertifikatsprüfungen trotz Übertragungsverschlüsselung Zugriff auf sensible Daten haben. Sensible Informationen wie Benutzernamen, Passwörter und Sicherheits-Token sind nicht in der URL zu codieren, damit Web-Browser-Verlauf oder unverschlüsselte Verbindungen in Serverprotokollen keine Hinweise liefern.

 

Grundsatz 8: Die Methoden selbst testen, bevor andere es tun

Bereits während der Entwicklung sollten Programmierer die Funktionen und Schnittstellen auf korrektes Funktionieren und ihr Verhalten bei fehlerhaften Parametern und Eingabewerten überprüfen. Ein bewährtes Verfahren für diesen Test von Modulen sind die sogenannten Unit-Tests. In der Prüfeinheit erstellt der Test für jede Funktion oder Methode eine Prüfroutine, die zunächst einen Ausgabezustand erzeugt, zum Beispiel Zuweisung von Variablenwerten, dann die zu testende Funktion/Methode aufruft und schließlich das Ergebnis, wie einen Ausgabewert mit dem erwarteten oder gewünschten Verhalten vergleicht. Es besteht die Möglichkeit, solche Unit-Tests mit Werkzeugen bei Integration in die Entwicklungs-IDE automatisch durchzuführen und auszuwerten. Entsprechende Werkzeuge und Frameworks sind für alle gängigen Programmiersprachen verfügbar.

Ohne Qualitätskontrolle oder bei unzureichenden Prüfverfahren besteht die Chance, funktionale und/oder sicherheitsrelevante Fehler in unseren Anwendungen unter Umständen zu übersehen und erst im Produktivbetrieb zu bemerken. Durch die Komplexität heutiger Programmcodes ist die Ursachenanalyse von Problemen aufgrund von Quellcodefehlern häufig sehr schwierig. Dies gilt insbesondere dann, wenn das Fehlverhalten nicht wirklich reproduzierbar ist oder über mehrere Programmkomponenten, -klassen, -module und -funktionen hinweg auftritt.

 

Tipps für die Entwicklung:

Bei der Speicherung von Daten im Programm-code oder der Verarbeitung von Ausgabewerten ist es wichtig, die einzelnen Datenfelder und Variablen daraufhin zu überprüfen, ob die Werte gültig sind und innerhalb des erwarteten Wertebereichs liegen. Es ist ratsam, für jede Funktion einen eigenen Unit-Test zu erstellen, der prüft, ob die Funktion bei fehlerhaften Eingabedaten korrekt arbeitet und sich erwartungsgemäß verhält. Für die meisten Programmiersprachen gibt es Software-Tools und Werkzeuge zur Erstellung von Unit-Tests, die sich auch in gängige Entwicklungsumgebungen integrieren lassen. Um Fehler frühzeitig zu erkennen und zu beheben, achten Softwareentwickler auf regelmäßige und automatische Unit-Tests. Sie ermöglichen eine frühe Fehlererkennung und eine schnelle Korrektur.

 

Grundsatz 9: Keinen externen und nicht selbst kontrollierten Quellen vertrauen

Web-Anwendungen enthalten oft Inhalte aus anderen Quellen, insbesondere von Content-Providern. Der Inhalt wird meist im Quellcode referenziert und vom Web-Browser des Nutzers dynamisch geladen. Bei der Integration von Inhalten aus Drittquellen ist die Vertrauenswürdigkeit der Quelle zu klassifizieren und gegebenenfalls sind die von Dritten gelieferten Inhalte zu überprüfen oder zu filtern.

Dateien von externen Servern können mit Schadcode infiziert sein, der durch die Integration in Anwendungen die Computersysteme der Nutzer infiziert. In der Vergangenheit tauchten solche Fälle vor allem durch Malware in Onlinewerbung auf, die auf Grund ihrer Integration in eine Vielzahl von Websites und Anwendungen, eine große Anzahl von Computersystemen infizierte.

Wenn integrierte externe Dateien eine Bedrohung für Nutzer darstellen, kann dies auch einen Image-Schaden für den Kunden nach sich ziehen. So ist die Herkunft von Schadcode für viele Nutzer nicht direkt nachvollziehbar und so problemlos mit den Kundenanwendungen in Verbindung zu bringen. Daher gilt: Alle möglichen Sicherheitsvorkehrungen treffen und integrierte externe Inhalte und Dateien sorgfältig prüfen und nur auf vertrauenswürdige Quellen zurückgreifen.

 

Tipps für die Entwicklung

Vor der Integration externer Inhalte steht die Überprüfung der Zuverlässigkeit und Vertrauenswürdigkeit der Quelle:

  • Stammen die Inhalte von einem bekannten Anbieter?
  • Ist der Content-Provider schon lange am Markt tätig?
  • Gab es in der Vergangenheit Sicherheitsvorfälle im Zusammenhang mit dem Content-Provider?

Wenn möglich isolieren Entwickler externe Inhalte von der übrigen Anwendung und statten sie mit so wenig Rechten wie möglich aus. Dies erreichen Programmierer zum Beispiel durch die Verwendung von iFrames in Verbindung mit dem Sandbox-Attribut (HTML5). Auf diese Weise nehmen Anwendungen externe Inhalte in die Ansicht auf, ohne dass der Content-Provider JavaScript ausführen, URLs aufrufen oder Cookies lesen muss. Außerdem scheint es sinnvoll, vertrauenswürdige Quellen für ausführbaren JavaScript-Code explizit zu benennen (Content-Security-Policy). JavaScript-Code aus anderen Quellen stellt dann keine Bedrohung mehr dar, denn der Web-Browser des Nutzers führt diese nicht mehr aus.

 

Grundsatz 10: Bei der Auswahl eines Partners die Augen offen halten

Um Funktionalitäten in Anwendungen zu implementieren, verwenden Softwareentwickler häufig Softwarekomponenten von Drittanbietern. Bei dem Gebrauch von Programmbibliotheken, Plugins und Add-Ons anderer Anbieter oder von Open-Source-Projekten sind diese auf ihre Robustheit und Sicherheit zu testen sowie die entsprechenden Lizenzbestimmungen zu überprüfen. Module externer Anbieter weisen manchmal technische Schwachstellen auf, die bei ihrer Integration neue zusätzliche Angriffsvektoren liefern. Auch wenn die eigenen Entwicklungen keine Schwachstellen aufweisen, besteht die Möglichkeit einer Kompromittierung des Systems durch unsichere Module und damit einer Gefahr für die Kundendaten.

Wenn externe Geräte eine Bedrohung für Nutzer darstellen, bedeutet dies auch einen Image-Schaden für den Kunden. So ist die Herkunft von Schadcode für viele Nutzer nicht direkt nachvollziehbar und problemlos mit den Kundenanwendungen in Verbindung zu bringen. Softwareentwickler sollten daher alle möglichen Sicherheitsvorkehrungen treffen, alle Fremdmodule vor der Verwendung überprüfen und nur solche aus vertrauenswürdigen Quellen einsetzen.

Genauso wichtig wie die Robustheit und Sicherheit von Fremdmodulen ist die Einhaltung der entsprechenden Lizenzbestimmungen:

  • Darf die Anwendung das Modul verwenden?
  • Welche Folgen und Verpflichtungen ergeben sich aus der Nutzung?

 

Tipps für die Entwicklung:

Die Vertrauenswürdigkeit der Quelle sowie die Robustheit und Sicherheit der Bibliotheken sind vom Programmierer vor der Verwendung von Fremdmodulen zu überprüfen. Erste Hinweise finden sich oft in Foren oder Mailinglisten für die Meldung von Bugs oder Fehlern:

  • Wurden in der Vergangenheit viele Fehler gemeldet?
  • Gibt es bekannte Sicherheitsschwachstellen?
  • Wie wurde bisher mit Fehlermeldungen und der Sicherheit umgegangen?
  • Stehen regelmäßige Patches und Updates bereit?
  • Befindet sich das Modul noch in der Weiterentwicklung oder liegt die Herausgabe der letzten Version schon lange zurück?

Vor dem Einsatz von Fremdmodulen prüfen Entwickler mit der Compliance-Abteilung die entsprechenden Lizenzbestimmungen. Auch bei Versionsänderungen, beispielsweise nach der Aktualisierung eines Fremdmoduls ist zu testen, ob Änderungen an der Lizenz negative Auswirkungen haben. Nur die neusten und stabilsten Versionen leisten einen sicheren Schutz. Darüber hinaus binden Softwareentwickler die Module in das Patch-Management ein, sodass die Prüfung der Aktualität der Version regelmäßig erfolgt.

 

Pierre Gronau ist Inhaber der 2011 gegründeteten Gronau IT Cloud Computing GmbH mit Firmensitz in Berlin. Seit über 20 Jahren arbeitet er für namhafte Unternehmen als Senior IT-Berater mit umfangreicher Projekterfahrung. Zu seinen Kompetenzfeldern gehören Server-Virtualisierungen, moderne Cloud- und Automationslösungen sowie Informationsschutz.

 

Quellen:

[1] https://de.wikipedia.org/wiki/CRUD

Victoria Krautter


Leave a Reply