Institut de technologie du Massachusetts. Cours magistral # 6.858. "Sécurité des systèmes informatiques." Nikolai Zeldovich, James Mickens. 2014 année
Computer Systems Security est un cours sur le développement et la mise en œuvre de systèmes informatiques sécurisés. Les conférences couvrent les modèles de menace, les attaques qui compromettent la sécurité et les techniques de sécurité basées sur des travaux scientifiques récents. Les sujets incluent la sécurité du système d'exploitation (OS), les fonctionnalités, la gestion du flux d'informations, la sécurité des langues, les protocoles réseau, la sécurité matérielle et la sécurité des applications Web.
Cours 1: «Introduction: modèles de menace»
Partie 1 /
Partie 2 /
Partie 3Conférence 2: «Contrôle des attaques de pirates»
Partie 1 /
Partie 2 /
Partie 3Conférence 3: «Débordements de tampon: exploits et protection»
Partie 1 /
Partie 2 /
Partie 3Conférence 4: «Séparation des privilèges»
Partie 1 /
Partie 2 /
Partie 3Conférence 5: «D'où viennent les systèmes de sécurité?»
Partie 1 /
Partie 2Conférence 6: «Opportunités»
Partie 1 /
Partie 2 /
Partie 3Conférence 7: «Native Client Sandbox»
Partie 1 /
Partie 2 /
Partie 3Conférence 8: «Modèle de sécurité réseau»
Partie 1 /
Partie 2 /
Partie 3Conférence 9: «Sécurité des applications Web»,
partie 1 /
partie 2 /
partie 3Conférence 10: «Exécution symbolique»
Partie 1 /
Partie 2 /
Partie 3Conférence 11: «Ur / Web Programming Language»
Partie 1 /
Partie 2 /
Partie 3 La dernière chose que nous devons faire et qui sera très instructive est de changer ce code en y indiquant le module de salle, puis d'essayer d'accéder à la table de salle, comme dans l'exemple précédent. Cette option n'est pas autorisée car elle n'est pas autorisée.

Ce serait comme pouvoir lire et écrire des champs de classe privés en Java. En effet, nous obtenons un message assez simple, disant essentiellement que nous avons ici une variable non liée, une expression inconnue pour le paramètre de pièce.

Nous pourrions mentionner ce module complémentaire, que nous avons créé juste pour le plaisir.

Mais alors ce seront des tableaux différents. Nous pouvons facilement y accéder. Par conséquent, je vais le diviser en deux parties, nous commencerons par appeler simplement la méthode room, puis ferons une chose légèrement différente pour lire ses éléments.

Afficher une liste de résultats, et non l'inverse, cela équivaut à peu près à la façon dont le programme fonctionnait auparavant, à l'exception de l'utilisation de divers types de données. Voyons ce qui en résulte. Maintenant, nous revenons à notre chat dans la salle 1 et entrons tous les messages dans la ligne. Vous voyez qu'ils sont tous affichés sans erreur.

Autrement dit, nous avons maintenant cette encapsulation, vous pouvez donc penser à la structure de cette pièce comme une bibliothèque, mais vous n'avez pas à vous en préoccuper.
Il existe différents endroits qui peuvent endommager l'invariance interne d'un système. Peut-être que vous voulez qu'après l'ajout du message, il ne disparaisse jamais. Tout cela est dans les magazines. Cette structure fournit de telles propriétés indépendamment d'un autre code, tel que celui sur lequel le module de salle de conversation est écrit.
Étudiant: vous avez donc changé la définition de la pièce, qu'arriverait-il à la table de base de données dans ce cas?
Professeur: vous devez exécuter manuellement la commande alter table si vous souhaitez conserver les anciennes données. Mais lorsque l'application démarre, elle interroge le répertoire de la base de données système et vérifie que le schéma est toujours comme prévu. Vous obtiendrez alors une erreur statique. J'espère que cela vous donne une idée de ce que vous devez changer dans la base de données.
Étudiant: mais cela ne supprimera pas automatiquement la base de données ou quelque chose comme ça?
Professeur: J'espère que non. Je ne pense pas que le compilateur devrait faire cela. Vous pouvez imaginer personnaliser le compilateur pour comprendre l'évolution de la base de données. Je pense que vous devez écrire des commandes alter table pour démarrer, car le compilateur ne le fait pas pour le moment.

