Question

Je commence à créer une API REST pour un projet sur lequel je travaille et cela m'a amené à faire une petite recherche sur le meilleur moyen de créer une API à l'aide de RoR. Je découvre assez rapidement que, par défaut, les modèles sont ouverts sur le monde et peuvent être appelés via une URL en mettant simplement un ".xml". à la fin de l'URL et en passant les paramètres appropriés.

Alors, la question suivante est venue. Comment sécuriser mon application pour empêcher les modifications non autorisées? En faisant des recherches, j'ai trouvé quelques articles parlant de attr_accessible et de attr_protected et de la façon dont ils peuvent être utilisés. L’URL particulière que j’ai trouvée en parlant a été postée en mai 2007 ( ici ).

Comme pour tout ce qui est ruby, je suis sûr que les choses ont évolué depuis. Ma question est donc la suivante: est-ce toujours le meilleur moyen de sécuriser une API REST dans RoR?

Sinon, que proposez-vous dans un "nouveau projet"? ou un scénario "projet existant"?

Était-ce utile?

La solution

Il existe plusieurs systèmes d'authentification des demandes d'API. Ils diffèrent de l'authentification normale fournie par les plug-ins, tels que restful_authentication ou acts_as_authenticated. Plus important encore, les clients ne maintiendront pas de sessions, il n’existe donc pas de concept de connexion.

Authentification HTTP

Vous pouvez utiliser l'authentification HTTP de base. Pour cela, les clients API utiliseront un nom d'utilisateur et un mot de passe habituels et les placeront simplement dans l'URL, comme suit:

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

Je pense que restful_authentication prend en charge cette fonctionnalité immédiatement. Vous pouvez donc ignorer si quelqu'un utilise votre application via l'API ou via un navigateur.

Un inconvénient est que vous demandez aux utilisateurs d'indiquer clairement leur nom d'utilisateur et leur mot de passe dans chaque demande. En le faisant sur SSL, vous pouvez sécuriser cela.

Cependant, je ne pense pas avoir jamais vu une API qui l'utilise. Cela me semble plutôt une bonne idée, d’autant plus que les schémas d’authentification actuels le supportent immédiatement, alors je ne sais pas quel est le problème.

Clé d'API

Un autre moyen simple d'activer l'authentification API consiste à utiliser des clés API. C'est essentiellement un nom d'utilisateur pour un service distant. Lorsque quelqu'un s'inscrit pour utiliser votre API, vous lui attribuez une clé API. Ceci doit être passé avec chaque demande.

Un 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 utilisant toutes les requêtes de l'API avec HTTPS (SSL), vous pouvez compenser un peu ce risque.

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

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

Obsolète (en quelque sorte) - voir OAuth ci-dessous

Signifier la demande avec une clé secrète est beaucoup plus complexe. C’est ce que font Amazon Web Services (S3, EC2, etc.). Essentiellement, vous donnez à l'utilisateur 2 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 à chaque demande, mais pas la clé secrète. Au lieu de cela, il est utilisé pour signer chaque demande, généralement en ajoutant un autre paramètre.

IIRC, Amazon accomplit cette tâche en prenant tous les paramètres dans 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 en tant que nouveau paramètre à la demande avant son envoi. Du côté d'Amazon, ils font la même chose. Ils prennent tous les paramètres (sauf la signature), les commandent et le hachage en utilisant la clé secrète. Si cela correspond à la signature, ils savent que la demande est légitime.

L’inconvénient est la complexité. Obtenir que ce schéma fonctionne correctement est une tâche ardue, à la fois pour le développeur de l'API et pour les clients. Attendez-vous à de nombreux appels d'assistance et à des courriels courroucés de la part des développeurs clients qui ne peuvent pas faire fonctionner les choses.

OAuth

Pour lutter contre certains problèmes de complexité liés à la signature clé + secrète, un standard appelé OAuth est apparu. A la base, OAuth est un exemple de signature clé + secrète, mais une grande partie est normalisée et a été incluse dans des bibliothèques pour de nombreuses langues. .

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 votre propre système de clé / signature.

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

En particulier pour Ruby, il existe un bijou OAuth qui offre un soutien immédiat aux producteurs et aux consommateurs. de OAuth. J'ai utilisé ce bijou pour construire une API et également 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 de clé d'API plus simple), alors je peux facilement vous recommander d'utiliser la gem OAuth.

Autres conseils

  

Comment sécuriser mon application pour empêcher   modifications non autorisées?

attr_accessible et attr_protected sont tous deux utiles pour contrôler la possibilité d'effectuer des assignations en masse sur un modèle ActiveRecord. Vous voulez absolument utiliser attr_protected pour prévenir les attaques par injection de formulaire; voir Utilisez attr_protected ou nous vous piraterons .

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 d'utilisateur et insérez un before_filter dans vos contrôleurs. pour vous assurer que la demande est faite par un utilisateur autorisé avant d'autoriser l'exécution de l'action de contrôleur demandée.

Consultez le Guide de sécurité de Ruby on Rails (qui fait partie du projet de documentation Rails) pour plus d'informations. informations plus utiles.

Je suis confronté aux mêmes questions que vous car pour le moment, je construis également une API REST pour une application sur rails.

Je suggère de vérifier que seuls les attributs pouvant être modifiés par l'utilisateur sont marqués avec attr_accessible. Ceci établira une liste blanche d'attributs pouvant être assignés avec update_attributes.

Ce que je fais ressemble à ceci:

   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 souhaitent affecter en masse. Personnellement, j'aimerais qu'il y ait un moyen d'activer ce comportement par défaut (il y en a peut-être et je ne le sais pas).

Pour que vous sachiez que quelqu'un peut attribuer en masse une propriété non seulement à l'aide de l'API REST, mais également à l'aide d'un formulaire standard.

Une autre approche qui évite de créer vous-même beaucoup de choses 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 de développement.

Il existe un plug-in d'API ruby ?? qui s'appliquera aux règles de gestion du trafic - vous pouvez l'utiliser conjointement avec la joyau oAuth . Vous pouvez également nous le faire en déposant du vernis devant l'application et en utilisant le mod lib varnish: Module API Varnish .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top