Massachusetts Institute of Technology. Vorlesung # 6.858. "Sicherheit von Computersystemen." Nikolai Zeldovich, James Mickens. 2014 Jahr
Computer Systems Security ist ein Kurs zur Entwicklung und Implementierung sicherer Computersysteme. Die Vorträge behandeln Bedrohungsmodelle, Angriffe, die die Sicherheit gefährden, und Sicherheitstechniken, die auf jüngsten wissenschaftlichen Arbeiten basieren. Zu den Themen gehören Betriebssystemsicherheit, Funktionen, Informationsflussmanagement, Sprachsicherheit, Netzwerkprotokolle, Hardwaresicherheit und Sicherheit von Webanwendungen.
Vorlesung 1: „Einführung: Bedrohungsmodelle“
Teil 1 /
Teil 2 /
Teil 3Vorlesung 2: „Kontrolle von Hackerangriffen“
Teil 1 /
Teil 2 /
Teil 3Vorlesung 3: „Pufferüberläufe: Exploits und Schutz“
Teil 1 /
Teil 2 /
Teil 3Vorlesung 4: „Trennung von Privilegien“
Teil 1 /
Teil 2 /
Teil 3Vorlesung 5: „Woher kommen Sicherheitssysteme?“
Teil 1 /
Teil 2Vorlesung 6: „Chancen“
Teil 1 /
Teil 2 /
Teil 3Vorlesung 7: „Native Client Sandbox“
Teil 1 /
Teil 2 /
Teil 3Vorlesung 8: „Netzwerksicherheitsmodell“
Teil 1 /
Teil 2 /
Teil 3Vorlesung 9: „Sicherheit von Webanwendungen“
Teil 1 /
Teil 2 /
Teil 3Vorlesung 10: „Symbolische Ausführung“
Teil 1 /
Teil 2 /
Teil 3Vorlesung 11: „Ur / Web-Programmiersprache“
Teil 1 /
Teil 2 /
Teil 3 Das Letzte, was wir tun müssen und was sehr lehrreich sein wird, ist, diesen Code durch Angabe des Raummoduls dort zu ändern und dann wie im vorherigen Beispiel auf den Raumtisch zuzugreifen. Diese Option ist nicht zulässig, da dies nicht zulässig ist.

Dies wäre so, als könnten Sie private Klassenfelder in Java lesen und schreiben. In der Tat erhalten wir eine ziemlich einfache Nachricht, die besagt, dass wir hier eine nicht verwandte Variable haben, einen unbekannten Ausdruck für den Raumparameter.

Wir könnten dieses Add-On-Modul erwähnen, das wir nur zum Spaß erstellt haben.

Aber dann werden es andere Tabellen sein. Wir können leicht darauf zugreifen. Daher werde ich es in zwei Teile aufteilen. Wir werden zunächst einfach die Raummethode aufrufen und dann etwas anderes tun, um ihre Elemente zu lesen.

Zeigen Sie eine Liste der Ergebnisse an und nicht umgekehrt. Dies entspricht in etwa der vorherigen Funktionsweise des Programms, mit Ausnahme der Verwendung verschiedener Datentypen. Mal sehen, was daraus wird. Jetzt kehren wir zu unserem Chat in Raum 1 zurück und geben alle Nachrichten in die Zeile ein. Sie sehen, dass sie alle fehlerfrei angezeigt werden.

Das heißt, jetzt haben wir diese Kapselung, sodass Sie sich die Struktur dieses Raums als Bibliothek vorstellen können, sich aber keine Sorgen machen müssen.
Es gibt verschiedene Stellen, die die interne Invarianz eines Systems beschädigen können. Vielleicht möchten Sie, dass die Nachricht nach dem Hinzufügen niemals verschwindet. All dies steht in den Zeitschriften. Diese Struktur bietet solche Eigenschaften unabhängig von anderem Code, z. B. dem, auf dem das Chatroom-Modul geschrieben ist.
Student: Sie haben also die Definition des Raums geändert. Was würde in diesem Fall mit der Datenbanktabelle passieren?
Professor: Sie müssen den Befehl alter table manuell ausführen, wenn Sie die alten Daten behalten möchten. Beim Start der Anwendung wird jedoch das Systemdatenbankverzeichnis abgefragt und überprüft, ob das Schema weiterhin den Erwartungen entspricht. Dann erhalten Sie einen statischen Fehler. Ich hoffe, dies gibt Ihnen einen Hinweis darauf, was Sie in der Datenbank ändern sollten.
Student: aber es wird nicht automatisch die Datenbank oder so etwas löschen?
Professor: Ich hoffe nicht. Ich denke nicht, dass der Compiler dies tun sollte. Sie können sich vorstellen, den Compiler anzupassen, um die Entwicklung der Datenbank zu verstehen. Ich denke, Sie müssen alter table-Befehle schreiben, um zu starten, da der Compiler dies derzeit nicht tut.

