Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Geleitwort
Vorwort
1 Hello iPhone
2 Grundlagen
3 Views und Viewcontroller
4 Alles unter Kontrolle
5 Daten, Tabellen und Controller
6 Models, Layer, Animationen
7 Programmieren, aber sicher
8 Datenserialisierung und Internetzugriff
9 Jahrmarkt der Nützlichkeiten
A Sicherer Entwicklungszyklus
Stichwort

Download:
- ZIP, ca. 49,9 MB
Buch bestellen
Ihre Meinung?

Spacer
Apps programmieren für iPhone und iPad von Klaus M. Rodewig, Clemens Wagner
Das umfassende Handbuch
Buch: Apps programmieren für iPhone und iPad

Apps programmieren für iPhone und iPad
Galileo Computing
1000 S., geb., mit DVD
39,90 Euro, ISBN 978-3-8362-1915-0
Pfeil 7 Programmieren, aber sicher
Pfeil 7.1 iOS und Hardware
Pfeil 7.2 Bedrohungen, Angriffe, Sicherheitslücken und Maßnahmen
Pfeil 7.2.1 Arten von Sicherheitslücken
Pfeil 7.3 Threat Modeling
Pfeil 7.3.1 Erstellen eines Datenflussdiagramms
Pfeil 7.3.2 STRIDE
Pfeil 7.3.3 Generische Design-Grundsätze
Pfeil 7.3.4 Threat Modeling aus der Tube – das Microsoft SDL Threat Modeling Tool
Pfeil 7.4 Sichere Programmierung in der Praxis
Pfeil 7.4.1 Authentisierung
Pfeil 7.4.2 Keychain
Pfeil 7.4.3 Jailbreak-Erkennung
Pfeil 7.4.4 Verzeichnisse und Dateiattribute
Pfeil 7.4.5 Event-Handling
Pfeil 7.4.6 Screenshots
Pfeil 7.4.7 Sorgfältiger Umgang mit der Bildschirmsperre
Pfeil 7.4.8 Struktur und Ordnung im Sandkasten
Pfeil 7.5 iCloud
Pfeil 7.5.1 Denkanstöße
Pfeil 7.5.2 iCloud in der Praxis
Pfeil 7.5.3 Key Value Storage
Pfeil 7.5.4 Verschlüsselung in der Cloud

Galileo Computing - Zum Seitenanfang

7.3 Threat ModelingZur nächsten Überschrift

Sie wissen jetzt, wie man Bedrohungen in Bedrohungsbäumen darstellt. Nehmen Sie sich das Konzept Ihrer nächsten App, und erstellen Sie alle Bedrohungsbäume, die Ihnen einfallen. Wenn Sie jetzt zu den 99 % aller Menschen gehören, denen mit Mühe ein oder zwei Bedrohungen einfallen, dann sind Sie in guter Gesellschaft. Ohne weiteres Hilfsmittel aus dem Blauen heraus Bedrohungen identifizieren zu wollen ist ähnlich schwierig, wie auf Befehl hin lustig zu sein – auch wenn Karnevalisten es Jahr für Jahr vergeblich versuchen und ihre Trauer über den sich nicht einstellenden Humor mit Alkohol ertränken.

Um dem Problem der Einfallslosigkeit zu begegnen, könnten Sie es den Karnevalisten gleichtun und sich volllaufen lassen. Das erhöht zwar nicht das Sicherheitsniveau Ihrer App, beschert Ihnen aber zumindest einen kurzweiligen Abend – und einen dicken Kopf am Tag danach.

Wir raten Ihnen allerdings, sich entweder einen Security-Experten einzukaufen oder sich einer Methodik zu bedienen, die Sie strukturiert durch den Prozess der Bedrohungsanalyse führt. Diese Methode nennt sich Threat Modeling – das Modellieren von Bedrohungen. Bekannt gemacht hat diese Methode die Firma Microsoft, indem sie Threat Modeling als integralen Bestandteil des Secure Development Lifecycle implementiert hat.

Ursprünglich stammt das Threat Modeling wie viele große Erfindungen der Menschheit aus dem militärischen Bereich. Ende der 1990er-Jahre wurde es von der US-Army und der britischen Armee entwickelt. Mittlerweile ist es als Methodik zur Risikoanalyse in die Norm AS/NZS 4360 integriert, seit 2005 ist es Bestandteil des CVSS (Common Vulnerability Scoring System), und obendrein ist es Bestandteil von OCTAVE, der Operationally Critical Threat, Asset, and Vulnerability Evaluation, einem Ansatz zum Management von Informationssicherheitsrisiken des Software Engineering In-stitute der Carnegie Mellon University.

Der von Microsoft verwendete Ansatz beim Threat Modeling basiert auf der Idee, eine Applikation (ein System, eine Infrastruktur etc.) anhand eines Datenflussdiagramms (DFD) zu modellieren. Der Gedanke dahinter ist, dass Angriffe nur dort möglich sind, wo Daten in ein System gelangen bzw. ein System verlassen. Modelliert man den Fluss der Daten durch eine Anwendung, muss man »lediglich« an allen relevanten Stellen überlegen, welche Bedrohungen dort wirken können.

Das Threat Models wird erstmalig in der Design-Phase der Entwicklung erstellt, also bevor überhaupt eine einzige Zeile Code programmiert wird. Die Überlegung dahinter ist, dass es wesentlich günstiger ist, Sicherheitslücken so früh wie möglich im Entwicklungsprozess zu identifizieren. Denn je später eine Sicherheitslücke gefunden wird, desto teurer ist es, sie zu schließen.

Insbesondere ist das Threat Modeling auch dazu geeignet, Designfehler zu finden, eine Fehlerklasse, die sich mit automatischen Tools zur Code-Analyse nicht identifizieren lassen. Und eine auf einem Designfehler beruhende Sicherheitslücke zu schließen kann extrem teuer oder gar unmöglich sein.

Die Geschichte vom Backup-Monster

Der Nichtmathematiker der beiden Autoren dieses Buches bekam vor einigen Jahren den Auftrag eines Kunden – nennen wir ihn der Einfachheit halber »Backup-Monster« –, seine bereits im Betrieb befindliche Software für Online-Backups auf Sicherheitslücken hin zu untersuchen.

In einer Zeit, als jeder beim Begriff Cloud noch in den Himmel guckte, wollte Backup-Monster seinen Kunden mit der Software die Möglichkeit geben, automatisiert Backups von ihren Rechnern auf einen Server von Backup-Monster im Internet zu spielen. Natürlich wurde mit AES256-Verschlüsselung geworben und damit, dass die Daten der Kunden absolut sicher seien und selbst von Backup-Monster nicht entschlüsselbar abgelegt würden.

Zum Zeitpunkt der Untersuchung hatte Backup-Monster einige Hundert bis tausend Kunden, die den Service fleißig nutzten und bereits mehrere Terabyte auf dem Server gesichert hatten. Beim Audit der Software kam dann heraus, dass Architekten und Programmierer gegen alle kryptografischen Regeln verstoßen hatten und die Software schlichtweg so offen wie ein Scheunentor war. Die Verstöße waren allesamt im Design angesiedelt (falscher Algorithmus, falsche Verschlüsselungsart, falsche Authentisierung).

Das Ergebnis war, dass Backup-Monster seine Software von Grund auf neu planen und schreiben musste. Denn bei einer Backup-Software hat die Verschlüsselung unmittelbaren Einfluss auf die Art und Geschwindigkeit der Datensicherung und lässt sich nicht durch den Austausch eines einzelnen Moduls ändern.

Da die Änderungen nicht nur Interna der Software betrafen, sondern auch die Kommunikation mit dem Server und insbesondere die Ablage der Backup-Daten auf dem Server, sind mit dem Update auf einen Schlag alle auf dem Server liegenden Backups unbrauchbar geworden. Backup-Monster hatte neben der Erstellung einer neuen Software also auch noch die unangenehme Aufgabe, allen Kunden mitzuteilen, dass ihre Backups sich in kleine Logikwölkchen aufgelöst hatten – und dass nicht ausgeschlossen werden konnte, das irgendwer unbefugt auf diese Daten zugegriffen hat.

Neben diesem Image-Schaden, der Backup-Monster viele Kunden gekostet hat, haben sich die Kosten für die Erstellung der Software nahezu verdoppelt, da das komplette Design neu erstellt und anschließend implementiert werden musste.

Neben der vorstehenden Anekdote veranschaulicht der NIST-Report »The Economic Impacts of Inadequate Infrastructure for Software Testing« aus dem Jahr 2002 sehr deutlich den Zusammenhang zwischen dem Zeitpunkt, zu dem ein Fehler gefunden wird, und den Kosten, um ihn zu beheben, wie Abbildung 7.2 zeigt (das NIST ist das US-amerikanische Institut für Standardisierung: das National Institute of Standards and Technology).

Abbildung

Abbildung 7.2 Die Kosten für die Fehlerbehebung in Software steigen umso mehr, je später der Fehler entdeckt wird.


Galileo Computing - Zum Seitenanfang

7.3.1 Erstellen eines DatenflussdiagrammsZur nächsten ÜberschriftZur vorigen Überschrift

Abbildung 7.3 zeigt ein einfaches Datenflussdiagramm (DFD) für eine Banking-App, eine App also, die für den Zugriff auf Kontodaten bei einer Bank gedacht ist. Dieses Diagramm zeigt die App und ihre Kommunikationsbeziehungen. Es enthält noch keine näheren Informationen darüber, wie die App intern strukturiert ist. Ein Datenflussdiagramm dieser Detailtiefe bezeichnet man als Kontextdiagramm, und ein Kontextdiagramm ist die Grundlage eines Threat Models.

Abbildung

Abbildung 7.3 Kontextdiagramm einer Banking-App

Die nächste Ebene des Datenflussdiagramms, die Ebene 1, zeigt die einzelnen Module der App (siehe Abbildung 7.4). Je nach Komplexität von Architektur oder App lässt sich das Datenflussdiagramm in weiteren Ebenen immer mehr verfeinern. Für die meisten Fälle genügen die Ebenen 0 und 1 aber vollkommen, denn wie Sie gleich sehen werden, lassen sich aus Abbildung 7.3 und Abbildung 7.4 schon alle für den Programmierer relevanten Bedrohungen ermitteln, die gegen die Banking-App wirken können.

Abbildung

Abbildung 7.4 Ebene 1 der Banking-Applikation im Datenflussdiagramm

Bevor es an die Analyse des Datenflussdiagramms geht, ist noch ein kurzer Abstecher in die Formalitäten-Ecke notwendig, denn Sie werden wissen wollen, aus welchen Elementen ein Datenflussdiagramm überhaupt bestehen kann respektive was die vorstehenden Abbildungen überhaupt bedeuten.

Ein Datenflussdiagramm (DFD) kann aus den folgenden Elementen bestehen:

  • Entität
  • Prozess
  • Prozessgruppe
  • Datenspeicher
  • Datenfluss
  • Trust Boundary

Im Folgenden sehen wir uns diese Elemente genauer an, bevor wir unsere Beispiel-App analysieren.

Entität

