web-dev-qa-db-fra.com

La sécurité intégrée de Django est-elle suffisante?

J'ai appris que Django fournit une protection intégrée contre les trois principaux types d'attaques d'applications Web (injection SQL, XSS et CSRF), ce qui est vraiment génial.

Pourtant, j'ai parlé à quelques Django développeurs et ils m'ont essentiellement dit de ne pas trop compter sur ceux-ci, voire pas du tout.

Ils m'ont dit de traiter toutes les données comme "dangereuses" et de les traiter de manière appropriée.

J'ai deux questions à poser à tout le monde à ce sujet:

  1. Peut-on se fier aux fonctionnalités de sécurité intégrées de Django?
  2. Qu'entendent mes amis par "gérer cela (données dangereuses) de manière appropriée"? Je sais qu'il est possible d'échapper et/ou de supprimer des phrases et/ou des caractères dangereux, mais ma plus grande crainte est que si j'essaie de le faire moi-même, je finisse par produire un "filtre" qui est pire que les éléments intégrés à Django. Quelqu'un at-il des guides pour construire au-dessus de Django et ne pas le remplacer, à cet égard?
51
pleasedesktop

Injection SQL. Si vous utilisez la couche de mappage relationnel objet (ORM) de Django, vous êtes fondamentalement protégé contre l'injection SQL.

La seule mise en garde est que vous devez éviter de former manuellement des requêtes SQL à l'aide de la concaténation de chaînes. Par exemple, n'utilisez pas de requêtes SQL brutes (par exemple, raw()). De même, n'utilisez pas la méthode/modificateur extra() pour injecter du SQL brut. Ne pas exécuter directement le SQL personnalisé ; si vous contournez la couche ORM de Django, vous contournez ses protections contre l'injection SQL.

CSRF. La protection CSRF intégrée de Django est bonne. Assurez-vous que activez-le et utilisez-le partout. Django fournit des moyens de le désactiver localement ou globalement; évidemment, ne le faites pas.

Il est important de vous assurer que les requêtes GET n'ont pas d'effets secondaires. Pour les demandes qui peuvent avoir un effet secondaire, assurez-vous d'utiliser une demande POST (et n'acceptez pas de demande GET pour celles-ci). Il s'agit d'une conception Web standard, mais certains développeurs la bousillent ; La prévention CSRF intégrée de Django suppose que vous obtenez ce droit.

Il y a quelques mises en garde si vous avez des sous-domaines (par exemple, votre application Web est hébergée sur www.example.com et il y a un sous-domaine alice.example.com qui héberge du contenu contrôlé par l'utilisateur); la protection CSRF intégrée peut ne pas être suffisante dans ce cas. C'est un cas délicat pour plusieurs raisons. La plupart des applications Web n'auront pas à se soucier de ces mises en garde.

XSS. Si vous utilisez le système de modèles de Django et assurez-vous que l'échappement automatique est activé, vous êtes à 95% du chemin. Django fournit un mécanisme d'échappement automatique pour arrêter XSS: il échappera automatiquement les données qui sont insérées dynamiquement dans le modèle, si elles ne l'ont pas déjà été (voir par exemple, mark_safe, safe, etc.). Ce mécanisme est une bonne chose, mais il ne suffit pas tout seul. Il vous faut beaucoup de chemin pour arrêter XSS, mais vous devez toujours être conscient de certains problèmes.

En particulier, l'échappement automatique de Django échappera suffisamment aux données pour la plupart des contextes HTML, mais dans certains cas spéciaux, vous devez effectuer manuellement un échappement supplémentaire:

  • Assurez-vous de citer tous les attributs où les données dynamiques sont insérées. Bien: <img alt="{{foo}}" ...>. Mauvais: <img alt={{foo}} ...>. L'échappement automatique de Django n'est pas suffisant pour les valeurs d'attribut non cotées.

  • Pour les données insérées dans CSS (balises et attributs style) ou Javascript (blocs script, gestionnaires d'événements et attributs onclick/etc.), Vous devez échapper manuellement les données à l'aide de les règles d'échappement appropriées pour CSS ou Javascript.

  • Pour les données insérées dans un attribut où une URL est attendue (par exemple, a href, img src), vous devez valider manuellement l'URL pour vous assurer qu'elle est sûre. Vous devez vérifier le protocole par rapport à une liste blanche de protocoles autorisés (par exemple, http:, https:, mailto:, ftp:, etc. - mais certainement pas javascript:).

  • Pour les données insérées dans un commentaire, vous devez faire quelque chose de plus pour échapper -s. En fait, mieux encore, n'insérez pas de données dynamiques dans un commentaire HTML; c'est un coin obscur de HTML qui demande juste des problèmes subtils. (De même, n'insérez pas de données dynamiques dans des attributs où il est insensé que des entrées utilisateur apparaissent (par exemple, foo class=...).)

  • Vous devez toujours éviter XSS côté client (également appelé XSS basé sur DOM) séparément; Django ne vous aide pas. YOu pourrait lire les conseils d'Adam Barth pour éviter XSS pour quelques directives qui vous aideront à éviter XSS côté client.

  • Si tu utilises mark_safe pour dire manuellement que Django que certaines données ont déjà été échappées et sont sûres, vous feriez mieux de savoir ce que vous faites, et il vaut mieux être sûr. Il est facile de faire des erreurs ici si vous ne savez pas ce que vous faites. Par exemple, si vous générez du HTML par programmation, le stockez dans la base de données, puis le renvoyez au client (sans échapper, évidemment), il est très facile de faire des erreurs; vous ' re par vous-même, et l'échappement automatique ne vous aidera pas.

La raison pour laquelle vous devez faire quelque chose de plus pour ces cas est que la fonctionnalité d'échappement automatique de Django utilise une fonction d'échappement qui est supposée pour être à taille unique, mais en pratique, une la taille ne convient pas toujours dans tous les cas; dans certains cas, vous devez faire quelque chose de plus par vous-même.

Pour plus d'informations sur les règles d'échappement à utiliser dans ces contextes spéciaux, consultez la feuille de triche OWASP XSS.

Autres choses. Il y a d'autres choses que vous n'avez pas mentionnées:

Pour plus d'informations. Voir documentation de Django sur la sécurité , y compris le chapitre sur la sécurité dans le = Django livre.

74
D.W.