Lassen Sie uns nun über die Fälschung von standortübergreifenden Anfragen und deren Prävention sprechen. Bevor wir dies tun, schauen wir uns den Code auf dieser Seite an. Wir haben ein traditionelles HTML-Formular, das hier generiert wird. Und natürlich gibt es keinen Schutz gegen Fälschung von standortübergreifenden Anfragen, und ich denke, das ist gut. Denn nach meinem Verständnis besteht das Problem der Fälschung von standortübergreifenden Anforderungen im impliziten Kontext, den die Anwendung mit jeder Anforderung sendet.
Angenommen, es gibt eine Art Angreifer, der Ihren impliziten Kontext nicht kennt. Angenommen, Ihr Passwort wird in einem Cookie gespeichert, ein sehr einfaches Beispiel. Und wenn der Angreifer Sie täuscht, wenn Sie auf den Link zu der von ihm benötigten Anwendung klicken, sendet der Browser automatisch einen impliziten Kontext und zwingt die Anwendung, das zu tun, was der Angreifer nicht direkt tun konnte.

In diesem Fall gibt es keinen impliziten Kontext, sodass kein Risiko besteht, standortübergreifende Anforderungen zu fälschen. Möchte jemand diese Funktion des Systems herausfordern, bevor ich fortfahre? Es kann für mich sehr informativ sein. Wenn nicht, fügen Sie hier einen impliziten Kontext hinzu. In diesem Fall wird das System automatisch die richtigen Gegenmaßnahmen ergreifen, basierend auf der Analyse des Programms, das versteht, dass es jetzt einen impliziten Kontext gibt.
Jetzt werde ich hier Cookies einfügen. Als weiteres Beispiel für die Modulkapselung werde ich hier ein ganzes Benutzerauthentifizierungssystem vorstellen, in dem wir Benutzerkonten und abstrakte Arten von Kennungen und Kennwörtern haben. Daher können Sie den Wert eines dieser Datentypen nicht einfach direkt erstellen. Sie müssen eine genehmigte Methode zum Erstellen von Werten dieser Typen durchlaufen.
Ich werde den Tisch direkt in die Unterschrift setzen. Und ich werde es auch einschränken, indem ich sage, dass der Schlüssel dazu das ID-Formular ist.

Tatsache ist jedoch, dass in dieser Benutzertabelle die ID und das Kennwort abstrakte Datentypen sind. Daher kann der Code das Kennwort nicht sehen und nicht alle Bezeichner konsistent generieren und in dieser Tabelle ausprobieren. Da ein abstrakter Typ verwendet wird, ist es unmöglich festzustellen, wie die ID aussieht, und es ist unmöglich, ein Kennwort zu finden. Sie kommen gerade von diesem Tisch und das sind undurchsichtige Token.
Aber wir könnten zulassen, dass sie Abwasser sind. Möglicherweise möchten Sie eine Konvertierungsrichtung zwischen Zeichenfolgen und diesen Typen zulassen. Jetzt werde ich hier etwas tun, hauptsächlich die Details, und ich werde nicht versuchen, sie zu erklären. Dies entspricht jedoch der Erklärung, dass Sie Zeichenfolgen in ID konvertieren dürfen. Für diejenigen, die mit Haskell vertraut sind, ist dies eine Instant-Typ-Klasse, diese Berechtigung, Zeichenfolgen in IDs umzuwandeln.

