65 votes

Vous cherchez des suggestions pour créer une API REST sécurisée dans Ruby on Rails ?

Je commence à construire une API REST pour un projet sur lequel je travaille, et cela m'a amené à faire quelques recherches sur la meilleure façon de construire une API en utilisant RoR. J'ai découvert assez rapidement que, par défaut, les modèles sont ouverts au monde et peuvent être appelés par URL en plaçant simplement un ".xml" à la fin de l'URL et en passant les paramètres appropriés.

La question suivante a donc été posée. Comment sécuriser mon application pour éviter les modifications non autorisées ? En faisant quelques recherches, j'ai trouvé quelques articles parlant de attr_accessible y attr_protected et comment ils peuvent être utilisés. L'URL particulière que j'ai trouvée à ce sujet a été postée en mai 2007 ( ici ).

Comme pour tout ce qui concerne Ruby, je suis sûr que les choses ont évolué depuis. Ma question est donc la suivante : est-ce toujours la meilleure façon de sécuriser une API REST dans RoR ?

Sinon, que suggérez-vous dans le cas d'un "nouveau projet" ou d'un "projet existant" ?

102voto

Micah Points 5630

Il existe plusieurs schémas pour authentifier les demandes d'API, et ils sont différents de l'authentification normale fournie par des plugins comme restful_authentication ou acts_as_authenticated. Plus important encore, les clients ne maintiendront pas de sessions, il n'y a donc pas de concept de connexion.

Authentification HTTP

Vous pouvez utiliser l'authentification HTTP de base. Dans ce cas, les clients de l'API utiliseront un nom d'utilisateur et un mot de passe ordinaires et les placeront dans l'URL comme suit :

http://myusername:mypass@www.someapp.com/

Je crois que restful_authentication prend en charge cette fonctionnalité dès le départ, de sorte que vous pouvez ignorer si quelqu'un utilise votre application via l'API ou via un navigateur.

L'inconvénient est que vous demandez aux utilisateurs d'indiquer leur nom d'utilisateur et leur mot de passe en clair à chaque demande. En utilisant le protocole SSL, vous pouvez sécuriser cette opération.

Je ne pense pas avoir déjà vu une API qui utilise cette méthode, cependant. Cela me semble être une bonne idée, d'autant plus qu'elle est prise en charge d'emblée par les schémas d'authentification actuels, donc je ne vois pas où est le problème.

Clé API

Une autre façon simple d'activer l'authentification des API est d'utiliser des clés d'API. Il s'agit essentiellement d'un nom d'utilisateur pour un service distant. Lorsque quelqu'un s'inscrit pour utiliser votre API, vous lui donnez une clé d'API. Celle-ci doit être transmise avec chaque requête.

L'inconvénient est que si quelqu'un obtient la clé API de quelqu'un d'autre, il peut faire des demandes en tant qu'utilisateur. Je pense qu'en faisant en sorte que toutes vos demandes d'API utilisent le protocole HTTPS (SSL), vous pouvez compenser quelque peu ce risque.

Un autre inconvénient est que les utilisateurs utilisent les mêmes informations d'authentification (la clé API) partout où ils vont. S'ils veulent révoquer l'accès à un client API, leur seule option est de changer leur clé API, ce qui désactivera également tous les autres clients. Ce problème peut être atténué en permettant aux utilisateurs de générer plusieurs clés d'API.

Signature de la clé API + clé secrète

Déprécié (en quelque sorte) - voir OAuth ci-dessous

La signature de la demande avec une clé secrète est nettement plus complexe. C'est ce que font les services Web d'Amazon (S3, EC2, etc.). Essentiellement, vous donnez à l'utilisateur deux clés : sa clé API (c'est-à-dire son nom d'utilisateur) et sa clé secrète (c'est-à-dire son mot de passe). La clé API est transmise avec chaque requête, mais pas la clé secrète. Elle est plutôt utilisée pour signer chaque demande, généralement en ajoutant un autre paramètre.

IIRC, Amazon accomplit ceci en prenant tous les paramètres de la requête, et en les classant par nom de paramètre. Ensuite, cette chaîne est hachée, en utilisant la clé secrète de l'utilisateur comme clé de hachage. Cette nouvelle valeur est ajoutée comme nouveau paramètre à la demande avant d'être envoyée. Du côté d'Amazon, ils font la même chose. Ils prennent tous les paramètres (sauf la signature), les ordonnent et les hachent en utilisant la clé secrète. Si cela correspond à la signature, ils savent que la demande est légitime.

