Il y a les wtfs évidents qui font les gros titres comme l'injection SQL, l'authentification en JavaScript, mais y a-t-il d'autres erreurs plus fondamentales et communes que les programmeurs ont tendance à faire lorsqu'ils écrivent des applications sans tenir compte de la sécurité ?
Réponses
Trop de publicités?Il y a déjà beaucoup de bonnes suggestions tactiques. Permettez-moi de formuler une observation stratégique. La plupart des applications sont écrites dans l'optique de sécurité par défaut de "tout autoriser". Cela signifie qu'un programmeur commencera à coder tout ce qui est ouvert, puis (avec un peu de chance) commencera à prendre en compte les éléments qui doivent être sécurisés (les suggestions tactiques qui ont déjà été faites en sont de formidables exemples).
Cela se produit dans tous les domaines. Tout, des systèmes d'exploitation aux clients lourds en passant par les clients légers basés sur le Web, est construit de cette manière. C'est l'une des principales raisons pour lesquelles Microsoft publie chaque mardi un ensemble de correctifs. Les vulnérabilités continuent d'être découvertes et doivent être corrigées dans un flux incessant de correctifs.
Ma suggestion stratégique est la suivante : commencez à coder dans une perspective par défaut de "tout nier". Chaque élément architectural, chaque couche, chaque objet, chaque méthode, chaque variable... construisez-les pour qu'ils soient inaccessibles à quoi que ce soit, à moins que vous ne l'autorisiez expressément. Cela ralentira un peu votre productivité (du moins au début). Cependant, une fois que vous vous serez habitué à penser de cette façon, le code que vous livrerez sera beaucoup plus sûr.
Une autre analogie à cela est lorsqu'un programmeur décide que les tests unitaires sont une bonne chose. Ou peut-être même TDD si vous voulez aller à l'extrême de ce spectre. Il faut beaucoup plus de travail pour écrire d'abord le test unitaire, puis le code pour faire passer le test, que pour écrire simplement le code. Mais le résultat final est un ordre de grandeur plus stable, et on pourrait dire que, globalement, moins de temps est passé à rechercher les défauts lorsqu'un investissement intelligent dans les tests unitaires est fait.
Les trois premiers qui me viennent à l'esprit sont :
- Pas de validation chaque bit de données du client
- Ne pas tenir compte des permissions du système de fichiers lorsqu'on travaille avec des fichiers
- Laisser un accès trop large à la base de données (lecture/écriture alors qu'un utilisateur n'a besoin que d'un accès en lecture)
Un autre problème qui n'est pas vraiment un problème de sécurité, bien qu'il soit lié à la sécurité, est l'incapacité totale et abjecte à comprendre la différence entre le hachage d'un mot de passe et son cryptage. On le trouve le plus souvent dans du code où le programmeur essaie de fournir une fonctionnalité non sécurisée de "rappel du mot de passe".
Voilà ce que je peux trouver :
- Défaut d'examen du code. Il va sans dire que la plupart du code non sécurisé écrit aujourd'hui existe en raison de l'absence de révision du code par les bonnes personnes. Les revues de code pour la sécurité sont différentes des revues de code pour la fonctionnalité.
- En supposant que vous ne serez pas attaqué. "Hé ! On est derrière un pare-feu, non ? Et c'est un réseau protégé."
- Obliger les utilisateurs à utiliser l'application d'une manière non sécurisée. Par exemple, la plupart des sites bancaires n'affichaient jamais le chrome du navigateur jusqu'à ce que des sites de phishing apparaissent.
- Ne pas comprendre les limites de la confiance. Il s'agit souvent d'une confiance aveugle imposée par le code côté serveur aux entrées côté client.
- Absence de séparation claire des préoccupations - le client finit par assumer le rôle du serveur. C'est souvent le cas lorsque les mots de passe sont validés en JavaScript, ou que les privilèges sont appliqués au client, etc.
- Ignorant le scénario de la falsification des demandes. Pire encore, soutenir que lesdites demandes ne peuvent pas être falsifiées.
- Ignorance des privilèges requis dans l'environnement d'exécution. Cela se manifeste souvent par des "notes" dans la documentation sur les privilèges à fournir, sans détails suffisants sur la raison pour laquelle ils sont requis. J'ai rencontré une applet qui exigeait que des privilèges de lecture et d'écriture sur l'ensemble du système de fichiers soient accordés à n'importe quelle base de code (même celles téléchargées depuis l'Internet), simplement pour télécharger un fichier sur le serveur.
- Valeurs par défaut non sécurisées. Par exemple, le mot de passe de l'administrateur système doit être défini manuellement après l'installation par un mot de passe fort, car l'installation n'a pas couvert le scénario des mots de passe d'administrateur faibles. Oui Microsoft, je vous regarde .
- La cryptographie maison. Bill vient de le noter. Ce n'est pas parce que le développeur le plus intelligent de l'entreprise ne peut pas craquer qu'un attaquant ne le peut pas. Une bonne sécurité est construite sur la base d'années d'efforts dans ce domaine par des mathématiciens et des scientifiques. Seul un imbécile penserait qu'il peut trouver quelque chose de mieux sous la douche d'une salle de bain.