Wir werden keine weitere Berechtigung anwenden, da wir die ID nicht wieder in etwas anderes verwandeln möchten. Machen wir dasselbe für das Passwort. Wir möchten das Passwort des Benutzers lesen können, aber wir werden das Passwort nicht akzeptieren und es in eine Zeichenfolge umwandeln, die uns mitteilt, dass der Benutzer den Chat betreten hat.
Auf diese Weise können andere Teile des Codes das Kennwort vom Benutzer akzeptieren, in diesen Typ konvertieren und zur Überprüfung zum Benutzermodul transportieren. Sie können jedoch nicht die Benutzertabelle abfragen und alle Kennwörter in einer Form abrufen, aus der sie ihren Textausdruck extrahieren können.
Dann können wir eine Anmeldemethode haben, die diese beiden Komponenten, ID und Passwort, akzeptiert und nur als Nebeneffekt wirkt, der tatsächlich im Code angegeben ist. Wir müssen auch herausfinden, welcher Benutzer registriert ist. Dies ist der Code, der die Transaktion ausführt, mit der die ID erstellt wird.

Der erste Schritt besteht darin, diese Definition einfach zu kopieren. Und dann kommt eine Überraschung. Es stellt sich heraus, dass die Benutzer-IDs und Kennwörter Zeichenfolgen sind, aber dieser Umstand wird außerhalb des Moduls nicht bekannt gegeben.

Jetzt werden wir Cookies erstellen. Cookies sind eine weitere Sache, die in die Sprache integriert ist. Tatsächlich fungieren sie als veränderbare globale Variablen, die für jeden Client, der Ihre Anwendung verwendet, eine Kopie haben.
Daher erstellen wir ein Cookie, in dem für jeden Benutzer einfach eine Kopie der beiden Felder gespeichert wird, die wir hier haben.

Diese Cookies sind für dieses Modul privat. Andere Teile des Codes können Cookies nicht lesen, da sie dieses private Feld einfach nicht haben. So kann niemand die ID und das Passwort, die für diesen Benutzer gespeichert sind, direkt sehen. Sie werden jedoch beim Anzeigen verschiedener Seiten gespeichert, wie dies bei normalen Cookies der Fall ist.
Jetzt werde ich die Anmeldefunktion einfügen, die den Prozess zum Überprüfen der Datenbank startet und herausfindet, ob dies wirklich das richtige Paar aus Benutzername und Passwort ist. Bei diesem Vorgang wird nur geprüft, ob in der Datenbank eine Zeile mit dieser Benutzer-ID und diesem Kennwort gefunden wird.
Wenn wir es finden, dann gut, dann ist dies die richtige Bedeutung. Speichern wir dies einfach in Cookies. Wir verwenden eine Methode, die den Wert eines Cookies ändert. Und wir müssen hier einige Dinge einfügen, der Einfachheit halber werde ich sagen, dass dieser Cookie nicht abläuft. Ich möchte hier kein SSL ausführen, daher sage ich, dass wir in diesem Fall keine Sicherheit benötigen, und setze den Parameter Secure = false.
Aber wenn Sie sich wirklich um Sicherheit kümmern, schreiben Sie natürlich Secure = true. Wenn die Prüfung fehlschlägt und das Modul einen Fehler meldet, stoppt das Programm und beschreibt diesen Fehler.

Schließlich können wir diese Funktion erstellen, die angibt, welcher bestimmte Benutzer angemeldet ist, indem der aktuelle Cookie-Wert empfangen wird. Dieser Parameter kann auch auf none gesetzt werden, wenn sich der Benutzer noch nicht angemeldet hat. In diesem Fall wird eine weitere Fehlermeldung angezeigt. Oder es könnte eine Art Aufzeichnung des genauen Typs sein, den wir oben verwendet haben. Also kopiere ich es einfach hier und führe die gleiche Prüfung durch. Wenn dies funktioniert, geben wir einfach den Teil des ID-Datensatzes zurück, den wir gerade in der Datenbank überprüft haben.

Lassen Sie mich das einfach überprüfen. Wir starten den Compiler und Sie sehen das Ergebnis auf dem Bildschirm.

