Berceaux de sécurité: REST



REST est une architecture d'application Web extrêmement populaire. Pour appeler des fonctions sur le serveur, des requêtes HTTP ordinaires avec des paramètres spécifiés sont utilisées (JSON ou XML est généralement utilisé pour structurer les paramètres), alors qu'il n'y a pas de norme stricte pour l'architecture REST, ce qui ajoute de la flexibilité (et, bien sûr, un peu de chaos).

REST vous permet d'aborder de manière flexible la question de la sécurité ou, que beaucoup de péchés, de ne pas aborder la question du tout. Basé sur OWASP , nous avons préparé une liste de conseils pour vous aider à améliorer la sécurité de votre application REST.

Comme point de départ dans ces rares cas où cela est nécessaire ici, nous utilisons python et Django.

Règle 0


Https


Il suffit de le configurer. Je vous en prie. La protection des données transmises n'a porté préjudice à personne. Même si vous pensez qu'il n'y a rien à protéger pour le moment, ce ne sera pas toujours le cas et vous devez encore configurer HTTPS. Alors configurez-le mieux tout de suite et tout le monde ira bien.

Règle 1


Authentification


Il semblerait que ce soit un conseil évident, que beaucoup préfèrent cependant négliger. L'application doit toujours avoir une authentification, même si vous pensez maintenant que vous ne l'utiliserez qu'au sein de l'entreprise et qu'il n'y a aucune différence parmi les employés qui la font. Et si vous ajoutez plus avec des magazines, enquêter sur les incidents et analyser l'activité deviendra incomparablement plus simple.

En tant que jetons d'accès, il est actuellement considéré comme une bonne pratique d'utiliser JWT (jetons Web JSON). N'utilisez pas de jetons avec la valeur {"alg": "none"} pour le contrôle d'intégrité, les jetons doivent toujours contenir une signature ou un MAC! Une signature est préférable car les clés de génération et de vérification du MAC correspondent (ou peuvent être facilement calculées les unes des autres), c'est-à-dire que si le serveur est capable de vérifier la valeur MAC, il peut également générer ses valeurs. La signature confirme également non seulement l'intégrité du message, mais également l'identité de l'expéditeur.

Règle 2


Refuser les méthodes HTTP que vous n'utilisez pas


Configurez le serveur pour mettre en liste blanche les méthodes avec lesquelles vous travaillez (GET, POST, PUT, etc.) et rejetez tout ce qui ne rentre pas dans cette liste. Il est peu probable que votre serveur ait besoin de traiter les demandes TRACE en production (cette méthode fait partie de l'attaque XST (Cross-Site Tracing), qui consiste en une attaque XSS et la méthode TRACE ou TRACK. Cette attaque permet, par exemple, de voler les cookies de l'utilisateur, même si ils sont marqués comme HttpOnly). Le moins d'informations sur votre infrastructure sont disponibles de l'extérieur, mieux c'est.

Règle 3


Différencier l'accès


Tous vos utilisateurs ont-ils besoin de toutes les méthodes, par exemple, SUPPRIMER? Si vous ne souhaitez pas que certains utilisateurs puissent effectuer certaines opérations - configurez le contrôle d'accès dans votre application. Par exemple, un utilisateur ordinaire ne peut accéder qu'à la méthode GET pour certaines fonctions, le gestionnaire peut utiliser GET et POST, etc. Pour cela, il convient de définir des rôles dans la base de données qui peuvent être attribués aux utilisateurs pour un contrôle d'accès pratique.

Par conséquent, chaque fonction aura un bloc de vérification d'environ ce type:

if request.POST and user.is_manager: do_stuff() 

Règle 4


Pensez à limiter le nombre de requêtes


Si vous pensez que vos utilisateurs ne devraient pas vous envoyer cent mille demandes par seconde, alors vous devriez limiter ce nombre. Utilisez des clés API ou tout autre mécanisme pratique pour suivre et limiter le nombre de demandes qui seront traitées dans un certain laps de temps par un utilisateur. Pour Django, par exemple, django-ratelimit fournit cette fonctionnalité, où vous pouvez définir divers paramètres comme identifiant pour la restriction, pas nécessairement des clés API, mais une adresse IP.

Règle 5


Assurez-vous de valider / désinfecter l'entrée


