Die Infor­ma­tion­ssicher­heit hat Einzug in den All­t­ag genom­men. Viele ken­nen jet­zt Dank der Geräte und Social Media Plat­tfor­men, die sie ver­wen­den, Tech­niken wie Zwei-Fak­tor-Authen­tisierung, Ver­schlüs­selung und Soft­ware-Updates. Wenn es um die Innereien — also das Secure Design — geht, so bleiben viele Fra­gen offen. Was in mod­er­nen Prozes­soren heutzu­tage vorge­ht, lässt sich schw­er in weni­gen Worten aus­drück­en. Die Fehler Melt­down und Spec­tre sind zwar in aller Munde, jedoch braucht man viel Vor­wis­sen, um zu ver­ste­hen, was da genau passiert. Dazu kommt zusät­zlich der Code, der in der Firmware, qua­si unter dem Betrieb­ssys­tem, Arbeit für Geräte wie Grafikkarten oder Net­zw­erkkarten ver­richtet. Möchte man jet­zt eine App­lika­tion entwick­eln, stellt sich die fol­gende Frage: Wie kann man bei der Vielzahl von Kom­po­nen­ten den Überblick behal­ten und sich­er pro­gram­mieren? Secure Cod­ing, also sichere Pro­gram­miertech­niken, alleine hil­ft ja nur beim eige­nen Code. Die Antwort liegt in der Architek­tur des Ganzen.

Der Aufbau entscheidet beim Secure Design

Eine Anwen­dung begin­nt niemals mit Code. Am Anfang ste­ht immer ein Design und eine Beschrei­bung der Auf­gaben, die eine App­lika­tion erfüllen soll. Diese Phase ist der kri­tis­chste Teil bei der Soft­wa­reen­twick­lung, denn Entschei­dun­gen, die hier getrof­fen wer­den, bes­tim­men meist die Zukun­ft des Pro­jek­ts. Das bedeutet im Beson­deren, dass die Grund­lage für die spätere Infor­ma­tion­ssicher­heit des Codes an dieser Stelle getrof­fen wird. Beispiel­sweise die Auswahl der Kom­po­nen­ten, die ver­wen­de­ten Pro­tokolle, notwendi­ge Bedin­gun­gen (wie beispiel­sweise kryp­tografis­che Schlüs­sel, Anforderun­gen an Net­zw­erk und Spe­ich­er, etc.) und Kom­mu­nika­tion mit Drit­tan­bi­etern wer­den in der Design­phase fest­geschrieben. Was bedeutet also Secure Design in diesem Zusam­men­hang?

Secure Design beste­ht aus ein­er Rei­he von Grund­la­gen, die an jed­er Stelle im Soft­ware­pro­jekt beachtet wer­den. Man ver­sucht die Angriffs­fläche des Codes zu min­imieren, über­all sichere Defaults zu ver­wen­den, so wenige Berech­ti­gun­gen wie möglich an Konten/Komponenten zu verteilen, Sicher­heit­sprü­fun­gen in allen Schicht­en einzubauen, Fehler sich­er abz­u­fan­gen, keinen frem­den Dien­sten zu ver­trauen und Auf­gaben im Code zu tren­nen. Die App­lika­tion muss in jed­er Umge­bung zuver­läs­sig arbeit­en kön­nen, ohne Schwach­stellen preiszugeben. Ver­ar­beit­ete Dat­en müssen ständig auf ihre Integrität über­prüft wer­den. Das gilt auch für interne Prozesse wie Kom­mu­nika­tion mit ein­er Daten­bank oder anderen Teilen. Entwick­ler und der Code dür­fen zu kein­er Zeit von Annah­men aus­ge­hen, die ein Angriff negieren kön­nte. Dies schließt Soft­ware­bib­lio­theken und Fähigkeit­en von Hard­ware bzw. Betrieb­ssys­te­men ein. Darunter fall­en auch die Eigen­schaften von Prozes­soren, die die Klasse der Melt­down und Spec­tre Fehler her­vorgerufen haben.

Natür­lich darf man sich jet­zt nicht von der Para­noia pack­en lassen und auf alle Fea­tures der Plat­tform verzicht­en. Man soll ja Code wiederver­wen­den und nicht immer das Boot neu erfind­en (das Boot ist älter als das Rad). Es geht immer um Annah­men, die man trifft, wenn man pro­gram­miert. Die XML Eingabe ist vielle­icht kein XML. Die Antwort des Cloud Ser­vices stammt vielle­icht nicht von der angenomme­nen Quelle oder ist ein­fach falsch. Die Dat­en, die man vorher in die Daten­bank geschrieben hat, sind möglicher­weise nun falsch (weil es einen Angriff gab). Mod­ern­er Code steckt voller Annah­men. Span­nend wird es, wenn diese nicht stim­men.