Zentral für all diese Implementierungsdetails. Aber außerhalb dieses Moduls denken wir aus Sicht der Schnittstelle darüber nach. Es gibt einige unbekannte Arten von IDs und Passwörtern. Diese Benutzertabelle enthält Begriffe, mit denen Sie Zeichenfolgen in Bezeichner und Kennwörter umwandeln können, nicht jedoch umgekehrt. Wir haben diese beiden Methoden, um zuerst die Anmeldung einzugeben, und es wird überprüft, welcher Benutzer zu diesem Zeitpunkt angemeldet ist. Haben Sie Fragen dazu?
Student: Müssen Sie die Benutzertabelle erweitern?
Professor: Ich mache das, weil ich es später als Fremdschlüssel verwenden möchte, also ist dies kein wichtiger Grund. Wir sind also fast an dem Punkt angelangt, an dem ich Ihnen den CSRF-Schutz in Aktion zeigen kann.
Zunächst ist das Anmelden am System recht einfach. Was können wir an dieser Stelle im Programm noch tun? Fügen wir hier einfach einen weiteren Teil der Seite hinzu, der besagt, dass Sie hier das Login eingeben. Hier müssen Sie den Benutzernamen und das Passwort eingeben und dann auf die Schaltfläche Aktion senden klicken. Diese Aktion ruft die Anmeldefunktion auf.

Definieren wir Login als eine Funktion, die diese Dinge tut. Tatsächlich handelt es sich nur um einen Wrapper zum Aufrufen der Anmeldefunktion aus diesem Modul, in dem wir jede der Komponenten nehmen und von einer Zeichenfolge in einen abstrakten Typ konvertieren.

Sie sucht nach einem Lesefehler. Der Fehler bedeutet, dass, wenn die Anmeldung nicht funktioniert, der Vorgang an dieser Stelle unterbrochen wird und die Funktion zum Hauptteil des Programms zurückkehrt.
Jetzt können wir uns einloggen. Wir werden wahrscheinlich ein Konto erstellen wollen, mit dem wir uns anmelden können. Lassen Sie mich also einen Benutzer mit dem Benutzernamen a und dem Passwort a erstellen.


Jetzt kann ich mich als Benutzer einloggen, mein Wort dafür nehmen. Wir haben eine Reihe von Cookies, um diese Informationen aufzuzeichnen. Gehen wir also in den Chatraum und senden Sie eine Nachricht, zum Beispiel asfasf. Sie sehen, dass nach dem Klicken auf die Schaltfläche Hinzufügen im Chat angezeigt wird.

Tatsächlich haben wir hier keine Zugriffskontrolle hinzugefügt, sodass hier nichts Besonderes passiert. Aber wir können überprüfen.

Es gibt hier Cookies, aber das System hat festgestellt, dass wir keine Cookies verwenden. Wenn wir dieses Formular senden, ist der Cookie nicht lesbar. Daher ist es bisher nicht erforderlich, hier einen CSRF-Schutz hinzuzufügen. Jetzt müssen wir eine Möglichkeit hinzufügen, Cookies zu verwenden und zu sehen, wie sich der Schutz manifestiert.
Student: Was ist Cookie-Inhalt?
Professor: Dies ist der Inhalt, den Sie vom Code erwarten. Mit anderen Worten, das Cookie hat den Typ dieses Datensatzes - Kennung und Kennwort.

Genau das ist dort also in einer bestimmten serialisierten Form enthalten. Verwenden wir jetzt tatsächlich Cookies. Wir sollten dies sehen, obwohl wir das Cookie indirekt verwenden werden, da wir es im Raummodul verwenden werden, was nichts mit Cookies zu tun hat. Wir werden jedoch benutzerdefinierte Modulmethoden aufrufen, die indirekt mit der Verwendung von Cookies zusammenhängen. Und dann wird das System verstehen, dass dies bedeutet, dass wir davon abhängig sind.
Machen wir es also ganz einfach und rufen die whoami-Methode auf. Tatsächlich werde ich es einfach ignorieren oder umgekehrt, lass ihn etwas tun. Lassen Sie uns entscheiden, dass der von uns erstellte Benutzer wirklich etwas Besonderes ist und nur dieser Benutzer etwas posten kann. Ist dies nicht der Fall, erhalten wir eine Fehlermeldung.