Parlons maintenant de la falsification de requêtes intersites et de sa prévention. En fait, avant de faire cela, regardons le code sur cette page. Nous avons un formulaire HTML traditionnel qui est généré ici. Et, bien sûr, il n’existe aucune protection contre la falsification de demandes intersites, et je pense que c’est bien. Parce que, si je comprends bien, le problème de la falsification des demandes intersites est le contexte implicite que l'application envoie avec chaque demande.
Supposons qu'il existe une sorte d'attaquant qui ne connaît pas votre contexte implicite. Supposons que votre mot de passe soit stocké dans un cookie, pour un exemple très simple. Et lorsque l'attaquant vous trompe en cliquant sur le lien vers l'application dont il a besoin, le navigateur envoie automatiquement un contexte implicite et force l'application à faire ce que l'attaquant ne pourrait pas faire directement.

Dans ce cas, il n'y a pas de contexte implicite, il n'y a donc aucun risque de falsification des requêtes intersites. Quelqu'un veut-il contester cette fonctionnalité du système avant de continuer? Cela peut être très instructif pour moi. Sinon, ajoutez ici un contexte implicite. Dans ce cas, le système va automatiquement prendre les bonnes contre-mesures, sur la base de l'analyse du programme, qui comprend qu'il existe désormais un contexte implicite.
Maintenant, je vais insérer des cookies ici. Comme autre exemple d'encapsulation de module, en fait, je vais mettre ici un système d'authentification utilisateur complet dans lequel nous avons des comptes utilisateur et des types abstraits d'identifiants et de mots de passe. Par conséquent, vous ne pouvez pas simplement créer directement la valeur de l'un de ces types de données. Vous devrez suivre une méthode approuvée de construction de valeurs de ces types.
Je vais placer la table directement dans la signature. Et je vais également lui imposer une restriction, en disant que la clé est le formulaire d'identification.

Mais le fait est que dans cette table utilisateur, l'ID et le mot de passe sont des types de données abstraits. Par conséquent, le code ne peut pas voir le mot de passe et ne peut pas générer systématiquement tous les identifiants et les essayer dans ce tableau. Parce qu'il utilise un type abstrait, à cause duquel il est impossible d'établir à quoi ressemble l'ID et il est impossible de trouver un mot de passe. Ils viennent juste de cette table, et ce sont des jetons opaques.
Mais nous pourrions leur permettre d'être des eaux usées. Vous souhaiterez peut-être autoriser une direction de conversion entre les chaînes et ces types. Maintenant, je vais faire quelque chose ici, principalement les détails, et je ne vais pas essayer de les expliquer. Mais cela revient à déclarer que vous êtes autorisé à convertir des chaînes en ID. Pour ceux qui connaissent Haskell, il s'agit d'une classe de type instantané, cette autorisation de transformer les chaînes en ID.

Nous n'allons pas appliquer une autre autorisation, car nous ne voulons pas pouvoir reconvertir l'ID en autre chose. Faisons de même pour le mot de passe. Nous voulons pouvoir lire le mot de passe de l'utilisateur, mais nous n'allons pas accepter le mot de passe et le transformer en une chaîne qui nous dira que l'utilisateur est entré dans le chat.
Ainsi, d'autres parties du code pourront accepter le mot de passe de l'utilisateur, le convertir en ce type et le transporter vers le module utilisateur pour vérification. Mais ce qu'ils ne peuvent pas faire, c'est interroger la table des utilisateurs et obtenir tous les mots de passe sous une forme à partir de laquelle ils peuvent extraire leur expression textuelle.
Ensuite, nous pouvons avoir une méthode de connexion qui accepte ces deux composants, l'ID et le mot de passe, et fonctionne simplement comme un effet secondaire, qui est en fait indiqué dans le code. Nous aurons également besoin d'un moyen de savoir quel utilisateur est enregistré. Il s'agit du code qui exécute la transaction qui crée l'ID.