L'inconvénient ici est la complexité. Le bon fonctionnement de ce schéma est un casse-tête, tant pour le développeur de l'API que pour les clients. Attendez-vous à de nombreux appels à l'assistance et à des courriers électroniques de développeurs clients en colère qui ne parviennent pas à faire fonctionner le système.

OAuth

Pour combattre certains des problèmes de complexité liés à la signature clé + secret, une norme a vu le jour, appelée OAuth . À la base, OAuth est une variante de la signature clé + secret, mais une grande partie est normalisée et a été incluse dans le système de gestion de l'identité. des bibliothèques pour de nombreux langages .

En général, il est beaucoup plus facile pour le producteur et le consommateur d'API d'utiliser OAuth plutôt que de créer son propre système de clé/signature.

OAuth segmente également l'accès de manière inhérente, en fournissant des informations d'identification d'accès différentes pour chaque consommateur d'API. Cela permet aux utilisateurs de révoquer l'accès de manière sélective sans affecter leurs autres applications consommatrices.

Spécifiquement pour Ruby, il existe un Gemme OAuth qui offre une prise en charge immédiate des producteurs et des consommateurs d'OAuth. J'ai utilisé cette gemme pour construire une API et aussi pour consommer des API OAuth et j'ai été très impressionné. Si vous pensez que votre application a besoin d'OAuth (par opposition au schéma plus simple des clés d'API), alors je peux facilement recommander l'utilisation de la gemme OAuth.

7voto

Gabe Hollombe Points 4687

Comment puis-je sécuriser mon application pour éviter modifications non autorisées ?

attr_accessible y attr_protected sont tous deux utiles pour contrôler la possibilité d'effectuer des affectations en masse sur un modèle ActiveRecord. Vous voulez absolument utiliser attr_protected pour éviter les attaques par injection de formulaire ; voir Utilisez attr_protégé ou nous allons vous pirater. .

De plus, afin d'empêcher quiconque d'accéder aux contrôleurs de votre application Rails, vous aurez certainement besoin d'un système d'authentification des utilisateurs et vous devrez mettre en place un système d'authentification de l'utilisateur. before_filter dans vos contrôleurs pour vous assurer qu'un utilisateur autorisé effectue la demande avant d'autoriser l'exécution de l'action demandée par le contrôleur.

Voir le Guide de sécurité de Ruby on Rails (qui fait partie du projet de documentation Rails) pour obtenir des tonnes d'informations utiles.

3voto

jonnii Points 17046

Je suis confronté à des questions similaires aux vôtres en ce moment, car je suis également en train de construire une api REST pour une application rails.

Je suggère de s'assurer que seuls les attributs qui peuvent être modifiés par l'utilisateur sont marqués avec attr_accessible. Cela créera une liste blanche d'attributs qui peuvent être assignés en utilisant update_attributes.

Ce que je fais est quelque chose comme ça :

   class Model < ActiveRecord::Base  
       attr_accessible nil  
   end

Tous mes modèles en héritent, de sorte qu'ils sont obligés de définir attr_accessible pour tous les champs qu'ils veulent rendre assignables en masse. Personnellement, j'aimerais qu'il existe un moyen d'activer ce comportement par défaut (il en existe peut-être un, mais je ne le connais pas).

Pour que vous sachiez que quelqu'un peut affecter en masse une propriété non seulement en utilisant l'api REST mais aussi en utilisant un formulaire ordinaire.

0voto

steve Points 995

Une autre approche qui évite de construire beaucoup de choses soi-même est d'utiliser quelque chose comme http://www.3scale.net/ qui gère les clés, les jetons, les quotas, etc. pour les développeurs individuels. Il effectue également des analyses et crée un portail pour les développeurs.

Il existe un plugin ruby/rails plugin API ruby qui appliquera les politiques au trafic dès son arrivée - vous pouvez l'utiliser en conjonction avec la stratégie oAuth gem . Vous pouvez également l'utiliser en plaçant varnish devant l'application et en utilisant le module varnish lib : Module API Varnish .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X