Eine Entität repräsentiert einen Akteur. Ein Akteur ist dadurch gekennzeichnet, dass er Aktionen ausführt, ohne dabei Daten zu verarbeiten. Ein Akteur erzeugt oder konsumiert Daten, verarbeitet sie aber nicht, zumindest nicht in einem für die sicherheitstechnische Analyse zu beachtenden Rahmen – ganz im Unterschied zu einem Prozess. In der Fachsprache bezeichnet man daher eine Entität im DFD als Quelle (erzeugt Daten) oder Senke (konsumiert Daten).

Abbildung

Abbildung 7.5 Entität im DFD

Beispiele für Entitäten sind:

  • Benutzer
  • Server
  • Client
  • Internet
  • Applikation
  • www.galileopress.de
  • Clemens Wagner

Prozess

Im Gegensatz zu einer Entität ist ein Prozess dadurch gekennzeichnet, dass er Daten verarbeitet. Das bedeutet, dass ein Prozess mindestens einen Dateneingang (Entry Point) und mindestens einen Datenausgang (Exit Point) besitzen muss. Ein Prozess kann niemals Quelle oder Senke in einem DFD sein. Die Daten, die ein Prozess verarbeiten soll, müssen von einem anderen Objekt zugeführt werden, und die verarbeiteten Daten müssen an ein anderes Objekt abgegeben werden.

Abbildung

Abbildung 7.6 Prozess im DFD

Beispiele für einen Prozess sind:

  • App
  • XML-Parser
  • Authentisierungsmodul einer App
  • Webserver
  • I/O-Controller

Prozessgruppe

Eine Prozessgruppe ist nichts anderes als das, was der Name suggeriert: eine Gruppe von Prozessen, die der Übersichtlichkeit halber im DFD zu einer Gruppe zusammengefasst sind. Im Regelfall löst sich diese Gruppe in weiteren Ebenen des DFD auf. Eine komplexe App würde man beispielsweise in der Ebene 0 als Prozessgruppe zeichnen und in den folgenden Ebenen dann in Module aufteilen.

Für die Prozessgruppe gelten folglich dieselben Regeln wie für einen Prozess: Sie muss mindestens einen Dateneingang und mindestens einen Datenausgang haben.

Abbildung

Abbildung 7.7 Prozessgruppe im DFD

Datenspeicher

Um mit Gertrude Stein zu sprechen: Ein Datenspeicher ist ein Datenspeicher ist ein Datenspeicher. Der Wortsinn steht für die Bedeutung im DFD. Jeder Ort, an dem Daten gespeichert werden, ist im DFD ein Datenspeicher. Im Gegensatz zu einem Prozess, der möglicherweise auch Daten speichert, und sei es nur temporär, verarbeitet der Datenspeicher aber keine Daten, ist also ein rein passives Element und somit ausschließlich Quelle und/oder Senke von Informationen.

Abbildung

Abbildung 7.8 Datenspeicher im DFD

Beispiele für einen Datenspeicher sind:

  • Datenbank
  • Datei
  • iCloud
  • Heap/Stack
  • Keychain
  • Papier-Ausdruck

Datenfluss

Der Datenfluss symbolisiert den eigentlich Sinn des DFD, nämlich den Weg der Daten durch das modellierte System. Dabei stellt der Pfeil die Richtung des Datenverlaufes von einer Quelle zu einer Senke dar. Ein bidirektionaler Datenfluss kann entweder durch zwei gegenläufige Pfeile oder einen Doppelpfeil dargestellt werden.

Abbildung

Abbildung 7.9 Datenfluss im DFD

Beispiele für einen Datenfluss sind:

  • Netzwerkverkehr
  • Benutzer-Eingabe über GUI
  • IPC
  • Shared Memory
  • RPC-Aufruf

Trust Boundary

Die Vertrauensgrenze oder Trust Boundary ist eine Erweiterung des ursprünglichen DFD für den Anwendungsfall des Threat Modelings. Eine Vertrauensgrenze trennt Bereiche unterschiedlicher Sicherheitsniveaus. Diese sind beim Threat Modeling von besonderem Interesse, da sich dort in der Regel die meisten Angriffsvektoren dadurch ergeben, dass Daten von einem unsicheren Bereich kommen und somit per se als nicht vertrauenswürdig gelten.

Abbildung

Abbildung 7.10 Vertrauensgrenze (Trust Boundary) im DFD

Beispiele für Vertrauensgrenzen sind:

  • Firewall
  • Prozesse mit unterschiedlichen Rechten
  • Kommunikation über Netzwerke
  • unterschiedliche Systeme (z. B. iPhone und iTunes-Rechner)

Analyse der Beispiel-App

Mit den Informationen aus den vorstehenden Absätzen können Sie nun die in Abbildung 7.3 und Abbildung 7.4 modellierte App analysieren. Das Kontextdiagramm zeigt, dass es zwei Entitäten gibt, die die App mit Daten beliefern. Der Benutzer gibt Daten über die GUI ein, und die Bank liefert Daten über das Netzwerk. Die App speichert die Zugangsdaten für das Onlinebanking sowie die Bewegungs- und Transaktionsdaten in jeweils einem Datenspeicher. Zusätzlich ist zu beachten, dass Daten der App beim automatischen Backup über iTunes auf den Rechner des Benutzers gelangen können.

Ebene 1 teilt die App in ihre Hauptmodule auf, sodass der Datenfluss innerhalb der App sichtbar wird. Die Schnittstelle zum iTunes-Backup ist in dieser Ebene entfallen, da sie zur Darstellung im Kontextdiagramm keiner weiteren Detaillierung mehr bedarf.

Mit diesen beiden Diagrammen können Sie nun beginnen, spezifische Bedrohungen für die App zu ermitteln. Dazu ist es sinnvoll, eine Tabelle mit allen Elementen der Datenflussdiagramme zu erstellen, diese Tabelle Zeile für Zeile zu durchlaufen und für jedes Element zu überlegen, welche Bedrohung wirken kann. Entitäten, Prozesse und Datenspeicher lassen sich aufgrund der geringen Anzahl leicht in einer Tabelle wiederfinden. Um die vielen Datenflüsse sinnvoll in eine Tabelle überführen zu können, sollten Sie diese – wie in den beiden Abbildungen – mit Nummern versehen. Es hat sich in der Praxis als hilfreich herauskristallisiert, die Nummern aus der jeweiligen Ebene des DFD, gefolgt von einem Punkt und einer fortlaufenden Nummer, zusammenzusetzen. Damit ist sofort klar, in welcher Ebene sich der Datenfluss befindet, was bei komplexen Diagrammen mit vielen Ebenen extrem hilfreich ist.

Ein Datenflussdiagramm alleine nützt natürlich nicht besonders viel, denn nur dadurch, dass man seine App schön aufgemalt hat, fallen einem keine Bedrohungen ein. Es fehlen noch eine Methode und Quellen für beispielhafte oder häufig vorkommende Sicherheitslücken, die man als Hilfestellung verwenden kann.

Informationsquellen zu Sicherheitslücken