La première étape consiste à copier simplement cette définition. Et puis vient une surprise. Il s'avère que les ID utilisateur et les mots de passe sont des chaînes, mais cette circonstance ne sera pas divulguée en dehors du module.

Nous allons maintenant créer des cookies. Les cookies sont une autre chose qui est intégrée dans la langue. En fait, ils agissent comme des variables globales mutables qui ont une copie pour chaque client qui utilise votre application.
Ainsi, nous allons créer un cookie qui pour chaque utilisateur stockera simplement une copie des deux mêmes champs que nous avons ici.

Ces cookies sont privés de ce module. Les autres parties du code ne pourront pas lire les cookies car ils n'ont tout simplement pas ce champ privé. Ainsi, personne ne pourra voir directement l'ID et le mot de passe enregistrés pour cet utilisateur. Mais ils seront enregistrés lors de l'affichage de différentes pages, comme c'est le cas avec les cookies ordinaires.
Maintenant, je vais insérer la fonction de connexion, qui lancera le processus pour vérifier la base de données et savoir s'il s'agit vraiment de la bonne paire de nom d'utilisateur et de mot de passe. Ce processus vérifiera simplement si nous pouvons trouver une ligne dans la base de données contenant cet ID utilisateur et ce mot de passe.
Si nous le trouvons, alors bon, alors c'est le sens correct. Disons simplement enregistrer cela dans les cookies. Nous utilisons une méthode qui modifie la valeur d'un cookie. Et nous devons mettre certaines choses ici, pour simplifier je dirai que ce cookie n'expire pas. Je ne veux pas exécuter SSL ici, donc je dirai que dans ce cas, nous n'avons pas besoin de sécurité et définissez le paramètre Secure = false.
Mais si vous vous souciez vraiment de la sécurité, vous écrirez évidemment Secure = true. Si la vérification échoue et que le module signale une erreur, le programme s'arrête et donne une description de cette erreur.

Enfin, nous pouvons créer cette fonction qui indique quel utilisateur particulier est connecté en recevant la valeur actuelle du cookie. Ce paramètre peut également être défini sur aucun si l'utilisateur ne s'est pas encore connecté, auquel cas nous obtiendrons un autre message d'erreur. Ou cela pourrait être une sorte d'enregistrement du type exact que nous avons utilisé ci-dessus. Je viens donc de le copier ici et d'exécuter le même contrôle. Si cela fonctionne, nous renvoyons simplement la partie de l'enregistrement ID que nous venons de vérifier dans la base de données.

Alors laissez-moi vérifier cela. Nous démarrons le compilateur et vous voyez le résultat à l'écran.

Au cœur de tous ces détails de mise en œuvre. Mais en dehors de ce module, on y pense du point de vue de l'interface. Il existe certains types d'ID et de mots de passe inconnus. Ce tableau utilisateur exprime des termes qui vous permettent de transformer des chaînes en identificateurs et mots de passe, mais pas l'inverse. Nous avons d'abord ces deux méthodes pour entrer la connexion et il y a une vérification de l'utilisateur qui est connecté à ce stade. Vous avez des questions à ce sujet?
Étudiant: Avez-vous besoin d'étendre la table des utilisateurs?
Professeur: Je fais cela parce que je veux l'utiliser plus tard comme clé étrangère, donc ce n'est pas une raison importante. Donc, nous sommes presque au point où je peux vous montrer la protection CSRF en action.
Pour commencer, la connexion au système est assez simple. Eh bien, que pouvons-nous faire d'autre à ce stade du programme? Ajoutons simplement ici une autre partie de la page qui dit que c'est là que vous entrez la connexion. Ici, vous devez entrer le nom d'utilisateur et le mot de passe, puis cliquer sur le bouton d'action de soumission. Cette action fournira un appel à la fonction de connexion.