Ne faites jamais confiance aux paramètres d'entrée transmis, effectuez toujours la validation / l'assainissement:

  • Si possible (et si possible), définissez une limite sur la longueur / le type / le format de l'entrée et la demande elle-même. Rejetez toutes les demandes / données transmises qui dépassent la longueur spécifiée par vous ou qui ne correspondent pas au type / format.
  • Lors du traitement des chaînes, échappez toujours à tous les caractères spéciaux.
  • Si vous utilisez le framework, la plupart d'entre eux contiennent leurs propres outils de validation et d'assainissement intégrés (à la différence des plus populaires - Django (python) et Yii2 (php)), il est donc important d'étudier leurs capacités et si certains aspects dont vous avez besoin ne sont pas couverts - trouvez une bibliothèque qui ferme cela ou écrivez vous-même une telle fonctionnalité.
  • Gardez une trace des erreurs de validation. Si les demandes de certains utilisateurs échouent constamment à la validation - pensez à bloquer automatiquement ces utilisateurs.
  • Assurez-vous que votre analyseur d'entrée (ou sa version actuelle) n'est pas susceptible à des attaques par lui-même.


Règle 6


Ne donnez pas plus d'informations que nécessaire


Si une demande a provoqué une erreur dans l'application, ou si elle est simplement indisponible pour une raison quelconque, ne fournissez pas de détails dans la réponse, renvoyez le message d'erreur le plus abstrait. Certains serveurs renvoient stacktrace après une erreur par défaut, assurez-vous donc de reconfigurer cette logique.

Règle 7


Gardez toujours des journaux


Laissez chaque événement (authentification, erreur, demande, etc.) être enregistré de manière aussi détaillée que possible. Enregistrez-les logiquement pour une recherche plus pratique si nécessaire. Juste au cas où, avant d'enregistrer dans les journaux, désinfectez les données enregistrées.

Règle 8


Indiquez correctement le type de contenu - c'est important!


Pour que le navigateur (ou le client) lise correctement les données fournies, le type de contenu correctement spécifié correspondant aux données fournies est important. Dans le cas des navigateurs, il convient également de définir l'en-tête X-Content-Type-Options: nosniff, afin d'empêcher le navigateur d'essayer de détecter d'autres types de contenu en plus de celui qui a été réellement envoyé (une mesure contre les attaques XSS).

Règle 9


Valider le type de contenu


  1. Il vaut la peine de configurer le rejet des demandes si leur type de contenu diffère de leur contenu. Cela réduira le risque de traitement incorrect des données, ce qui peut entraîner une injection ou l'exécution de code sur le serveur / client.
  2. Il convient également de rejeter les demandes dont le type de contenu n'est pas pris en charge ou pour lesquelles cet en-tête est généralement absent. Évitez également les réponses directes sur la fonction Content-Type acceptée / émise, si cela n'est pas nécessaire (cela aidera à éviter les attaques XXE).
  3. Dans les services REST, il est courant de prendre en charge plusieurs types de réponses (par exemple, json et xml), et le client indique le type de réponse préféré dans l'en-tête Accept lors de la demande. Évitez de copier le contenu de l'en-tête Accept dans le Content-Type de la réponse comme mécanisme de définition de cet en-tête. Rejetez également les demandes pour lesquelles l'en-tête Accept ne contient pas directement au moins un des types pris en charge.

Règle 10


N'oubliez pas de configurer le partage de ressources d'origine croisée (CORS)


CORS est une norme qui décrit l'utilisation de requêtes interdomaines. Si votre application ne prend pas en charge CORS, désactivez le travail avec ce type d'en-têtes. Si vous devez l'utiliser, la politique d'accès doit être aussi spécifique et stricte que possible.

Règle 11


Ne développez pas les paramètres dans l'URL


Toutes les données critiques (mots de passe, clés, jetons et connexions, de préférence également) doivent se trouver à l'intérieur du corps de la demande ou dans les en-têtes, mais ne doivent en aucun cas apparaître dans l'URL. Si vous devez transmettre des données sensibles via la méthode GET, mettez-les dans l'en-tête.

C'est impossible:
exemple .com / controller / 123 / action? apiKey = a53f435643de32

Vous pouvez:
exemple .com / contrôleur / 123 / action

En-têtes:
Hôte: example.com
User-Agent: Mozilla ...
X-APIkey: a53f435643de32

Règle 12


Pensez à la protection contre les attaques CSRF


Vous pouvez en savoir plus sur tous les types de protection ici , et donc, l'utilisation de jetons CSRF est considérée comme le moyen le plus populaire pour réduire le risque d'attaques de ce type.

Règle 13


Explorez votre cadre


Si vous utilisez un framework pour implémenter REST dans votre application, vous devez l'étudier et ne pas l'utiliser aveuglément, comme cela se fait souvent. Lisez attentivement la documentation, en particulier la partie sécurité. Ne le laissez pas travailler sur les paramètres par défaut! Chaque framework a ses propres nuances, notamment en matière de sécurité, il est donc très important de les connaître.

Source: https://habr.com/ru/post/fr453384/


All Articles