Article rédigé dans le cadre de la Hacker's Challenge et sponsorisé par Radware

À l'origine des failles de sécurité, il y a le plus souvent, une erreur humaine. Et les développeurs sont (à quelques rares exceptions prêtes ) des humains.

Pourtant il existe quelques principes de base notamment recommandée par l'OWASP qui permettent de produire du code à minima sécurisé. Mais peu de développeurs prennent le temps d'intégrer et d'appliquer ces principes.

C'est d'ailleurs pour ça que le bug bounty et bountyfactory.io ont le vent en poupe, car au-delà d'aider les boites à mieux se sécuriser, il permet aussi aux développeurs de monter en compétences en se frottant à une véritable communauté d'experts en sécurité.

Souvenez-vous, en 2013, Adobe subissait une fuite de données impactant 38 millions de personnes. Cela a abouti à un procès et Adobe a dû payer 1 million de dollars (c'est peu) répartis entre 500 000 personnes dans 15 états américains.

Puis en 2015, Orange Business a vu fuiter plus de 9500 contacts pros (adresses postales, téléphones, noms de sociétés de responsables de comptes, responsables commerciaux, RSSI...etc.) à cause d'une erreur dans un formulaire, autorisant une injection SQL.

L'année d'après, ce fut au tour de la branche bancaire de Tesco (chaine de magasins en Angleterre) se voir 9000 comptes clients se faire piller à cause d'une faille de sécurité. Ce piratage a d'ailleurs provoqué une sérieuse chute du titre boursier de la société.

Plus récemment, vous vous souvenez peut-être aussi de DAO, cette plateforme reposant sur la blockchain Ethereum, qui utilise des smart contracts. Ce sont les lois qui régissent la plateforme et c'est le code qui fait la loi. Seulement, à cause d'une faille dans ce code, DAO a vu s'envoler dans la poche d'un gars plus malin que les autres, environ 56 millions de dollars. Ça doit piquer un peu.

Tous ces exemples montrent que négliger la sécurité de son code applicatif peut avoir de lourdes conséquences. Les risques sont assez simples à visualiser : Perte de confiance des clients (fuite de données personnelles), remise en cause de la réputation globale de la société (chute en bourse) et dans certains cas, cela peut même aider la concurrence (perte de code sensible et autres secrets industriels).

Évidemment, la société touchée perdra de l'argent et si la faille dans le code est vraiment énorme, j'image qu'on exigera des explications de la part des équipes de dev à l'origine de la négligence. Bref, c'est moche pour tout le monde.

Le développement sécurisé, c'est donc tout simplement :

N'accorder aucune confiance. Ni à vos utilisateurs, ni à vos admins systèmes, ni aux webservices externes que vous utilisez. Vous devez contrôler tout ce que vos utilisateurs et vos webservices vous communiquent, et vous ne devez pas vous reposer entièrement sur votre sysadmin en vous disant que "c'est bon, il a mis un firewall". Le WAF (Firewall applicatif) n'est pas votre maman et ne fera pas tout à votre place.

Garder en tête que quelqu'un, quelque part vous veut du mal. Non, vous n'êtes pas sous le radar, même si vous êtes une startup qui débute, même si personne ne connait votre application...etc. Il existe tellement de bots, de scanners de vuln ou de gens qui testent des trucs que forcement à un moment, quelqu'un essayera de contourner vos sécurités.

Devenir monomaniaque. Alors pas dans la vie privée bien sûr, mais quand il s'agit de code, vous devez adopter une vision pessimiste de la vie et réfléchir à la sécurité à chaque fois que vous pressez une touche de votre clavier.

De plus, il y a pas mal de mythes à combattre. Comme je le disais, le WAF ne fera pas tout. Aussi, les outils de crypto ou les frameworks que vous choisissez sont très importants pour monter le niveau de sécurité de votre application, mais ils ne sont pas magiques. Ce seront vos bonnes pratiques qui feront la différence.

Les pentests et autres audits sont importants, mais c'est par nature une intervention limitée en temps, et en ressources humaines donc vous ne pouvez pas non plus vous reposer uniquement là dessus pour sécuriser après coup votre code.

Enfin, ne négligez pas vos applications mineures. Tout ce que vous développez doit être soumis à la même rigueur, car de petites choses non sensibles en apparence peuvent servir de passerelle pour attaquer quelque chose de plus important, ou qui sais, peut être qu'un jour, ce code fait à l'arrache sur un prototype sera repris par quelqu'un pour être déployé sur une application un poil plus cruciale pour le business de votre société.

Heureusement, pour vous guider, l'OWASP a fait un formidable travail de recensement et grosso modo, le top 10 des failles les plus courantes sont :

  • XSS - Cross site scripting
  • CSRF / XSRF - vulnérabilité des services d'authentification web. (Cross-Site Request Forgery)
  • SQLi
  • et Clickjacking

Il y a évidemment beaucoup de bonnes pratiques donc je ne serai pas exhaustif, mais voici celles de base que vous devez respecter.

1 - Testez la sécurité de votre site le plus tôt possible et le plus souvent.

Dans la plupart des entreprises, les tests de sécurité se font hors process de développement. C'est un jeu d'aller-retour entre les développeurs et les pentesteurs. C'est bien, mais ce n'est pas ce qu'il y a de plus efficace.

Tout comme vous faites probablement des tests qualité, vous devez aussi faire des tests de sécurité sur votre propre code. Vous pouvez faire ça manuellement à l'aide de scénarios de tests ou avec des scanners automatiques. Dans un cadre de développement continu, c'est très important d'avoir ce réflexe de tester en permanence la sécurité de votre code.

2 - Les requêtes préparées

Les injections SQL sont l'un des risques les plus importants et les plus répandus quand on parle d'application web. Elles sont faciles à exploiter, peuvent se faire manière automatique et peuvent mener à de l'usurpation de compte voire à de l'extraction de données. Cela produit des catastrophes avec des mots de passe, emails, messages privés...etc. qui se retrouvent dans les mains de cyber criminels.

De plus, la base de données peut aussi être modifiée, voire totalement effacée.

Pour éviter cela, vous devez faire ce qui s'appelle des requêtes préparées (ou requêtes paramétrables). Il s'agit de requêtes SQL comme les autres, à la différence prête que les paramètres contenus dans celles-ci ont des types et des tailles définies. Cela permet d'éviter d'y mettre n'importe quoi.

La plupart des frameworks récents comme Rails, Django, NodeJS...etc. utilisent déjà de manière transparente les requêtes préparées, mais en tant que développeur vous devez rester prudent lorsque vous intégrez dans vos requêtes des contenus entrées par l'utilisateur.

Voyez aussi avec vos admins car il est possible de configurer les bases de données pour qu'elles acceptent uniquement des requêtes paramétrées.

3 - L'encodage des données

L'autre risque "star" c'est la faille XSS. Celle-là, vous en avez aussi tous entendu parler.

Dans le cadre d'une application dynamique, les développeurs réutilisent des données entrées par les utilisateurs pour ensuite les afficher dans les pages. Ces données doivent toujours être considérées comme dangereuses, car un attaquant pourrait y glisser un script de son cru, qui n'a rien à faire dans votre code et qui s'exécutera à chaque chargement de page.

Pour contrer cela, il faut systématiquement encoder chaque input. Par exemple, même si c'est un classique, htmlentities est une fonction PHP qui convertit tous les caractères en entités HTML, ce qui les rend inoffensifs.

4 - La validation des entrées

Comme on vient de le voir, chaque donnée qui arrive de l'extérieur doit être considérée comme à risque. Cela vaut pour les URL POST ou GET, mais aussi pour les cookies, les uploads de fichiers, les données récupérées via des webservices et j'en passe.

Pour éviter tout risque, il faut valider chacune de ces données. La solution la plus commune, ce sont les expressions régulières qui permettent par exemple de vérifier qu'une adresse email respecte bien le format xxx@domain.tld, ou encore qu'un code PIN contient bien uniquement 4 chiffres. Vous pouvez bien sûr écrire aussi vos propres méthodes de validation.

5 - L'authentification

L'authenfication, c'est le process qui consiste à valider que quelqu'un est bien celui qu'il dit être. La plupart du temps, ça se passe avec un login et un mot de passe.

Mais pourquoi se contenter de ça ?

Pour améliorer la sécurité de vos applications, vous pouvez mettre en place différentes choses.

Premièrement, de l'authentification multi facteur. Cela consiste à demander à un user plusieurs choses :

  • Quelque chose qu'il connait, par exemple un mot de passe.
  • Quelque chose qu'il possède, par exemple un code reçu par SMS ou généré par une application installée sur son téléphone
  • Et quelque chose de biométrique, comme une empreinte digitale

À vous de faire les combinaisons qui vous plaisent. Même chose évidemment pour récupérer un mot de passe perdu. Par exemple un email + un code envoyé par SMS.

Mais ce n'est pas tout. Afin d'assurer en termes de sécurité, il est aussi recommandé de hasher et saler les mots de passe contenus en base. Ainsi, en cas d'accès non autorisé à la base de données, l'attaquant ne pourra pas récupérer de mot de passe en clair.

6 - Le contrôle les accès

Évidemment, une fois loggé, votre utilisateur a accès à un certain nombre de données et de fonctions. Mais ce ne sont pas les mêmes selon son rôle. Un administrateur pourra par exemple supprimer des données alors qu'un utilisateur lambda ne le pourra pas.

Pour éviter tout problème, il est recommandé de tout lui refuser par défaut, qu'il ait le moins de privilèges possible, puis d'ouvrir chaque fonction selon son rôle. Ainsi en cas d'ajout postérieur de fonctionnalités dans votre code, vous devrez spécifiquement autoriser l'accès aux groupes voulus.

7 - La protection des données

N'oubliez pas, la donnée, c'est l'or noir de notre siècle. C'est ce qui a de la valeur et c'est ce qui s'échange sur le marché noir. Ne pas protéger ses données et celles de ses clients, c'est s'exposer à la fois aux cyber criminels, mais aussi à des remontrances de la CNIL ou de la justice. Vous êtes tenus légalement de protéger les données de vos utilisateurs.

Pour cela, il faut mettre en place :

  • Du chiffrement TLS (HTTPS) sur toutes les données qui transitent
  • Du chiffrement sur les données stockées (au moins les données sensibles) et pour cela, je vous recommande de vous reposer sur des bibliothèques de crypto ouvertes et libres.

À vous aussi d'être vigilant en ne laissant pas trainer des données sensibles et non chiffrées dans des répertoires temporaires ou dans des logs.

8 - L'activation des logs

Vous loggez surement déjà tout un tas de choses dans vos applications pour débugger ou faire de l'analyse business. Et bien je vous invite aussi à le faire pour détecter d'éventuels intrusions ou abus sur vos systèmes applicatifs.

Un journal qui contient l'ensemble des événements relatifs à votre application peut vous permettre à la fois d'anticiper une attaque ou de retracer une attaque après coup.

9 - Les frameworks

Comme je le disais en début d'article, la plupart des bibliothèques et frameworks récents implémentent déjà des fonctionnalités de sécurisation. Lisez la doc et utilisez-les ! Veillez aussi à les mettre à jour pour ne pas utiliser d'anciennes versions qui contiendraient des failles.

10 - La gestion des erreurs

Je sais, c'est comme écrire de la documentation, c'est pénible, mais mettre en place un système de gestion d'erreurs efficace est indispensable. Mais il faut bien le faire, pour ne pas qu'un attaquant puisse se servir d'éventuels messages d'erreurs pour apprendre plus sur votre application et en exploiter les faiblesses.

De plus, un système de gestion d'erreur va vous apprendre beaucoup sur votre application, mais aussi sur ce qu'en font les utilisateurs. Ainsi vous allez pouvoir anticiper pas mal de risque et corriger vos bugs.

Voilà pour les bonnes pratiques en termes de développement. Mais depuis tout à l'heure, je parle de votre code, mais pensez aussi à bien sécuriser votre poste de travail et à adopter les bonnes pratiques en matière de sécurité personnelle.

  • N'ouvrez pas les pièces jointes email d'inconnus
  • N'utilisez pas de clés USB douteuses
  • N'installez pas des logiciels à la provenance douteuse
  • Faites vos mises à jour
  • Choisissez de bons mots de passe (et pas post-it)
  • Faites des sauvegardes
  • Ne tombez pas dans des attaques de phishing
  • Ne vous connectez pas à des réseaux wifi douteux
  • N'utilisez pas de compte Admin
  • Activez la double authentification partout où vous le pouvez
  • Utilisez les services mis en place par votre société, respectez les consignes de sécurité de votre RSSI et ne les contournez pas.
  • Evitez d'éparpiller des secrets industriels sur des clouds privés situés dans des pays étrangers si vous voyez ce que je veux dire.
  • Ne laissez pas trainer votre portable dans le train, gardez-le toujours à l'oeil.
  • Soyez vigilant dans la vie de tous les jours pour éviter les attaques de type social engineering. Quelqu'un qui veut vous emprunter votre téléphone, ou qui vous demande spontanément en ami sur Facebook c'est louche.

Je sais aussi que ces êtres barbus qu'on appelle les administrateurs système sont étranges et souvent de mauvaise humeur, mais c'est bien de s'entendre et de travailler en synergie avec eux, car leur rôle est tout aussi important que le vôtre. Ils sont là pour veiller au bon fonctionnement, mais aussi à la sécurité de vos livrables, donc échangez avec eux et voyez ce que vous pouvez mettre en place ensemble pour sécuriser au maximum vos applications : Du HTTPS, de l'authentification double facteur...etc. Les sysadmins sont vos amis, apprenez à les connaitre et vous verrez, vous finirez par les aimer.

Voilà, j'en ai terminé. Si vous arrivez à faire de tous ces principes, votre quotidien, bravo ! Mais gardez toujours en tête que l'erreur est humaine et qu'aucune application n'est à 100% sécurisée. C'est pourquoi il faut continuer à faire tester son code dans le cadre d'un audit avant une release, et sur la durée avec un bug Bounty. N'oubliez pas non plus qu'il existes des outils de protection comme ceux de Radware qui vous permettront de réagir rapidement et automatiquement à des attaques que vous n'auriez pas anticipé.

Bon courage à tous !