Mathematische Beweise für Secure Coding

Eine Möglichkeit Mehrdeutigkeit­en in Spez­i­fika­tio­nen zu ver­mei­den ist die Math­e­matik. Da Code aus der Infor­matik kommt und die Infor­matik ein Teil­ge­bi­et der Math­e­matik ist, lassen sich Prozesse math­e­ma­tisch darstellen. Über­set­zt man nun Auf­gaben aus den Design­doku­menten in eine math­e­ma­tis­che Sprache, so lassen sich mit Hil­fe von Werkzeu­gen Abläufe im Code math­e­ma­tisiert darstellen und beweisen. Schafft man dies, so ist man sprich­wörtlich auf der sicheren Seite. Zusät­zlich eli­m­iniert man so unklare For­mulierun­gen, was wiederum den Entwick­lerin­nen hil­ft.

Die For­mal­is­men sind auch ein Teil von Secure Design.

Datenbasierte Entwicklung ≠ Datenbank-Entwicklung

Wie imple­men­tiert man nun Secure Design? Da man es immer mit Dat­en zu tun hat, kann man bei diesen begin­nen. Die App­lika­tion soll ja mit Fehlern sich­ern umge­hen kön­nen. Das bedeutet bei Eingabe von unsin­ni­gen oder manip­ulierten Dat­en darf nichts Kri­tis­ches passieren. Eine Tak­tik ist daher, die Soft­ware mit zufäl­lig erzeugten oder manip­ulierten Dat­en zu füt­tern und zu schauen was passiert. Let­ztlich ist das die Strate­gie der Test­fälle, die man bei der Entwick­lung oft hat, um beseit­igte Fehler nicht wieder im Code zu find­en. Die Tech­nik, Sys­teme mit Zufalls­dat­en zum Stolpern zu brin­gen, heißt Fuzzing. Es gibt viele Werkzeuge dafür, teil­weise auch schon für die Entwick­lungswerkzeuge. Am besten funk­tion­iert die Kom­bi­na­tion aus Zufalls­dat­en und echt­en Dat­en, damit man über die erste Über­prü­fung hin­wegkommt. Schließlich möchte man ja den ganzen Code testen.

Her­steller von Betrieb­ssys­te­men oder Teams, die kri­tis­che Soft­ware entwick­eln, ver­wen­den diesen Ansatz schon.

Die Gewohnheiten ändern!

Infor­ma­tion­ssicher­heit ste­ht und fällt mit den Gewohn­heit­en des All­t­ags. Alles, was aktiv bedacht wer­den muss, geht früher oder später schief. Das­selbe gilt natür­lich auch für die Soft­wa­reen­twick­lung. Aus diesem Grunde muss man Secure Design und Secure Cod­ing in geeigneten Schrit­ten in die eige­nen Prozesse ein­bauen. Das lässt sich lei­der nicht mit der Lek­türe ein­er Doku­men­ta­tion oder Anleitung alleine durch­führen. Empfehlenswert ist die Umset­zung in Teilschrit­ten, begleit­et durch einen Work­shop für alle Entwick­ler. Es gibt reich­haltig Mate­r­i­al zur Anschau­ung, denn das Studi­um von bekan­nten Fehlern schafft Prax­is­nähe und hil­ft den eige­nen Code zu hin­ter­fra­gen.

Über René Pfeif­fer

René Pfeif­fer ist seit 2009 als Senior Secu­ri­ty Con­sul­tant für SEC4YOU tätig. Neben sein­er selb­st­tändi­gen Tätigkeit ist der Geschäft­führer der DeepSec GmbH und ver­anstal­tet seit über 10 Jahren die DEEPSEC. Durch die Nutzung von anerkan­nten Meth­o­d­en und seine Affinität zu IT-Secu­ri­ty und Lin­ux durfte er unzäh­lige Kun­den den den Branchen Indus­trie, Luft­fahrt, Telekom­mu­nika­tion, Energiev­er­sorg­er, Phar­mazie, Gesund­heitswe­sen, Wer­bung, Anwalt­skan­zleien, NGOs, Medi­en, Logis­tik und Soft­ware-Entwick­lung in Sicher­heits­fra­gen berat­en.

Fra­gen an René Pfeif­fer zu Secure Design — Secure Cod­ing  stellen Sie bitte über unser Kon­tak­t­for­mu­lar.