Définissons la connexion comme une fonction qui fait ces choses. En fait, c'est juste un wrapper autour de l'appel de la fonction de connexion à partir de ce module, dans lequel nous prenons chacun des composants et le convertissons d'une chaîne en un type abstrait.

Elle vérifie une erreur de lecture. L'erreur signifie que si la connexion ne fonctionne pas, l'opération sera interrompue à ce stade et la fonction reviendra à la partie principale du programme.
Maintenant, nous pouvons nous connecter. Nous voudrons probablement créer un compte qui nous permettra de nous connecter, alors laissez-moi créer un utilisateur avec un nom d'utilisateur et un mot de passe a.


Maintenant, je peux me connecter en tant qu'utilisateur a, croyez-moi. Nous avons un ensemble de cookies pour enregistrer ces informations, alors allons dans la salle de chat et envoyons un message, par exemple, asfasf. Vous voyez qu'après avoir cliqué sur le bouton Ajouter, il est apparu dans le chat.

En fait, nous n'avons ajouté aucun contrôle d'accès ici, donc rien de spécial ne se produit ici. Mais nous pouvons vérifier.

Il y a des cookies ici, mais le système a déterminé que nous n'utilisons pas de cookies. Lorsque nous soumettons ce formulaire, le cookie n'est pas lisible. Ainsi, jusqu'à présent, il n'est pas nécessaire d'ajouter ici une protection CSRF. Donc, maintenant, nous devons ajouter un moyen d'utiliser les cookies et voir comment la protection se manifestera.
Étudiant: qu'est-ce que le contenu des cookies?
Professeur: c'est le contenu que vous vous attendez à recevoir du code. En d'autres termes, le cookie est déclaré comme ayant le type de cet enregistrement - identifiant et mot de passe.

C'est donc exactement ce qui y est contenu sous une certaine forme sérialisée. Maintenant, utilisons des cookies. Nous devrions voir cela, malgré le fait que nous allons utiliser le cookie indirectement, car nous allons l'utiliser dans le module de salle, qui n'a rien à voir avec les cookies. Mais nous appellerons des méthodes de module personnalisées qui sont indirectement liées à l'utilisation de cookies. Et puis le système comprendra que cela signifie que nous en dépendons.
Alors, faisons-le très simplement et appelons la méthode whoami. En fait, je vais juste l'ignorer, ou vice versa, le laisser faire quelque chose. Décidons que l'utilisateur que nous avons créé est vraiment spécial, et seul cet utilisateur peut publier n'importe quoi. Si ce n'est pas le cas, nous obtiendrons un message d'erreur.

J'ajouterai un ID au module utilisateur, puis cela devrait fonctionner, car le type d'ID prend en charge la vérification d'égalité.

Maintenant, tout devrait être en ordre, et nous pouvons faire plus de choses avec cet ID, ce qui peut entraîner des problèmes de sécurité.

Cela nous permet d'ajouter une vérification de contrôle d'accès, alors voyons comment cela fonctionne et revenons à la page principale.