Ich werde dem Benutzermodul eine ID hinzufügen, und dann sollte dies funktionieren, da der ID-Typ die Gleichheitsprüfung unterstützt.

Jetzt sollte alles in Ordnung sein, und wir können mit dieser ID mehr tun, was einige Sicherheitsprobleme verursachen kann.

Auf diese Weise können wir eine Zugriffskontrollprüfung hinzufügen. Sehen wir uns also an, wie dies funktioniert, und kehren zur Hauptseite zurück.

Nun erschienen diese vier Buchstaben "a" im Chat.
In der Schnittstellenkonsole sehen wir, dass das Formular jetzt automatisch den versteckten Eingabenamen sig erhalten hat, der die kryptografische Signatur der Werte aller Cookies darstellt. Dieses Sig signierte Cookies mit einem Schlüssel, der für den Server geheim ist. Und wenn das Formular fertig ist, weiß die Anwendung - weil der Compiler es ihm mitgeteilt hat -, dass die Anwendung die Signaturen für die nächsten Operationen überprüfen sollte. Dafür haben wir ein Mitspracherecht.
Student: Haben die Unterschriften eine Art Zeitstempel?
Professor: Nein, Unterschriften haben keine Zeitstempel.
Student: In diesem Fall könnte ein Angreifer, der es geschafft hat, diese Daten auszuspionieren, vorgeben, ein Benutzer zu sein, da diese Cookies niemals ablaufen.
Professor: Ja, es läuft nie ab. Dies kann geändert werden, indem einfach die Sprachimplementierung geändert wird, ohne die Anwendungen zu ändern, und diese dann schnell bereitgestellt wird. Aber jetzt ist das nicht hier. Und ich verstehe, warum dies nützlich wäre, um hinzuzufügen.
Student: Sie können dies auch beheben, indem Sie einfach einen Zeitstempel auf die Signatur setzen.
Professor: Ja, Sie haben Recht, Sie können die Anwendung so ändern, dass die Cookie-Daten absichtlich oft genug geändert werden, dh die Signatur läuft ab.
Student: Können Sie URLs neu zuweisen?
Professor: Ja, welche Neuzuweisung möchten Sie sehen?
Student: Ich möchte nur sehen, wie das gemacht wird.
Professor: Also, der Compiler weist zu ... wie wir sehen, haben wir die Funktion say aufgerufen, und dieser Funktionsaufruf wird als eine bestimmte Form von URL serialisiert. Angenommen, wir mögen dieses Formular nicht.

Wir beschlossen, die URL sozusagen innerhalb des Raummoduls und innerhalb der Demo neu zu schreiben. Besser dranbleiben. Also wollen wir die URL Demo / Room / say zu Demo / Room / Speak neu zuweisen.