Es gibt drei wichtige Quellen, die Informationen über Sicherheitslücken in IT-Systemen sammeln. Die erste und bei Programmierern wohl bekannteste ist das Open Web Application Security Project (OWASP) [http://www.owasp.org]. OWASP ist ein freies, aus der Community heraus entstandenes Projekt, das sich ursprünglich nur mit der Sicherheit von Web-Applikationen beschäftigt hat. Daraus ist in der Zwischenzeit aber wesentlich mehr geworden: Es gibt mittlerweile sogar ein OWASP Mobile Security Project, das aber noch sehr in den Kinderschuhen steckt und daher noch keine Relevanz für die Praxis besitzt.

OWASP, das im Übrigen durch eine gemeinnützige Organisation gleichen Namens getragen wird, veröffentlicht regelmäßig eine Liste der 10 häufigsten Sicherheitslücken in Web-Applikationen, die OWASP Top 10 [http://goo.gl/AL77v]. Neben einigen, rein web-bezogenen Sicherheitslücken sind die OWASP Top 10 auch für iOS-Programmierer ein wichtiger Ratgeber, denn kaum eine App kommt heutzutage ohne Kommunikation mit dem Internet aus, und obwohl das Frontend eine App und kein Browser ist, lauern dieselben Gefahren, die in einer Web-Applikation lauern können, auch bei der Programmierung einer App, die mit Servern im Internet kommuniziert. Das ist Grund genug, einen kurzen Blick auf die OWASP Top 10 zu werfen (Version 2010).

Eine detaillierte Erläuterung der OWASP Top 10 und der darin aufgeführten Sicherheitslücken würde locker ein eigenes Buch füllen, daher möchten wir Sie an dieser Stelle auf das sehr ausführliche OWASP-Dokument verweisen. [http://goo.gl/AL77v] Wir werden aber im weiteren Verlauf des Kapitels bei der Ausarbeitung des Threat Models auf einzelne Sicherheitslücken aus der Top 10 zu sprechen kommen, insbesondere auf A1, A7 und A9.

Tabelle 7.1 Die OWASP Top 10

ID Thema Bedrohung

A1

Injection

Ein Angreifer kann Befehle in einen dafür nicht vorgesehenen Datenstrom injizieren.

A2

Cross Site Scripting

Ein Server leitet schädliche Eingaben (Scripte) eines Angreifers ungefiltert an einen Benutzer weiter.

A3

Authentisierung & Session Management

Ein Angreifer kann Anmelde- oder Session-Mechanismen umgehen oder manipulieren und so auf Daten anderer Benutzer zugreifen.

A4

Unsichere Referenzen

Ein Angreifer kann auf ungesicherte Objekte zugreifen (Dateien, URL etc.).

A5

Cross Site Request Forgery

Ein Angreifer kann Aktionen im Benutzerkontext anderer Benutzer ausführen lassen.

A6

Fehlkonfiguration

Fehler in Konfiguration und Betrieb der Betriebsplattform führen zu Sicherheitslücken.

A7

Unsichere Kryptografie

Ein Angreifer kann auf nicht oder fehlerhaft verschlüsselte Daten zugreifen.

A8

Mangelhafter URL-Zugriffsschutz

Ein Angreifer kann einen nur auf Verbergen von URLs basierenden Zugriffsschutz umgehen.

A9

Unzureichende Absicherung der Transportschicht

Die Kommunikation zwischen den Netzwerk-Teilnehmern ist nicht ausreichend abgesichert und kann von einem Angreifer abgehört werden.

A10

Ungeprüfte Weiterleitungen

Ein Angreifer kann das Ziel von URL-Weiterleitungen manipulieren und damit Opfer auf falsche Seiten locken (z. B. Phishing-Angriffe).

Eine weitere gute Informationsquelle ist die Liste der 25 gefährlichsten und häufigsten Software-Fehler, die Top 25 Most Dangerous Software Errors [http://cwe.mitre.org/top25/]. Herausgeber ist die MITRE Cooperation in Zusammenarbeit mit dem SANS Institute. MITRE ist eine US?amerikanische Forschungsorganisation, und das SANS Institute (SANS steht für SysAdmin, Networking, Security) ist ein genossenschaftlicher Zusammenschluss von IT-Fachleuten mit Fokus auf IT-Sicherheit.

Die MITRE Cooperation pflegt seit vielen Jahren eine öffentlich verfügbare Liste von Sicherheitslücken in IT-Systemen. Diese Liste mit dem Namen CVE (was für Common Vulnerabilites and Exposures steht) ist ein Industriestandard für die eindeutige Bezeichnung von Sicherheitslücken. Aus der CVE-Liste und den Erfahrungen des SANS (und weiterer IT-Sicherheitsunternehmen und -fachleute) entsteht jährlich die besagte Liste der 25 schlimmsten Software-Sicherheitslücken. Im Gegensatz zu den OWASP Top 10 ist diese Liste nicht primär auf die Sicherheit von Web-Anwendungen fokussiert, sondern auf IT-Systeme im Allgemeinen. Die meisten Elemente der OWASP Top 10 finden sich daher auch in dieser Liste wieder, wobei aus Konfigurationsfehlern resultierende Sicherheitslücken (OWASP A6) kein Bestandteil der Top 25 sind.

MITRE und die Hacker

Die MITRE Cooperation war nicht immer ein Aushängeschild für IT-Sicherheit. Ganz im Gegenteil. Der bekannte KGB-Hack [https://secure.wikimedia.org/wikipedia/de/wiki/KGB-Hack] Ende der 1980er-Jahre lief zu großen Teilen über ungesicherte Systeme der MITRE Cooperation. Und wie es auch heute noch typisch für Institutionen ist, die man auf die Sicherheit ihrer IT-Systeme anspricht, hat auch die MITRE Cooperation damals lange abgestritten, ein Problem zu haben – so lange, bis es sich nicht mehr leugnen ließ.

Um Ihnen für den weiteren Verlauf des Kapitels weitere potenzielle Sicherheitslücken aufzuzeigen, finden Sie nachfolgend die Top 25 von MITRE und SANS aus dem Jahr 2011 samt einer kurzen Erläuterung, denn die Grundlage eines erfolgreichen Threat Models und der sicheren Programmierung ist die Kenntnis der wichtigsten Sicherheitslücken. Wo es dem Verständnis und der Wahrheitsfindung dient, sind einige Code-Beispiele eingefügt. Da alle aufgeführten Sicherheitslücken in Internet und Literatur bereits vielfach in epischer Breite und beliebiger Detailtiefe beschrieben sind, sind die nachfolgenden Erläuterungen so kurz wie möglich gehalten, denn Sie möchten ja iOS-Apps programmieren und kein Fachmann für IT-Sicherheit werden.

Top 1: SQL Injection

Ein Angreifer kann SQL-Befehle mit einer Eingabe in die Kommunikation einschleusen und diese Befehle somit auf der Datenbank zur Ausführung bringen. Das Einschleusen erfolgt über die Benutzerschnittstelle, nicht über die Manipulation des Netzwerkverkehrs. SQL Injection ist daher ein Problem der Eingabe-Validierung. Benutzer-Eingaben müssen grundsätzlich auf schädliche Sonderzeichen hin untersucht werden, und diese Sonderzeichen müssen anschließend entfernt werden.

Eine beispielhafte SQL-Abfrage, mit der die Existenz eines Benutzers und die Richtigkeit seines Passwortes abgefragt wird, ist die folgende:

select * from tbl.user where user=’foo’ and pw=’bar’;

Gibt es eine Zeile in der Tabelle tbl.user, bei der die Spalte user den Wert foo und die Spalte pw den Wert bar hat, ist der Benutzer vorhanden, das Passwort korrekt und die Anmeldung somit erlaubt.

Das SQL-Statement selber steht fest, und die Werte für die Spalten user und pw kommen aus Benutzer-Eingaben. In Objective-C abgebildet, würde das Ganze wie folgt aussehen (die beiden NSString-Objekte user und pass simulieren in dem Beispiel die Benutzer-Eingaben):

NSString *user = @"foo";
NSString *pass = @"bar";
NSString *query = [NSString stringWithFormat:Zeilenumbruch
@"select * from tbl.user where user='%@' Zeilenumbruch
and pass='%@'", user, pass];
NSLog(@"query: %@", query);

Listing 7.1 SQL-Befehl zur Autorisierung eines Benutzers

Das Ergebnis in der Konsole ist eine gültige SQL-Abfrage:

query: select * from tbl.user where user='foo' and pass='bar'

Gibt ein böswilliger oder neugieriger Benutzer statt seines regulären Passwortes aber einen simplen SQL-Befehl ein ...

NSString *pass = @"' or 1=1--";

... hat die ganze Abfrage jetzt eine ganz andere Bedeutung:

query: select * from tbl.user where user='foo' Zeilenumbruch
and pass='' or 1=1--'

Diese Abfrage gibt als Ergebnis die Zeile der Tabelle tbl.user zurück, bei der die Spalte user den Wert foo hat, das Passwort leer ist oder die Bedingung 1=1 erfüllt ist. Und die letzte Bedingung ist immer erfüllt, denn 1 ist grundsätzlich immer 1! Ein Angreifer kann sich auf diese Weise also ohne Kenntnis des Passwortes am System anmelden. Und der Grund dafür ist, dass der Programmcode die Eingabe des Benutzers ungefiltert in SQL-Befehle integriert und an die Datenbank schickt.

Die erste Maßnahme gegen SQL Injection ist daher die Validierung der Benutzer-Eingabe auf schädliche Sonderzeichen – besonders auf das einfache Hochkomma, das Minus-Zeichen und das Semikolon.

Die zweite Maßnahme ist die Verwendung von Prepared Statements, sofern die jeweilige Datenbank dies unterstützt. Und dann verfügen die meisten Datenbank-Bibliotheken über Abfragemethoden, die den Input-String direkt auf schädliche Sonderzeichen filtern.

Wenn Sie die iOS-eigene Datenbank SQLite verwenden, können Sie problemlos Prepared Statements [https://www.sqlite.org/c3ref/stmt.html] verwenden, genauso wie bei vielen anderen gängigen Datenbanksystemen.

Whitelisting vs. Blacklisting

Zur Validierung von Eingabe-Daten gibt es zwei grundlegende Ansätze. Das Whitelisting definiert explizit die Zeichen, die erlaubt sind. Alle anderen Zeichen werden verworfen. Das Blacklisting definiert explizit die Zeichen, die verboten sind.

Sie sollten grundsätzlich bei allen sicherheitsrelevanten Auswahlverwahren das Whitelisting verwenden. Denn nur damit stellen Sie sicher, dass Sie nicht durch eigene Nachlässigkeit etwas übersehen oder von einem findigen Angreifer ausgetrickst werden.

Top 2: OS Injection

Analog zur SQL Injection kann ein Angreifer Betriebssystem-Befehle in eine Benutzer-Eingabe schleusen und diese Befehle auf dem System zur Ausführung bringen, wenn die Benutzer-Eingabe ungefiltert verarbeitet wird. Darüber hinaus gibt es gängige Injection-Angriffe auch noch gegen LDAP-Systeme und XML-Parser.

Die Maßnahme gegen diese Art von Angriffen ist analog zur SQL Injection die strikte Filterung von Benutzer-Eingaben und, sofern möglich, die Einrichtung weiterer Filtermöglichkeiten auf dem Weg zum Backend.

Top 3: Buffer Overflow

Ein Angreifer kann die fehlende Längenüberprüfung einer Funktion ausnutzen und Speicher-Überläufe provozieren, um z. B. eigenen Code zur Ausführung zu bringen. Besonders bekannt sind Angriffe gegen stackbasierte Buffer Overflows, die durch die Verwendung unsicherer C-Funktionen die Rücksprungadresse einer Funktion manipulieren und den Programmfluss dadurch auf Code umleiten, der vom Angreifer kontrolliert wird.

Ein simples Beispiel für einen Angriff dieser Art zeigt der folgende C-Code:

char boo[4];
strcpy(boo, "AAAAAAAAAA");
NSLog(@"Peng!");

Listing 7.2 Simpler Buffer Overflow

Das Problem bei Listing 7.2 besteht darin, dass die Funktion strcpy keine Längenüberprüfung ihrer Parameter durchführt. So führt die Zuweisung von zehn Zeichen an ein nur vier Zeichen großes Array zu keiner Fehlermeldung während der Übersetzung. Zur Laufzeit überschreibt diese Zuweisung dann aber gnadenlos den Stack-Speicher – das Programm stürzt ab. Das Problem liegt also sowohl in der fehlenden Überprüfung durch die Sprache als auch in der falschen Verwendung der Funktion durch den Programmierer.

Neben stackbasierten Buffer Overflows gibt es auch solche, die auf dem Heap stattfinden. Grundsätzlich bezeichnet der Begriff Buffer Overflow aber alle Fehler, bei denen zu viele Daten in einen Puffer geschrieben werden.

Eine generische Maßnahme gegen Buffer Overflows gibt es nicht. Wenn Sie sich in der iOS-Programmierung nur auf der Ebene von Cocoa Touch bewegen, haben Sie keine Probleme mit Buffer Overflows. Sobald Sie aber in die C-Welt hinabtauchen, stehen Ihnen all die schönen Sicherheitslücken zur Verfügung, die C und seine Im-plementierung bietet. Apple hält zu diesem Thema den Secure Coding Guide bereit, der auf die Grundlagen der sicheren C-Programmierung eingeht. Werfen Sie im Bedarfsfall einen Blick dort hinein. Grundsätzlich aber gilt, insbesondere für Programmierer ohne C-Erfahrung: Verwenden Sie in erster Linie den höchstmöglichen API-Level für Ihre Programmierung.

Top 4: Cross Site Scripting

Beim Cross Site Scripting (XSS) kann ein Angreifer fehlende Ein- und Ausgabe-Validierung dazu nutzen, eigenen Schadcode über eine für XSS anfällige Applikation an Opfer liefern und dort zur Ausführung bringen zu lassen. Diese Art des Angriffs richtet sich gegen Clients, die in der Lage sind, JavaScript oder anderen aktiven Code auszuführen. Ein solcher Client ist z. B. jeder moderne Browser.

Beim XSS fungiert die Applikation mit der entsprechenden Sicherheitslücke nur als Mittelsmann. Anfällig sind alle Applikationen, die Benutzer-Eingaben ungefiltert wieder ausgeben. Akzeptiert beispielsweise die Suchfunktion einer Web-Applikation beliebige Zeichen als Suchtext und gibt sie diese Zeichen ungefiltert mit den Suchergebnissen wieder aus, kann ein Angreifer JavaScript-Code an die Suchfunktion senden, der dann vom Webserver wieder ausgegeben wird. Der Browser interpretiert das JavaScript dann korrekt als JavaScript und führt den Code aus – fertig ist der Angriff. Alles was der Angreifer tun muss, ist, seinen Opfern Links auf die Suchfunktion mit dem entsprechenden Schadcode zu senden. Klickt ein Opfer auf den Link, wird der Schadcode ausgeführt.

Die persistente Variante des XSS besteht darin, dass ein Angreifer Schadcode persistent in einer Applikation abspeichern kann. Ein Beispiel ist ein web-basiertes Forum, in dem ein Angreifer seine Postings neben normalem Text obendrein auch noch mit JavaScript-Code füllen kann. Jeder Benutzer, der sich anschließend ein solches Posting ansieht, hat den Schadcode dann in seinem Browser.

Abhilfe gegen XSS schafft das sogenannte Escapen von Sonderzeichen. Damit wandeln Sie die Sonderzeichen in der Benutzer-Eingabe in unschädliche Varianten um, die vom Browser nicht als Code-Tags interpretiert werden. Allerdings ist beim XSS nicht nur die Eingabe-, sondern auch die Ausgabe-Seite relevant, denn Sie sollten nie davon ausgehen, dass alle Daten, die an den Benutzer gehen, aus vertrauenswürdiger Quelle stammen. Wenn Sie, um beim Beispiel des Forums zu bleiben, zwar alle Benutzer-Eingaben auf schädliche Zeichen prüfen, sich aber über importierte RSS-Feeds XSS-Angriffe einhandeln, hilft Ihnen nur die Validierung der Ausgabe-Daten.

Das Escapen von Sonderzeichen ist mit Cocoa Touch praktischerweise ganz einfach, wie der folgende Code-Schnipsel zeigt:

NSString *evilString = @"c:\foobar<script>alert(23)</script>";
NSLog(@"evilString: %@", evilString);
NSString *sanitizedString =[evilStringZeilenumbruch
stringByAddingPercentEscapesUsingEncoding:Zeilenumbruch
NSUTF8StringEncoding];
NSLog(@"sanitizedString: %@", sanitizedString);

Listing 7.3 Escapen von Sonderzeichen

Der NSString evilString enthält neben sonstigen Sonderzeichen eckige Klammern, die dazu verwendet werden, Code für den Browser zu kennzeichnen. In der NSLog-Ausgabe sehen Sie, dass obendrein der Backslash zu einem Umbruch geführt hat, da er eine Formatierungsanweisung enthält:

2012-08-01 20:00:37.938 Top25Foo[32685:c07] evilString: c:Zeilenumbruch
oobar<script>alert(23)</script>

Der über die Methode stringByAddingPercentEscapesUsingEncoding ins UTF8-Format konvertierte NSString sanitizedString enthält hingegen nur noch sogenannte escapte Zeichen. Die stellt ein Browser zwar als die ursprünglichen Zeichen dar, interpretiert sie aber nicht mehr als Code-Tags:

2012-08-01 20:00:37.939 Top25Foo[32685:c07] sanitizedString:Zeilenumbruch
c:%0Coobar%3Cscript%3Ealert(23)%3C/script%3E

Auf Ein- und Ausgabe angewendet, sorgt die Funktion also dadurch für Sicherheit, dass darüber keine XSS-Schwachstelle entstehen kann.

Top 5: Fehlende Authentisierung für sicherheitsrelevante Funktionen

Bei diesem Fehler handelt es sich weniger um einen Implementierungs- als vielmehr um einen Designfehler. Er besteht darin, dass der Zugriff auf sicherheitsrelevante Funktionen ohne wirksame Authentisierung möglich ist. Denken Sie bei der Implementierung sicherheitsrelevanter Funktionen daher immer daran, diese gut zu schützen. Wenn Ihre App beispielsweise einen Upload-Service für Dateien anbietet, dann wäre es ein typischer Fehler dieser Art, wenn die Upload-Funktion immer aktiviert ist und jeder ohne Authentisierung die bereits hochgeladenen Dateien wieder herunterladen kann. Damit würden Sie in jedem öffentlichen Hotspot viele Freunde finden.

Top 6: Fehlende Autorisierung

Dieser Fehler liegt vor, wenn es entweder keine Autorisierungsfunktion gibt oder wenn eine vorhandene Autorisierungsfunktion fehlerhaft arbeitet. Wenn Ihre App beispielsweise im Kontext einer Client-Server-Architektur ein Rollenmodell verlangt, um verschiedene Benutzer und Benutzer unterschiedlicher Privilegierungsstufen zu unterscheiden, dann muss dieses Rollenmodell zum einen vorhanden, zum anderen auch sicher sein. Wenn ein Angreifer durch die Änderung eines Parameters Administratorrechte erlangt und auf die Daten aller Benutzer zugreifen kann, liegt ein Fehler dieser Art vor.

Top 7: Verwendung fest kodierter Geheimnisse

Es kommt ständig vor, dass eine App Geheimnisse speichern muss. Ein Geheimnis kann das Passwort für den Datenbankzugriff im Backend sein, ein Geheimnis kann ein Zertifikat sein, eine Seriennummer etc.

Ganz schlechter Stil – und eben dieser Fehler – ist das feste Einkodieren von Geheimnissen in die App, z. B. als NSString im Quelltext. Zum einen lässt sich ein String ohne Weiteres aus der App wieder auslesen und ist somit allen zugänglich, die diese App in die Hände bekommen. Zum anderen lässt sich ein auf diese Weise gespeichertes Geheimnis nicht ändern – Sie müssten eine neue App übersetzen und verteilen.

iOS bietet zum Speichern von Geheimnissen die Keychain (siehe Abschnitt 7.4.2), daher gibt es zum Glück keine Ausrede dafür, Geheimnisse im Quelltext oder an vergleichbar unglücklicher Stelle zu speichern.

Top 8: Fehlende Verschlüsselung sensibler Daten

Die Überschrift beschreibt die Sicherheitslücke bereits sehr treffend. Gemeint sind damit alle Stellen, an denen personenbezogene oder sensible Daten nicht durch wirksame Verschlüsselung vor unbefugtem Zugriff geschützt werden. Das kann die Ablage im Dateisystem betreffen, die Übertragung im Netzwerk, Einträge in der Keychain etc. In diesem Kapitel werden Sie die iOS-eigenen Mechanismen für die Verschlüsselung von Daten kennenlernen, sodass Ihnen dieser Fehler (hoffentlich) nicht unterlaufen wird.

Top 9: Unsichere Upload-Funktion

Beim Upload von Dateien auf Server kann es passieren, dass die fehlende Überprüfung der hochgeladenen Dateien dazu führt, dass ein Angreifer darüber Schadcode einschleusen kann. Auf einem Webserver kann es beispielsweise passieren, dass ein Angreifer aktiven Code hochlädt (z. B. Java oder PHP) und der Webserver den Code beim Abruf der hochgeladenen Datei ausführt. Damit steht dem Angreifer der Webserver offen.

Auf eine App bezogen, könnte der Fall eintreten, dass eine App eine Server-Schnittstelle öffnet, um den Upload von Dokumenten auf ein iDevice zu ermöglichen. Gelingt es einem Angreifer, über diese Schnittstelle Dateien hochzuladen, die Schadcode oder sonstige Schadroutinen enthalten, öffnet diese App eine veritable Sicherheitslücke. Solch ein Schadcode kann z. B. ein Konfigurationsprofil für iOS sein, das der Angreifer mit dem iPhone Configuration Utility [http://support.apple.com/kb/DL1465?viewlocale=de_DE] erstellt und ahnungslosen Nutzern in öffentlichen Hotspots über die Upload-Funktion der betreffenden App auf ihre iDevices lädt. Öffnet ein Benutzer dann die Datei, installiert sich das Profil, und je nachdem, welche Einstellungen der Angreifer vorgenommen hat, können diese die komplette Funktionsuntüchtigkeit des Gerätes bewirken.

Eine App sollte daher bei der Verwendung einer Upload-Funktion die hochgeladenen Dateien auf Typ und Inhalt prüfen.

Top 10: Sicherheitsrelevante Entscheidungen aufgrund unsicherer Eingaben

Diese Art von Fehler kommt häufig in einer Client-Server-Kommunikation vor. Rufen Sie sich die App aus dem Beispiel der SQL Injection noch einmal ins Gedächtnis. Diese App authentisiert einen Benutzer gegen eine Datenbank. Das heißt, dass der Benutzer nur Zugriff auf die Daten erhält, wenn seine Anmeldedaten in der Datenbank vorhanden sind. Die App führt die Validierung der Benutzer-Eingaben durch, um zu verhindern, dass sich ein Angreifer über eine SQL Injection unbefugten Zugriff zu den Daten verschafft.

Nun ist die App auf dem iDevice aus Sicht des Datenbankservers, der sicher verwahrt in einem Rechenzentrum steht, ein unsicheres System. Daher sollte sich der Server nicht darauf verlassen, dass die Daten, die von der App kommen, vertrauenswürdig sind. Der Angreifer kann die Daten ja auch auf dem Weg von der App zum Server manipulieren, einfach indem er sich mit einem Proxy-Server in die Mitte setzt. Wenn er dann dort eine SQL Injection in den Datenstrom einfügt, kann er die Datenbank kompromittieren. Der Server muss seinerseits also auch Maßnahmen gegen SQL Injection treffen.

Dies entspricht zum einen dem Prinzip Defense in depth (siehe Abschnitt 7.3.3, »Generische Design-Grundsätze«), vermeidet aber den Fehler, dass Daten aus unsicherer Quelle ungeprüft für sicherheitsrelevante Aktionen (in diesem Fall die Authentisierung des Benutzers) herangezogen werden.

Top 11: Ausführung mit nicht benötigten Rechten

Dieser Punkt subsumiert alle Sicherheitslücken, die daraus entstehen, dass Funktionen mit mehr Berechtigungen ausgeführt werden also nötig. Das betrifft bei der App-Entwicklung nicht die App selbst, denn diese bekommt Ihre Berechtigungen von iOS zugewiesen. Um beim Beispiel der SQL Injection zu bleiben, wären nicht benötigte Rechte dann vorhanden, wenn der Datenbankbenutzer, mit dem die App auf die Datenbank zugreift, über Administratorrechte auf der Datenbank verfügt (DB-Admin). Ist dies der Fall, wäre eine SQL Injection fatal, denn dann könnte ein Angreifer auf alle Daten in der Datenbank zugreifen.

Verwendet die App aber einen Datenbankbenutzer, der nur über so viele Rechte verfügt, wie notwendig sind, z. B. ausschließlich über lesenden Zugriff auf die Benutzer-Tabelle, dann hält sich der Schaden in Grenzen.

Top 12: Cross Site Request Forgery

Cross Site Request Forgery (XSRF) ist eine web-spezifische Sicherheitslücke, die bei der App-Programmierung selber nicht auftritt, sondern nur innerhalb einer Web-Applikation. Detaillierte Informationen dazu finden Sie in der Dokumentation des OWASP-Projekts [ https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)].

Top 13: Path Traversal

Beim Path Traversal kann der Zugriff auf eine Ressource über Benutzer-Eingaben manipuliert werden. Ein klassischer Fall ist eine Download-Funktion, bei der ein Angreifer durch geschickte Manipulation von Parametern beliebige Dateien herunterladen kann. Wenn der Zugriff auf Ressourcen schon dynamisch erfolgen muss, sollte er nicht über Benutzer-Eingaben manipulierbar sein. Überdies müssen Pfad-Elemente wie Punkte (.), Slashes (/) und Backslashes (\) aus Benutzer-Eingaben herausgefiltert werden.

Top 14: Download ohne Integritätsprüfung

Eine Sicherheitslücke dieser Art entsteht, wenn eine App Code aus unsicherer Quelle nachlädt (also z. B. aus dem Internet) und diesen Code nicht auf Integrität prüft. Manipuliert ein Angreifer den Code, kann er darüber beliebigen Schadcode einschleusen.

Bei der Programmierung von Apps für den Apple App Store kann dieser Fehler nicht auftreten, da die Apple-Richtlinien das Nachladen von Code verbieten. Eine App mit so einer Funktion würde daher nicht in den Store kommen (falls Apple dies bei der Überprüfung der App bemerkt).

Im Enterprise-Umfeld muss man sich als Programmierer aber nicht an die Apple-Richtlinien halten, sodass eine App beliebigen Code nachladen kann. Denken Sie in diesem Fall immer daran, eine Integritätsprüfung zu implementieren, um sicherzustellen, dass der Code auch der ist, den Sie haben wollen.

Top 15: Fehlerhafte Autorisierung

Die fehlerhafte Autorisierung von Benutzern oder Rollen führt immer wieder zu schweren Sicherheitslücken, die den unbefugten Zugriff auf Ressourcen erlauben. Wenn Ihre App Trust- und Rollenmodelle verwendet, um Benutzer oder Rollen zu autorisieren, müssen Sie darauf achten, dass ein Angreifer den Autorisierungsmechanimsus nicht umgehen kann.

Top 16: Verwendung von Funktionen in unsicheren Bereichen

Sicherheitslücken dieser Art entsprechen denen von Punkt 10, nur dass sie nicht aus der Verwendung von Informationen aus unsicherer Quelle resultieren, sondern aus der Verwendung von Funktionalität aus unsicherer Quelle, z. B. aus der Verwendung eines Frameworks, das Schadroutinen enthält.

Es ist schwierig, Sicherheitslücken dieser Art zu erkennen. Sie haben in Kapitel 2, »Grundlagen«, Kategorien kennengelernt. Es ist z. B. möglich, dass ein Framework über Kategorien die Methode einer Cocoa-Touch-Klasse überschreibt und mit unerwünschten Funktionen anreichert. Wenn Sie dieses Framework in den eigenen Code einbinden, ist diese Kategorie bei allen Klassen vorhanden, die über import-Anweisungen mit dem Framework verbunden sind.

Ein anderer Fall ist das Auslagern von Funktionalität an einen Dienst, z. B. eine Cloud. Wenn Sie nicht zufällig Betreiber dieses Dienstes sind und eine belastbare Aussage über die Sicherheit desselben treffen können, sollten Sie den Dienst als grundsätzlich unsicher betrachten und die entsprechenden Vorkehrungen treffen, um die Gefahren zu minimieren, die aus dieser Annahme resultieren.

Top 17: Fehlerhafte Berechtigungen

Eine Sicherheitslücke dieser Art liegt vor, wenn eine wichtige Ressource nicht ausreichend vor unbefugtem Zugriff geschützt ist. Ein Klassiker sind falsche Dateisystemberechtigungen für sicherheitsrelevante Dateien. Wenn ein Angreifer lesend auf die Datei /etc/shadow in einem Linux-System zugreifen kann, hat er Zugriff auf die Passwort-Hashes aller Benutzer.

Mit solchen Feinheiten haben Sie dank der restriktiven Sandbox von iOS bei der App-Programmierung nicht zu kämpfen, nichtsdestotrotz sollten Sie sich als App-Programmierer immer die Frage stellen, wer Zugriff auf eine Ressource bekommen muss, und den Zugriff grundsätzlich so restriktiv wie möglich gestalten.

Top 18: Verwendung potenziell unsicherer Funktionen

In der Beschreibung von Buffer Overflow (Top 3) haben Sie bereits die C-Funktion strcpy kennengelernt, die aufgrund der fehlenden Überprüfung der Puffer-Länge grundsätzlich unsicher ist. Funktionen solcher Art gibt es einige, und die Verwendung dieser Funktionen führt immer wieder zu schweren Sicherheitslücken.

Darüber hinaus gehört die falsche Verwendung kryptografischer Funktionen bzw. die Verwendung unsicherer kryptografischer Funktionen zu dieser Fehlerklasse. So weist das API-Interface CCCryptor in iOS eine Sicherheitslücke auf, da es zwar standmäßig den CBC-Modus [https://secure.wikimedia.org/wikipedia/de/wiki/Cipher_Block_Chaining_Mode] für symmetrische Algorithmen verwendet, als Initialisierungsvektor aber nur Nullen verwendet. Das führt zu einer unsicheren Verschlüsselung. Die Verwendung von CCCryptor im Standardmodus ist daher ein Beispiel für die Verwendung einer potenziell unsicheren Funktion.

Top 19: Verwendung unsicherer kryptografischer Algorithmen

Neben der Verwendung unsicherer Funktionen ist die Verwendung unsicherer kryptografischer Algorithmen eine weitere typische Quelle von Sicherheitslücken. Sie müssen als Programmierer daher immer prüfen, dass die von Ihnen verwendeten Algorithmen noch als sicher gelten.

Die Verwendung sicherer Algorithmen alleine ist noch kein Garant für Sicherheit. Sie müssen darüber hinaus auch noch auf die korrekte Verwendung achten. Dazu zählen insbesondere die folgenden Punkte:

  • ausreichend lange und starke Schlüssel
  • sichere Ablage von Schlüsselmaterial
  • zufällige Initialisierungsvektoren
  • Verwendung hinreichend zufälliger Zufallszahlen-Generatoren

Top 20: Falsche Berechnung von Puffer-Größen

Dieser Punkt entspricht Punkt 3. Warum der falsche Umgang mit Puffer-Größen zweimal in der Top 25 auftaucht ... gute Frage.

Top 21: Fehlende Begrenzung von Anmeldeversuchen

Ein Weg, unbefugten Zugang zu Systemen zu erlangen, ist das Durchprobieren von Anmeldedaten, der sogenannte Brute-Force-Angriff. Hat eine App oder ein System keinen Mechanismus implementiert, um Brute-Force-Angriffe zu erkennen und zu unterbinden, kann ein Angreifer beliebig viel Zeit damit verbringen, sich Zugang zu verschaffen.

Implementieren Sie daher stets Mechanismen gegen Brute-Force-Angriffe, wenn Sie Authentisierungsfunktionen in Ihrer App haben. Ein gutes Beispiel ist das iPhone selber. Mit aktiviertem Benutzercode haben Sie in der Standardkonfiguration sechs Anmeldeversuche, bevor das Gerät für eine Minute gesperrt wird. Ein angemessen starkes Passwort vorausgesetzt, braucht ein Angreifer schon sehr viel Glück, um dieses in sechs Versuchen zu erraten. Nach weiteren Fehlversuchen sperrt sich das iPhone am Ende für 60 Minuten, bis es sich nach 10 Anmeldeversuchen selber löscht. Die gestaffelte Sperrung ist ein gutes Mittel, um automatisierte Angriffe auszubremsen.

Top 22: Unsichere URL-Weiterleitung

Das Problem unsicherer URL-Weiterleitungen betrifft ausschließlich Web-Anwendungen ist daher für die App-Programmierung nicht von Interesse. Grundsätzlich erlauben unsichere URL-Weiterleitungen einem Angreifer, Opfern Links von vertrauensvollen Institutionen zu schicken, die dann aufgrund einer fehlerhaft implementierten URL-Weiterleitungsfunktion an eine vom Angreifer kontrollierte Webseite weiterleiten, wo den Opfern dann Schadcode untergeschoben wird oder sie Opfer eines Phishing-Angriffs werden.

Top 23: Formatstring-Fehler

Formatstring-Fehler sind eine Erblast aus der C-Programmierung. Sie haben Formatstrings bereits in Kapitel 2 kennengelernt und im weiteren Verlauf des Buches an zahlreichen Stellen verwendet. Formatstrings stellen aufgrund ihrer Natur eine grundsätzliche Gefahr dar: Ein Angreifer kann einen Formatstring, zu dem er die Eingabe liefern kann, durch eigene, eingeschleuste Formatierungsanweisungen dazu bringen, etwas anderes zu tun als vorgesehen – namentlich, unbefugt auf Speicher zuzugreifen. Bei der Verwendung von Formatstrings sollten Sie daher stets darauf achten, dass die Anzahl der Platzhalter der Anzahl der Argumente entspricht und dass Eingaben außerhalb ihres eigenen Kontrollbereichs nicht ungeprüft in einem Formatstring landen.

Top 24: Integer Overflow oder Wraparound

Computer sind folgsame Gesellen, denn sie machen genau das, was man ihnen sagt. Betrachten Sie die folgenden Code-Zeilen:

char foo = 127;
NSLog(@"foo vorher: %i", foo);
foo++;
NSLog(@"foo nachher: %i", foo);

Listing 7.4 Addition von 1 und 127 im Datentyp »char«

int bar = 4294967295;
NSLog(@"bar vorher: %u", bar);
bar++;
NSLog(@"bar nachher: %u", bar);

Listing 7.5 Addition von 1 und 4294967295 im Datentyp »Integer«

int fooBar = 0;
NSLog(@"bar vorher: %u", fooBar);
fooBar--;
NSLog(@"bar nachher: %u", fooBar);

Listing 7.6 Subtraktion von 0 und 1 im Datentyp »Integer«

Die Konsolen-Ausgabe von Listing 7.4 ist die folgende:

2012-08-02 21:06:38.514 Top25Foo[76237:c07] foo vorher: 127
2012-08-02 21:06:38.516 Top25Foo[76237:c07] foo nachher: –128

Was ist passiert? Der Datentyp char ist 8 Bit groß und kann daher 256 verschiedene Werte annehmen. Da es sich hier um ein char mit Vorzeichen handelt (signed), wird ein Bit für das Vorzeichen verbraucht, daher hat char einen Wertebereich von –128 bis 127. Die Addition von 1 zu 127 führt also nicht etwa dazu, dass ein Laufzeitfehler auftritt, sondern der Computer schiebt die Bits einfach weiter: Ein Überlauf findet statt, und das Ergebnis ist –128 [Das liegt an der Binärdarstellung der Werte.]. Wenn dieser Wert in einem Programm zum Regeln einer Motorengeschwindigkeit genutzt wird, hätte der Überlauf fatale Folgen. Lachen Sie jetzt nicht; die europäische Rakete Ariane 5 hat sich bei ihrem Jungfernflug aufgrund eines Überlaufs selber in die Luft gesprengt!

In der Konsolenausgabe zu Listing 7.5 sehen Sie dasselbe Verhalten, diesmal mit einem Integer-Wert:

2012-08-02 21:19:38.561 Top25Foo[77833:c07] Zeilenumbruch
bar vorher: 4294967295
2012-08-02 21:19:38.561 Top25Foo[77833:c07] Zeilenumbruch
bar nachher: 0

Dieses Mal ist der Datentyp ohne Vorzeichen (unsigned). Die Addition von 1 zum maximalen Integer-Wert 4294967296 (32-Bit-Integer) führt zu einem Überlauf, und der Wert steht anschließend auf dem Minimalwert 0.

Das Listing 7.6 zeigt den umgekehrten Fall, die Subtraktion vom Minimalwert bei einem unsignierten 32-Bit-Integer. Der Wert »wrappt«, und heraus kommt der Maximalwert:

2012-08-02 21:19:38.562 Top25Foo[77833:c07] Zeilenumbruch
bar vorher: 0
2012-08-02 21:19:38.563 Top25Foo[77833:c07] Zeilenumbruch
bar nachher: 4294967295

Die Auswirkungen von Integer Overflows können mannigfaltig sein. Im besten Fall führen sie zum Absturz einer App, in schlimmeren Fällen zum Absturz einer Rakete. Achten Sie daher tunlichst darauf, Datentypen zu verwenden, die groß genug für die erwarteten Werte sind. Und vertrauen Sie nicht darauf, dass ein Benutzer nur Werte eingibt, die Sie erwarten. Aber dieses Thema hatten wir ja bereits.

Übrigens, die Verwendung von NSNumber als Wrapper für die primitiven C-Datentypen schützt Sie auch nicht vor Integer Overflows, wie das folgende Code-Beispiel zeigt:

NSNumber *tschar = [NSNumber numberWithChar:257];
NSLog(@"tschar: %i", [tschar charValue]);

Listing 7.7 »NSNumber« mit »char«-Wert 257

Das Ergebnis ist ernüchternd:

2012-08-02 21:31:43.466 Top25Foo[79525:c07] tschar: 1

Cocoa Touch nimmt Ihnen in Sachen Integer Overflows nicht das Denken ab. Denken Sie daran!

Top 25: Verwendung von Hashfunktionen ohne Salz

Die letzte Sicherheitslücke aus der Top 25 ist die Verwendung von Hashfunktionen ohne Salz. Das hört sich nicht lecker an, und es ist auch nicht lecker. Kryptografische Hashfunktionen verwendet man häufig dazu, um Geheimnisse so zu speichern, dass sie nicht mehr wiederhergestellt werden können. Ein Anwendungsfall ist das Speichern von Passwort-Hashes.

Wenn man die Passwörter seiner Benutzer nicht im Klartext speichern möchte, was ja ein ungeheures Missbrauchspotenzial eröffnet, schickt man sie durch eine kryptografische Hashfunktion – eine sogenannte Falltür-Funktion – und speichert nur den daraus resultierenden Hashwert. Aus diesem lässt sich das Passwort nicht mehr zurückrechnen. Um anschließend zu überprüfen, ob ein Benutzer sein Passwort korrekt eingegeben hat, muss man nur die Eingabe durch dieselbe Hashfunktion schicken und das Ergebnis mit dem gespeicherten Hash vergleichen.

Es gibt zwar für aktuelle Hashfunktionen keine Möglichkeit gibt, den Ausgangstext aus dem Hash zurückzurechnen, man kann aber Hashes im Voraus berechnen. [http://www.freerainbowtables.com/de/] Gelangt man dann als Angreifer in den Besitz von Passwort-Hashes, muss man nur noch die erbeuteten Hashes mit den Listen bereits errechneter Hashes vergleichen, um so auf die Passwörter zu kommen.

Nun nehmen die Listen vorausberechneter Hashes schnell viele Terabyte an Platz ein, und die Berechnung ist aufwendig, sodass es nicht für beliebige Texte vorberechnete Listen gibt, sondern nur für Passwörter bestimmter Länge und Komplexität. Da Benutzer gerne einfach zu merkende Passwörter nehmen, ist die Wahrscheinlichkeit sehr groß, dass sich aus einer erbeuten Datenbank die Passwörter über die vorausberechneten Hashes wiederherstellen lassen. Sind darüber hinaus Hashes von verschiedenen Systemen gleich, weiß der Angreifer, dass dort auch die Passwörter gleich sind.

Eine sichere Hashfunktion zeichnet sich dadurch aus, dass sie zwei Bedingungen erfüllt:

  • Unumkehrbarkeit: Aus dem Hashwert darf der Klartext nicht rekonstruierbar sein.
  • Kollisionsfreiheit: Verschiedene Klartexte dürfen nicht denselben Hashwert ergeben.

Um dies zu verhindern, sollte man beim Hashen von Passwörtern (oder anderen Geheimnissen) eine zufällige Zeichenkette vor den eigentlichen Text stellen. Diese Zeichenkette nennt man Salt (Salz), und sie sorgt dafür, dass Angriffe mit vorausberechneten Hashtabellen ins Leere laufen. Das ist wenig Aufwand für viel Sicherheit. Ein guter Tausch.

Zusammenfassung

Falls Sie sich bisher noch nicht mit sicherer Programmierung und typischen Sicherheitslücken auseinandergesetzt haben, werden Sie nun wahrscheinlich den Eindruck gewonnen haben, dass man in der IT-Sicherheit eine durchweg misanthropische Einstellung aufweisen muss. Und in der Tat ist es so, dass Misstrauen das oberste Gebot bei der sicheren Programmierung ist. Sie müssen zwar nicht gleich zum Menschenfeind werden, aber vertrauen Sie nichts und niemandem, den Sie nicht kennen. Daten aus nicht vertrauenswürdiger Quelle sind gefährlich.

Doch sichere Software lässt sich nicht alleine durch das Beachten relevanter Punkte in der Implementierungsphase produzieren. Sicherheit lässt sich vielmehr nur durch einen Software-Entwicklungsprozess gewährleisten, der verschiedene Sicherheitsaspekte berücksichtigt, sodass eine durchgängige Qualität von der Anforderungsphase bis zum Ausrollen der Software entsteht.

Im Anhang des Buches finden Sie einen Anforderungskatalog, der die Anforderungen an einen Software-Entwicklungsprozess definiert, der das Erstellen sicherer Software ermöglicht. Insbesondere im Firmenumfeld lohnt sich ein Blick in diesen Anforderungskatalog.

Doch nun zurück zum Threat Model, einem integralen Bestandteil sicherer Software-Entwicklung, dem Sie sich jetzt – gewappnet mit dem Wissen um die typischsten Sicherheitslücken – nähern können.


Galileo Computing - Zum Seitenanfang

7.3.2 STRIDEZur nächsten ÜberschriftZur vorigen Überschrift

Nachdem Sie das Datenflussdiagramm (DFD) für Ihre App erstellt und alle Elemente in eine Tabelle überführt haben, kommt STRIDE ins Spiel. STRIDE hat seinen Ursprung ebenfalls bei Microsoft und ist ein Akronym, das sich aus den Anfangsbuchstaben der sechs Kategorien zusammensetzt, in die sich alle Bedrohungen einordnen lassen, die nach der STRIDE-Kategorisierung auf ein IT-System wirken können.

STRIDE ist also genau die Hilfe, die Sie benötigen, um Bedrohungen identifizieren zu können. Für jedes Element im DFD, also für jede Zeile der Tabelle, müssen Sie jetzt »nur« noch überlegen, welche Art von Bedrohungen aus den sechs STRIDE-Kategorien wirken kann. Sie erhalten mit STRIDE also eine generische Bedrohungsvorlage und können daraus eine konkrete Bedrohung ableiten – oder eben auch nicht, wenn keine Bedrohung vorhanden ist.

STRIDE steht für die folgenden sechs Kategorien:

  • Spoofing: Vortäuschen einer falschen Identität
  • Tampering: Verändern von Daten
  • Repudiation: Abstreiten von Aktionen
  • Information Disclosure: Preisgabe von Informationen
  • Denial of Service: Störung eines Dienstes
  • Elevation of Privileges: unbefugtes Erlangen von Rechten

Die folgende Tabelle führt für jede der sechs STRIDE-Bedrohungen eine generische Gegenmaßnahme und konkrete Maßnahmen auf:

Tabelle 7.2 STRIDE-Bedrohungen und Gegenmaßnahmen

STRIDE Maßnahme Beispiel

Spoofing

Authentisierung

Public-Key-Kryptografie

Tampering

Integrität

Hashprüfung

Repudiation

Nonrepudiation

Logging

Information Disclosure

Vertraulichkeit

Verschlüsselung

Denial of Service

Verfügbarkeit

Performance-Optimierung

Elevation of Privileges

Autorisierung

Benutzerverwaltung

Aufgrund ihrer Natur unterliegen nicht alle Elemente des DFD allen STRIDE-Bedrohungskategorien. Da eine Entität z. B. keine Daten verarbeitet, kann kein Tampering stattfinden. Ebenso ist Information Disclosure bei einer Entität keine Bedrohung. Ein Benutzer kann zwar seine Zugangsdaten für das Online-Banking bei Facebook veröffentlichen, dies ist aber keine Bedrohung, die für den Programmierer der Banking-App relevant ist – die Bedrohung ist out-of-scope oder, um Douglas Adams zu bemühen, ein PAL (Problem anderer Leute).

Abbildung 7.11 zeigt die möglichen Kombinationen von DFD-Element und STRIDE-Kategorie.

Abbildung

Abbildung 7.11 Zuordnung von DFD-Elementen zu STRIDE-Kategorien

Nun haben Sie alle Informationen beisammen, um sich methodisch der Bedrohungsanalyse Ihrer App anzunehmen. Erstellen Sie eine Tabelle aller Elemente, und überlegen Sie für jedes Element, welche in die Kategorisierung des STRIDE-Katalogs passende Bedrohung für das betreffende Element vorhanden sein könnte. Da die Tabelle Ihre Software auf dem gesamten Lebensweg begleiten wird, empfiehlt sich für die Erstellung ein dynamisches, bei der Arbeit mit Tabellen halbwegs sinnvolles Medium wie Numbers, OpenOffice oder Excel. Das Erweitern und Bearbeiten einer Tabelle ist damit schlichtweg einfacher, und da Sie das Threat Modeling nicht zum Selbstzweck durchführen, sondern möglichst effizient arbeiten möchten, sollte das Handwerkszeug Ihnen möglichst viel Arbeit abnehmen.

Abbildung

Abbildung 7.12 Threat Model der Beispiel-App

Wichtige Grundregeln beim Threat Modeling

Der große Nutzen des Threat Modeling liegt in der Methodik. Diese Methodik leitet auch einen unerfahrenen Anwender durch die schwierige Aufgabe, spezifische Bedrohungen für seine App zu ermitteln. Das Threat Modeling ist diese Methodik, und daher ist es für den Erfolg unerlässlich, diese Methodik strikt anzuwenden. Das Zeichnen eines DFD und das anschließende Anfertigen einer Tabelle aller Elemente und ihrer Bedrohungen führt für sich genommen zu keinen bahnbrechenden Erkenntnissen; beide Tätigkeiten sind aber darauf ausgerichtet, den Anwender zu führen.

Durch das methodische Vorgehen wird der Blick des Anwenders auf die wesentlichen Punkte gelenkt. Der Anwender wird gezwungen, sich intensiv Gedanken über seine App zu machen, und er erhält mit der STRIDE-Kategorisierung eine gute Hilfestellung, um selbstständig Bedrohungen identifizieren zu können.

Es gibt zwei typische Fehler beim Threat Modeling. Der erste Fehler ist, die Methodik nicht durchgehend anzuwenden. Machen Sie sich immer die Mühe, ein ausreichend detailliertes DFD zu erstellen. Das zwingt Sie dazu, sich intensiv mit der Architektur Ihrer App auseinanderzusetzen. Erstellen Sie im Anschluss die Tabelle der Elemente und der Bedrohungen. Dieser Schritt ist nicht nur dazu gedacht, alle Elemente auf Bedrohungen aus dem STRIDE-Katalog abzuklopfen, die Tabelle ist überdies auch das zentrale Dokument des gesamten Vorgangs. Liegt eine vernünftige Dokumentation vor, können Sie immer darauf zurückgreifen, was insbesondere bei der Weiterentwicklung Ihrer App wichtig ist. Sie möchten nicht für jedes neue Feature ein neues Threat Model erstellen, sondern das vorhandene erweitern können.

Der zweite Fehler beim Threat Modeling ist es, über die Einordnung einer Bedrohung in eine der sechs STRIDE-Kategorien zu diskutieren. Ist, um bei der Beispiel-App zu bleiben, der Zugriff per Jailbreak (ID 1) nun ein Spoofing oder nicht eher eine Elevation of Privileges? Die Antwort ist: Das ist total egal! Es geht nicht darum, mögliche Bedrohungen möglichst passgenau in die sechs STRIDE-Kategorien einzuordnen, sondern darum, die sechs STRIDE-Kategorien zu verwenden, um Bedrohungen zu identifizieren! Allzu häufig verlieren sich Threat-Modeling-Workshops in dieser Diskussion, und das Ergebnis ist ein unvollständiges Threat Model, eine Software mit unentdeckten Sicherheitslücken und ein Team von Teilnehmern, das mit dem trügerischen Gefühl nach Hause geht, »richtig was geschafft« zu haben.

Denken Sie also immer daran: Niemand gibt Ihnen eine gute Note für eine schöne Zeichnung, eine formvollendete Tabelle und korrekt klassifizierte Bedrohungen. Heise online wird Ihnen aber sicher einen prominenten Platz in seinem Newsticker geben, wenn Ihre App durch eklatante Sicherheitslücken aufgefallen ist.

Um Ihnen den Einstieg und die Arbeit mit den STRIDE-Kategorien zu erleichtern, finden Sie nachfolgend zu jeder STRIDE-Kategorie einige Beispiele für Bedrohungen samt geeigneten Gegenmaßnahmen.

Spoofing

Spoofing subsumiert alle Bedrohungen, bei denen ein Angreifer eine Identität fälscht, austauscht oder austauscht. Der Begriff der Identität ist dabei nicht auf die Identität einer Person beschränkt, sondern umfasst alle Objekte, die über eine Identität verfügen. Das können die verschiedensten Arten von Objekten sein:

  • Benutzer
  • Server
  • App
  • RSS-Feed
  • Bibliothek
  • Framework
  • IP-Adresse
  • www.ifoo.de

Tabelle 7.3 Spoofing

Bedrohung Maßnahme

Ein Angreifer fälscht die MAC-Adresse oder die IP-Adresse seines Rechners und umgeht auf diese Weise eine darauf basierende Authentisierung.

Authentisierung in der Anwendungsschicht durchführen oder zusätzliche netzwerkseitige Sicherungsmaßnahmen verwenden, z. B. SSL-Zertifikate für Server und/oder Client.

Ein Angreifer tauscht eine von der App verwendete Bibliothek gegen eine mit Schadcode präparierte Bibliothek aus.

Integritäts- oder Versionsprüfung der verwendeten Bibliotheken. Sicherstellen, dass Bibliotheken ausschließlich von vertrauenswürdigen Verzeichnissen aus geladen werden.

Durch die Manipulation des Routings oder der Namensauflösung kann ein Angreifer die Zugriffe der App auf einen Webserver auf einen von ihm kontrollierten Webserver umleiten und auf diese Weise Zugriff auf sensible Daten erlangen.

Verwenden von SSL zur Identifizierung des Webservers (z. B. Prüfen des Zertifikats über den Vergleich des Fingerprints)

Tampering

Alle Angriffe, die mit der Veränderung von Daten zu tun haben, fallen in die Kategorie Tampering. Das reicht vom schreibenden Zugriff in eine Datenbank mittels SQL-Injection über Manipulationen am Dateisystem bis zur Veränderung der Netzwerk-Kommunikation.

Tabelle 7.4 Tampering

Bedrohung Maßnahme

Ein Angreifer kann über einen Man-in-the-middle-Angriff unverschlüsselte Netzwerkkommunikation abfangen (z. B. in einem öffentlichen Hotspot), den Datenstrom verändern und so z. B. in Transaktionen eingreifen.

Übertragung sensibler Daten ausschließlich über verschlüsselte Protokolle

Ein Angreifer deaktiviert durch einen über das Netzwerk applizierten Jailbreak die Sicherheitsmechanismen des iPhone seines Opfers und damit auch der App.

Prüfen auf das Vorhandensein eines Jailbreaks beim Start der App

Ein Angreifer kann über eine SQL-Injection in der App schreibend auf die Datenbank des Serversystems zugreifen, das mit der App kommuniziert.

Filtern aller Benutzer-Eingaben auf potenziell schädliche Sonderzeichen

Repudiation

Repudiation fasst sowohl das Verschleiern von Aktionen und Angriffen durch fehlendes Logging als auch Angriffe gegen und über Logging-Mechanismen zusammen.

Tabelle 7.5 Repudiation

Bedrohung Maßnahme

Ein Angreifer kann Aktionen gegen eine App oder gegen ein aus einer App und einem Server bestehendes Kommunikationssystem durchführen, ohne dass diese Aktionen durch einen Logging-Mechanismus registriert werden.

Schreiben aussagekräftiger Log-Dateien und Speicherung der Daten an sicherer (dritter) Stelle

Ein Angreifer kann sensible Daten aus
Log-Dateien auslesen.

Log-Dateien sollten gegen unbefugten Zugriff geschützt sein und keine sensiblen Daten wie z. B. Passwörter oder Transaktionsinterna (Kontostand etc.) enthalten.

Ein Angreifer kann den Logging-Mechanismus so beeinflussen, dass die Log-Dateien durch Rotation gelöscht werden, und dadurch seinen Angriff verschleiern.

Rotierte Log-Dateien nicht löschen. Logging in angemessener Detailtiefe, um das Anfallen zu großer Datenmengen in den Logfiles zu verhindern

Information Disclosure

Die Preisgabe von Informationen jeglicher Art fällt in die Kategorie Information Disclosure. Informationen können dabei an den verschiedensten Stellen anfallen und von beliebiger Natur sein. Beispiele für Information Disclosure sind:

  • Fehlermeldungen
  • Sensible Informationen im Syslog (»Konsole«)
  • Verwendung von Klartextprotokollen für vertrauliche Daten
  • Secret Key für symmetrische Verschlüsselung als String im Binary
  • Debug-Symbole
  • Netzwerkbanner von Serverdiensten

Tabelle 7.6 Information Disclosure

Bedrohung Maßnahme

Eine App gibt bei (gezielter) Fehlbenutzung Fehlermeldungen mit Debug-
Informationen aus.

Fehlermeldungen sollten grundsätzlich neutral gehalten sein. Debug-Informationen und Stack-Traces sollten ausschließlich in separate Debug-Logdateien oder an den Syslog-Server geschrieben werden.

Der geheime Schlüssel für die Verwendung eines symmetrischen Kryptoalgorithmus ist als String im App-Binary gespeichert. Ein Angreifer kann den String ohne großen Aufwand auslesen und erhält auf diese Weise Zugriff auf die Verschlüsselung.

Sichere Ablage geheim zu haltender Informationen, z. B. in der Keychain. Keine Verwendung eines einzigen statischen Schlüssels für alle Instanzen einer App.

Übertragung von Zugangsdaten über ein Klartextprotokoll (anfällig für Man-in-the-middle-Angriffe)

Übertragung sensibler Daten ausschließlich über verschlüsselte Protokolle

Denial of Service

Der Begriff Denial of Service ist aus Funk und Fernsehen im Zusammenhang mit DoS- oder DDoS-Angriffen (Distributed Denial of Service) auf Webseiten bekannt. Unter Denial of Service versteht man aber nicht nur netzwerkbasierte Angriffe, die darauf ausgelegt sind, einen Webserver in die Knie zu zwingen, sondern alle Arten von Angriffen, die dazu führen, dass ein System nicht mehr so funktioniert wie vorgesehen.

Tabelle 7.7 Denial of Service

Bedrohung Maßnahme

Ein Angreifer kann über die Importfunktion einer App eine Datei mit manipuliertem Format einschleusen und dadurch den Import-Parser der App lahmlegen.

Robuste Programmierung von Importfiltern und Parsern, um Angriffe über manipulierte Formate zu verhindern

Wiederholte fehlerhafte Anmeldung an der App führt kommentarlos zum Löschen aller lokalen Daten.

Verwenden von Hinweisen, um den Benutzer auf die Gefahr aufmerksam zu machen, gegebenenfalls Implementierung einer Funktion zur Passwort-Merkhilfe

Eine schmalbandige Netzwerkverbindung führt dazu, dass Kernfunktionalitäten einer App nicht mehr funktionieren. Ein Angreifer im lokalen Netzwerk kann dies beim Start der App für DoS-Angriffe ausnutzen, indem er das Netzwerk mit Paketen flutet.

Effiziente Netzwerkprogrammierung und angemessenes Error-Handling verwenden

Elevation of Privileges

Die letzte STRIDE-Kategorie umfasst alle Angriffe, bei denen ein Angreifer Aktionen in einem anderen als dem eigenen Rechte-Kontext ausführt. Im Webbereich ist das Cross-Site-Scripting eine bekannte Schwachstelle, bei der ein Angreifer eigenen Code im Sicherheitskontext eines anderen Webservers ausführen kann.

Tabelle 7.8 Elevation of Privileges

Bedrohung Maßnahme

Ein unbefugter Benutzer greift auf die in den Hintergrund geschickte App zu und gelangt so in den Besitz sensibler Daten.

Sperren der App beim Wechsel in den Hintergrund. Reaktivierung nur über Eingabe der gültigen Zugangsdaten.

Ein Benutzer einer App oder ein Angreifer im Netz kann von einer App an einen Server übermittelte Daten so mit Schadcode manipulieren, dass der Server diesen Schadcode an andere Benutzer ausliefert.

Strikte Filterung von Benutzer-Eingaben auf potenziell schädliche Sonderzeichen und Sicherstellen der Integrität der Netzwerk-Übertragung. Auf dem Server zusätzlich strikte Filterung aller Ausgaben auf potenziell schädliche Sonderzeichen.

Datenimport von einer nicht geprüften URL erlaubt einem Angreifer das Einschleusen von fehlerhaften Daten oder Schadcode.

Semantische Prüfung von importiertem Content, Filterung auf potenziell schädliche Sonderzeichen, Verwenden von SSL, um Kommunikationspartner im Netz eindeutig identifizieren zu können.


Galileo Computing - Zum Seitenanfang

7.3.3 Generische Design-GrundsätzeZur nächsten ÜberschriftZur vorigen Überschrift

Beim sicheren Design von Software gibt es einige grundsätzliche Prinzipen, die man als Entwickler verinnerlichen sollte. Da es nur eine Handvoll sind, sollte es Ihnen nicht allzu schwerfallen, sie sich zu merken. Die konsequente Beachtung dieser Prinzipien beim Design kann aber helfen, grobe Schnitzer zu vermeiden. Überdies taugt die Liste der Prinzipien in Kundengesprächen gut zum Bullshit-Bingo. ;-)

  • Keep it simple, stupid: Von der Implementierung einer Klasse bis zum Design der Architektur sollte alles so einfach wie möglich gehalten sein. Komplexität führt zu Unübersichtlichkeit und Fehlern. Anstatt eine Methode in zwölf Ebenen zu schachteln, sollten Sie lieber eine Pause machen und darüber nachdenken, wo in der Planung etwas falsch gelaufen sein könnte.
  • Need to know: Beim Umgang mit Informationen sollten Sie sich immer die Frage stellen: »Wer muss was wissen?« Niemand muss mehr wissen als nötig. »Niemand« kann eine Person sein, eine App, eine Klasse, ein Server etc.
  • Attack Surface Reduction: Die Anzahl der Eintrittspunkte für Daten (Entry Points) sollte immer so gering wie möglich sein. Bevor man auf dem iPhone einen Serverdienst startet, sollte man lieber darüber nachdenken, ob es nicht auch umgekehrt geht (als Client).
  • Datensparsamkeit: Nur die Daten einfordern, verarbeiten und speichern, die für den Betrieb zwingend notwendig sind. Große Datenbanken üben eine magische Anziehungskraft auf Angreifer aus.
  • Secure by Default: Sie sollten sicherheitsrelevante Optionen standardmäßig aktivieren und den Benutzer oder Administrator diese manuell deaktivieren lassen, wenn es denn unbedingt notwendig ist.
  • Least Privilege: Verwenden Sie grundsätzlich die geringstmöglichen Rechte zur Ausführung von Operationen.
  • Defense in Depth: Verlassen Sie sich niemals auf singuläre Sicherheitsmechanismen, sondern implementieren Sie verschiedene Stufen der Sicherheit.

Galileo Computing - Zum Seitenanfang

7.3.4 Threat Modeling aus der Tube – das Microsoft SDL Threat Modeling ToolZur vorigen Überschrift

Wie in der Einführung zum Threat Modeling bereits erwähnt wurde, ist diese Methodik im Bereich der Software-Entwicklung ursprünglich von Microsoft eingeführt und verfeinert worden. Nach den großen Wurm-Plagen und den nicht abreißenden Meldungen über Sicherheitslücken in Microsoft-Produkten hat Microsoft im Jahr 2003 auf die Bremse getreten und mit dem Security Push den Grundstein für den in den folgenden Jahren immer weiter intensivierten und verfeinerten Secure Development Lifecycle (SDL) gelegt.

Neben dem Ziel, eigene Produkte sicherer zu machen, lässt Microsoft auch Dritte an seinen Erkenntnissen rund um den SDL teilhaben und hat dazu das Microsoft SDL Pro Network ins Leben gerufen. Auf der dazugehörenden Website (http://www.microsoft.com/security/sdl/) gibt es das Microsoft SDL Threat Modeling Tool kostenlos zum Download. Dieses Tool bietet eine Oberfläche zum Erstellen eines Datenflussdiagramms und erstellt aus diesem DFD selbstständig die Tabelle der für die Elemente des DFD potenziell wirkenden Bedrohungen – einfacher geht es wirklich nicht.

Nun wäre Microsoft nicht Microsoft, wenn es an der Sache nicht einen klitzekleinen Haken gäbe. Dieser äußert sich dergestalt, dass zwar das Tool kostenlos ist, man zum Benutzen aber eine installierte Version von Visio auf dem Rechner haben muss, da die DFD-Erstellung im Tool über die Visio-Engine erfolgt. Honi soit qui mal y pense. Der Umstand, dass das Tool nur für Windows erhältlich ist, ergibt sich direkt aus dem Visio-Zwang und muss hier nicht extra erwähnt werden. Nichtsdestotrotz ist es zurzeit das einzige Tool, das Threat Modeling am DFD ermöglicht und diese Aufgabe auch hinreichend gut erledigt. Daher lohnt sich, sofern Windows und Visio vorhanden sind, auf jeden Fall ein Blick auf das Tool.

Das Tool ist von Entwicklern für Entwickler konzipiert worden und nicht von Security-Experten für Security-Experten. Das schlägt sich in der angenehm intuitiven, zielgerichteten und einfachen Bedienung nieder. Nach dem Start erstellt das Tool ein rudimentäres DFD, um die grundlegende Funktionsweise zu demonstrieren (siehe Abbildung 7.13).

Abbildung

Abbildung 7.13 Das Microsoft SDL Threat Modeling Tool

Das DFD befindet sich, nicht zu übersehen, im rechten Teil der GUI. Links daneben, im Bereich Shapes, finden Sie alle Elemente, die Sie für die Erstellung eines DFD benötigen. Ziehen Sie die benötigten Elemente einfach in den Zeichenbereich rechts, und erstellen Sie die notwendigen Verknüpfungen.

Das Tool analysiert das DFD in Echtzeit und gibt Verstöße gegen die Semantik links im Bereich Diagram Validation aus. Das merken Sie spätestens dann, wenn Sie ein oder mehrere Elemente im DFD nicht korrekt verknüpft haben. So führt z. B. ein Prozess ohne Verbindungen zu der in Abbildung 7.14 gezeigten Fehlermeldung.

Abbildung

Abbildung 7.14 Das Tool meldet einen Validierungsfehler.

Der Bereich Help im linken Teil der GUI gibt eine Minimal-Anleitung für die Erstellung eines DFD und verweist auf die dem Tool beiliegende Hilfe-Datei, die übrigens sehr gut ist.

Links oben befindet sich im Bereich Diagrams die Übersicht über die Ebenen des DFD. Fügen Sie mit der rechten Maustaste einfach weitere Ebenen hinzu, wenn Sie Ihr Diagramm weiter aufteilen möchten. Das DFD unserer Beispiel-App lässt sich somit ohne großen Aufwand über alle Ebenen in dem Tool darstellen (siehe Abbildung 7.15).

Abbildung

Abbildung 7.15 DFD der Beispiel-App im Threat Modeling Tool

Der wahre Nutzen des Tools ergibt sich erst aus der Transformation der DFD-Elemente in die Liste der STRIDE-Kategorien. Dies erfolgt über den Button Analyze Model links unten im Fenster. Das Tool erstellt eine Liste der DFD-Elemente und fügt jedem Element die STRIDE-Bedrohungen hinzu, die für dieses Element wirken können (siehe die Zuordnungen in Abbildung 7.16).

Abbildung

Abbildung 7.16 Die Liste der DFD-Elemente und ihrer STRIDE-Bedrohungen

Durch Auswahl eines Elements öffnet sich rechts im Fenster die Liste der STRIDE-Bedrohungen. Neben einigen Informationen und Beispielen zu den einzelnen Bedrohungen gibt es dort für jede Bedrohung ein Textfeld mit dem Titel Impact und eines mit dem Titel Solution (siehe Abbildung 7.17). Im Feld Impact formulieren Sie die von Ihnen identifizierte Bedrohung und im Feld Solution die entsprechende Maßnahme.

Abbildung

Abbildung 7.17 Spoofing für das Element »User«

Möchten Sie keine Bedrohung formulieren, beispielsweise weil Ihnen keine einfällt oder weil Sie eine mögliche Bedrohung als akzeptabel erachten, klicken Sie auf den Link Certify that there are no threat of this type und geben die Begründung für diese Entscheidung an (siehe Abbildung 7.18).

Abbildung

Abbildung 7.18 Ein akzeptiertes Risiko

Über den Button Describe Environment unten links im Fenster können Sie Metadaten zum Threat Model angeben, die das Tool in den Bericht übernimmt. Dies ist zu Dokumentationszwecken durchaus sinnvoll. Um einen Bericht zu erstellen, wählen Sie ebenfalls unten links Generate Reports aus und lassen sich das Threat Model anzeigen. Dieser Bericht enthält die von Ihnen angegebenen Metadaten, das oder die DFDs, eine nummerierte Aufzählung aller Elemente der DFDs sowie die komplette Liste aller von Ihnen formulierten Bedrohungen, Maßnahmen und Begründungen für akzeptierte Bedrohungen. Für Einsteiger in die Thematik, die Zugriff auf Windows und Visio haben, ist das Tool also eine sinnvolle Hilfe.

Verwirrende Tool-Vielfalt

Sie finden bei Microsoft zwei Tools zu dem Thema Threat Modeling. Eines ist das erwähnte Microsoft SDL Threat Modeling Tool, und das andere heißt Microsoft Threat Analysis & Modeling. Das erste Tool haben Sie in diesem Abschnitt kennengelernt. Das zweite ist ein Tool, das Threat Modeling aus einer anderen Perspektive als dem DFD betrachtet. In diesem Tool, das übrigens auch kostenlos ist und ohne weitere Zusatzsoftware funktioniert (unter Windows), erfolgt das Identifizieren von Bedrohungen über Anwendungsfälle.

Der Benutzer muss eine Liste aller Anwendungsfälle seiner App erstellen, und das Tool versucht zu diesen Anwendungsfällen aus einer Bedrohungsdatenbank selbstständig Bedrohungen zu identifizieren. Der Ansatz ist interessant, die Umsetzung ist aber wenig gelungen, und überdies wird das Tool von Microsoft nicht weiter gepflegt. Es lohnt sich also nicht, sich näher damit zu beschäftigen.

Abbildung

Abbildung 7.19 Der Threat-Model-Report



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.







<< zurück
  Zum Katalog
Zum Katalog: Apps programmieren für iPhone und iPad

Apps programmieren für iPhone und iPad
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Einstieg in Objective-C 2.0 und Cocoa





 Einstieg in
 Objective-C 2.0
 und Cocoa


Zum Katalog: Apps entwickeln für iPhone und iPad - Videotraining






 Apps entwickeln für
 iPhone und iPad -
 Videotraining


Zum Katalog: Apps mit HTML5 und CSS3






 Apps mit HTML5
 und CSS3


Zum Katalog: iPhone- und iPad-Apps entwickeln






 iPhone- und
 iPad-Apps entwickeln


Zum Katalog: Android 4






 Android 4


Zum Katalog: Android-Apps entwickeln - Videotraining






 Android-Apps
 entwickeln -
 Videotraining


Zum Katalog: Windows Store Apps mit XAML und C#






 Windows Store Apps
 mit XAML und C#


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo





Copyright © Galileo Press 2013
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de