Maintenant, ces quatre lettres "a" sont apparues dans le chat.
Dans la console d'interface, nous voyons que le formulaire a maintenant reçu automatiquement le nom d'entrée caché sig, qui est la signature cryptographique des valeurs de tous les cookies. Cette signature a signé les cookies à l'aide d'une clé secrète pour le serveur. Et lorsque le formulaire est prêt, l'application sait - parce que le compilateur l'a informé - que l'application doit vérifier les signatures pour le prochain ensemble d'opérations. Pour cela, nous avons une opération de dire.
Étudiant: les signatures ont-elles une sorte d'horodatage?
Professeur: non, les signatures n'ont pas d'horodatage.
Étudiant: dans ce cas, si un attaquant réussissait à "espionner" ces données, il pourrait prétendre être un utilisateur, car ces cookies n'expirent jamais.
Professeur: oui, il n'expire jamais. C'est quelque chose qui peut être changé en changeant simplement l'implémentation du langage sans changer les applications, puis en le déployant rapidement. Mais maintenant, ce n'est pas ici. Et je comprends pourquoi cela serait utile d'ajouter.
Étudiant: vous pouvez également résoudre ce problème en plaçant simplement un horodatage sur la signature.
Professeur: oui, vous avez raison, vous pouvez modifier l'application de manière à modifier intentionnellement les données des cookies assez souvent, c'est-à-dire faire expirer la signature.
Étudiant: pouvez-vous réaffecter des URL?
Professeur: oui, quelle réaffectation aimeriez-vous voir?
Étudiant: tout, je veux juste voir comment cela se fait.
Professeur: Donc, le compilateur attribue ... comme nous le voyons, nous avons appelé la fonction say, et cet appel de fonction est sérialisé en tant que forme spécifique d'URL. Supposons que nous n'aimons pas ce formulaire.

Nous avons décidé que nous allions réécrire l'URL, pour ainsi dire, à l'intérieur du module de salle, à l'intérieur de la démo. Mieux vaut le coller. Nous voulons donc réaffecter l'URL Demo / Room / say à Demo / Room / Speak.

Nous démarrons le compilateur et allons à l'écran principal de l'application. Voyons ce qui se passe. Tout est en ordre, nous pouvons également saisir des messages texte et ils apparaissent dans la ligne de discussion. Vous pouvez utiliser des caractères imprévisibles dans ces règles pour remplacer un préfixe par un autre, et le compilateur s'assurera que chaque fonction a un schéma d'URL distinct, mais l'URL est automatiquement générée par défaut.
Étudiant: vous avez mentionné que HTML n'est pas spécifique au compilateur, c'est juste une bibliothèque. Existe-t-il d'autres bibliothèques pour d'autres formats?
Professeur: il existe d'autres bibliothèques qui ne vérifient pas le type avec la même exhaustivité fonctionnelle, mais, par exemple, il existe une bibliothèque pour sérialiser et désérialiser JSON, et un grand nombre de moyens automatisés pour gérer la structure de type. De cette façon, vous pouvez faire des choses qui ne sont pas intégrées au compilateur.
Étudiant: supposons que nous voulions toujours écrire en JavaScript, par exemple, pour animer certaines choses sur la page ...
Professeur: laissez-moi télécharger la version Ajax de cela, qui répondra à votre question. Cette version a du code côté client. Passons à une version du programme appelée demo3. J'ai entré les données sur la page principale de la ligne de discussion, et elles sont également apparues au bas de la discussion. Croyez-le ou non, cette fois, le complément a fonctionné à l'aide d'un appel Ajax. Cela est dû à la valeur du bouton de la balise bouton. Il possède un attribut onclick qui, lorsque l'utilisateur clique sur le bouton, tout ce code sous la ligne avec cet attribut fonctionne du côté client.

]
Mais c'est du code Ur / Web, ce n'est pas du code JavaScript. Le compilateur traduit cela en JavaScript pour vous et s'assure qu'il enregistre les propriétés que nous voulons pour les abstractions dans notre liste si l'utilisateur ne veut pas bricoler manuellement dans le navigateur.
Étudiant: Je pense qu'aujourd'hui, il existe de nombreuses bibliothèques qui font des choses utiles, et dans de nombreux cas des choses complexes, si vous voulez tout recoder vous-même. Existe-t-il un moyen d'interagir avec JavaScript depuis Ur / Web?
Professeur: oui, il existe une interface de fonction externe qui vous permet de donner des noms de fonction Ur / Web aux noms de fonction JavaScript et aux appels. Mais lorsque vous utilisez l'interface d'une fonction externe, vous ne pouvez plus utiliser toutes ces fonctions de construction utiles. Dans ce cas, vous devez être très prudent.
Vous devez comprendre la mise en œuvre de certaines de ces abstractions afin de ne pas interférer avec elles. Tant que j'ai ce code, permettez-moi de vous montrer autre chose.
Nous avons toujours la même fonction de dire qu'auparavant. Mais maintenant, au lieu de l'appeler par référence, nous prenons simplement un appel de fonction qui est rempli d'arguments provenant du contexte du gestionnaire onclick.