Wir starten den Compiler und gehen zum Hauptbildschirm der Anwendung. Mal sehen, was passiert. Alles ist in Ordnung, wir können auch beliebige Textnachrichten eingeben und diese erscheinen in der Chat-Zeile. In diesen Regeln können Sie unvorhersehbare Zeichen verwenden, um ein Präfix durch ein anderes zu ersetzen. Der Compiler stellt sicher, dass jede Funktion über ein separates URL-Schema verfügt. Die URL wird jedoch standardmäßig automatisch generiert.
Student: Sie haben erwähnt, dass HTML nicht spezifisch für den Compiler ist, sondern nur eine Bibliothek. Gibt es andere Bibliotheken für andere Formate?
Professor: Es gibt andere Bibliotheken, die den Typ nicht mit der gleichen funktionalen Vollständigkeit prüfen, aber zum Beispiel gibt es eine Bibliothek zum Serialisieren und Deserialisieren von JSON und eine große Anzahl automatisierter Methoden zum Verwalten der Typstruktur. Auf diese Weise können Sie Dinge tun, die nicht in den Compiler integriert sind.
Student: Nehmen wir an, wir möchten immer noch in JavaScript schreiben, um beispielsweise einige Dinge auf der Seite zu animieren ...
Professor: Lassen Sie mich die Ajax-Version herunterladen, die Ihre Frage beantwortet. Diese Version enthält clientseitigen Code. Fahren wir einfach mit einer Version des Programms namens demo3 fort. Ich habe die Daten auf der Hauptseite in der Chat-Zeile eingegeben und sie wurden auch am Ende des Chats angezeigt. Ob Sie es glauben oder nicht, diesmal funktionierte das Add-In mit einem Ajax-Aufruf. Dies ist auf den Wert der Schaltflächenkennzeichnung zurückzuführen. Es verfügt über ein Onclick-Attribut. Wenn der Benutzer auf die Schaltfläche klickt, funktioniert der gesamte Code unterhalb der Zeile mit diesem Attribut auf der Clientseite.

]]
Dies ist jedoch Ur / Web-Code, dies ist kein JavaScript-Code. Der Compiler übersetzt dies für Sie in JavaScript und stellt sicher, dass die gewünschten Eigenschaften für Abstraktionen in unserer Liste gespeichert werden, wenn der Benutzer nicht manuell im Browser daran basteln möchte.
Student: Ich denke, dass es heute viele Bibliotheken gibt, die nützliche und in vielen Fällen komplexe Dinge tun, wenn Sie alles selbst neu codieren möchten. Gibt es eine Möglichkeit, mit JavaScript aus Ur / Web zu interagieren?
Professor: Ja, es gibt eine externe Funktionsschnittstelle, über die Sie JavaScript-Funktionsnamen und -Aufrufen Ur / Web-Funktionsnamen zuweisen können. Wenn Sie jedoch die Schnittstelle einer externen Funktion verwenden, können Sie nicht mehr alle diese nützlichen Konstruktionsfunktionen verwenden. In diesem Fall müssen Sie sehr vorsichtig sein.
Sie müssen die Implementierung einiger dieser Abstraktionen verstehen, um sie nicht zu beeinträchtigen. Solange ich diesen Code habe, möchte ich Ihnen etwas anderes zeigen.
Wir haben immer noch die gleiche Funktion wie zuvor. Aber jetzt, anstatt es als Referenz aufzurufen, nehmen wir nur einen Funktionsaufruf, der mit Argumenten gefüllt ist, die aus dem Kontext des Onclick-Handlers stammen.

Wir verpacken diese Funktion einfach in die RPC-Syntax. Dies bedeutet, dass dies eine clientseitige Anruffunktion ist, der Aufruf selbst jedoch auf dem Server mit Zugriff auf die Datenbank und andere Serverressourcen gestartet wird und das Ergebnis dann hierher zurück überträgt.
, , JavaScript .
, . , , , .

, , , . , , .
, - , . GUI , , , , .
, , , . , DOM. , , .

, GUI, , , , .
, , .
: ?
: , , . , - .
: . , ?
: — . , . , , . , .
: — Ur?
: Ur — , , . , . .
.
Vielen Dank für Ihren Aufenthalt bei uns. Gefällt dir unser Artikel? Möchten Sie weitere interessante Materialien sehen? Unterstützen Sie uns, indem Sie eine Bestellung
aufgeben oder Ihren Freunden empfehlen, einen
Rabatt von 30% für Habr-Benutzer auf ein einzigartiges Analogon von Einstiegsservern, das wir für Sie erfunden haben: Die ganze Wahrheit über VPS (KVM) E5-2650 v4 (6 Kerne) 10 GB DDR4 240 GB SSD 1 Gbit / s von $ 20 oder wie teilt man den Server? (Optionen sind mit RAID1 und RAID10, bis zu 24 Kernen und bis zu 40 GB DDR4 verfügbar).
VPS (KVM) E5-2650 v4 (6 Kerne) 10 GB DDR4 240 GB SSD 1 Gbit / s bis Dezember kostenlos, wenn Sie für einen Zeitraum von sechs Monaten bezahlen, können Sie
hier bestellen.
Dell R730xd 2 mal günstiger? Nur wir haben
2 x Intel Dodeca-Core Xeon E5-2650v4 128 GB DDR4 6 x 480 GB SSD 1 Gbit / s 100 TV von 249 US-Dollar in den Niederlanden und den USA! Lesen Sie mehr über
den Aufbau eines Infrastrukturgebäudes. Klasse mit Dell R730xd E5-2650 v4 Servern für 9.000 Euro für einen Cent?