Nous enveloppons simplement cette fonction dans la syntaxe rpc. Cela signifie qu'il s'agit d'une fonction d'appel côté client, mais l'appel lui-même est lancé sur le serveur avec accès à la base de données et aux autres ressources du serveur, puis transfère le résultat ici.
Et il est écrit dans un style si simple qu'il ne nécessite pas de rappels, que vous devez généralement utiliser en JavaScript pour appeler un serveur distant.Le client peut effectuer un appel n'importe où dans le cadre de la fonction, à l'exception des champs privés masqués. Je veux dire, puisque la fonction est située à cet endroit du programme, elle peut appeler tous ceux dont les noms sont dans sa portée.
Il s'avère que ce nom n'est pas dans le champ d'application, nous n'avons donc pas pu appeler ici. Mais tout ce qui est dans le cadre de la fonction peut être appelé., - , . GUI , , , , .
, , , . , DOM. , , .

, GUI, , , , .
, , .
: ?
: , , . , - .
: . , ?
:la meilleure façon est d'amener les gens à utiliser ces choses et à signaler des bogues. C'est le meilleur conseil que je puisse vous donner. L'idée est que ces compilateurs devraient être écrits beaucoup moins fréquemment que les nouvelles applications. Parce qu'il recueille toutes les erreurs en un seul endroit et essaie de les éliminer, même si cela ne se produit pas de la manière la plus efficace.Étudiant: pourquoi avez-vous choisi un tel nom pour votre langue - Ur?Professeur: Ur est un concept de la linguistique, le nom de la langue qui est l'ancêtre de la langue moderne. Et l'idée est que cette langue vous permet d'insérer toutes sortes d'autres langues à l'intérieur. C'est donc une sorte de progéniteur de toutes les langues.La version complète du cours est disponible ici .Merci de rester avec nous. Aimez-vous nos articles? Vous voulez voir des matériaux plus intéressants? Soutenez-nous en passant une commande ou en le recommandant à vos amis, une
réduction de 30% pour les utilisateurs Habr sur un analogue unique de serveurs d'entrée de gamme que nous avons inventés pour vous: Toute la vérité sur VPS (KVM) E5-2650 v4 (6 cœurs) 10 Go DDR4 240 Go SSD 1 Gbps à partir de 20 $ ou comment diviser le serveur? (les options sont disponibles avec RAID1 et RAID10, jusqu'à 24 cœurs et jusqu'à 40 Go de DDR4).
VPS (KVM) E5-2650 v4 (6 cœurs) 10 Go DDR4 240 Go SSD 1 Gbit / s jusqu'en décembre gratuitement en payant pour une période de six mois, vous pouvez commander
ici .
Dell R730xd 2 fois moins cher? Nous avons seulement
2 x Intel Dodeca-Core Xeon E5-2650v4 128 Go DDR4 6x480 Go SSD 1 Gbps 100 TV à partir de 249 $ aux Pays-Bas et aux États-Unis! Pour en savoir plus sur la
création d'un bâtiment d'infrastructure. classe utilisant des serveurs Dell R730xd E5-2650 v4 coûtant 9 000 euros pour un sou?