Vous recherchez 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 un peu de recherche sur la meilleure façon de créer une API avec RoR. Je découvre assez rapidement que par défaut, les modèles sont ouverts au monde et peuvent être appelés via une URL en mettant simplement un “.xml” à la fin de l’URL et en passant les parameters 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 attr_protected et de la façon dont ils peuvent être utilisés. L’URL particulière que j’ai trouvée en parler a été publiée en mai 2007 ( ici ).

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

Si non, que proposez-vous dans un scénario “nouveau projet” ou “projet existant”?

Il existe plusieurs méthodes d’authentification des demandes d’API, et elles diffèrent de l’authentification normale fournie par des plug-ins tels que restful_authentication ou acts_as_authenticated. Plus important encore, les clients ne maintiendront pas les sessions, il n’y a donc pas de concept de connexion.

Authentification HTTP

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

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

Je pense que restful_authentication prend cela en charge, 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 de mettre leur nom d’utilisateur et leur mot de passe en clair dans chaque demande. En le faisant sur SSL, vous pouvez le rendre sûr.

Je ne pense pas avoir déjà vu une API qui l’utilise, cependant. Cela me semble être une bonne idée, d’autant plus que les schémas d’authentification actuels le prennent en charge, donc je ne sais pas quel est le problème.

clé API

Une autre méthode simple pour 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 donnez une clé API. Cela 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 requêtes en tant qu’utilisateur. Je pense qu’en faisant toutes vos demandes d’API utiliser 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é API) partout où ils vont. S’ils veulent révoquer l’access à un client API, leur seule option est de changer 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 + clé secrète

Obsolète (sorte de) – voir OAuth ci-dessous

Signer la requête 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: leur clé API (c.-à-d. Nom d’utilisateur) et leur clé secrète (par exemple, mot de passe). La clé API est transmise avec chaque requête, mais la clé secrète ne l’est pas. Au lieu de cela, il est utilisé pour signer chaque demande, généralement en ajoutant un autre paramètre.

IIRC, Amazon accomplit ceci en prenant tous les parameters à la demande, et en les ordonnant 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 parameters (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é. Faire en sorte que ce schéma fonctionne correctement pose un problème à la fois pour le développeur de l’API et pour les clients. Attendez-vous à beaucoup d’appels de soutien et de courriels en colère de la part des développeurs de clients qui n’arrivent pas à faire fonctionner les choses.

OAuth

Pour lutter contre certains problèmes de complexité liés à la signature par clé + secret, une norme a vu le jour, appelée OAuth . À la base, OAuth est une saveur de signature + clé, mais une grande partie est normalisée et a été incluse dans les 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 de manière inhérente l’access, en fournissant des informations d’identification d’access différentes pour chaque consommateur d’API. Cela permet aux utilisateurs de révoquer de manière sélective l’access sans affecter leurs autres applications consommasortingces.

Spécifiquement pour Ruby, il existe un joyau OAuth qui fournit une assistance immédiate aux producteurs et aux consommateurs d’OAuth. J’ai utilisé ce bijou pour construire une API et pour consumr 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), je peux facilement recommander l’utilisation du joyau OAuth.

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

attr_accessible et attr_protected sont tous deux utiles pour contrôler la possibilité d’effectuer des assignations de masse sur un modèle ActiveRecord. Vous voulez certainement utiliser attr_protected pour empêcher les attaques par injection de formulaires; voir Utiliser attr_protected ou nous allons vous pirater .

De plus, afin d’empêcher quiconque d’être capable d’accéder aux contrôleurs de votre application Rails, vous aurez certainement besoin d’un système d’authentification des utilisateurs et placez un before_filter dans vos contrôleurs pour vous assurer que vous disposez d’un utilisateur autorisé. demande avant d’autoriser l’exécution de l’action de contrôleur demandée.

Reportez-vous au Guide de sécurité Ruby on Rails (qui fait partie du projet de documentation Rails) pour plus d’informations utiles.

Je suis confronté à des questions similaires, car je construis également une api REST pour une application de rails.

Je suggère de veiller à ce que seuls les atsortingbuts pouvant être modifiés par l’utilisateur soient marqués avec attr_accessible. Cela définira une liste blanche d’atsortingbuts pouvant être atsortingbués à l’aide de update_atsortingbutes.

Ce que je fais, c’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 assigner en masse. Personnellement, je souhaite qu'il y ait un moyen d'activer ce comportement par défaut (il pourrait y en avoir, et je ne le sais pas).

Juste pour que vous sachiez que quelqu'un peut assigner en masse une propriété non seulement en utilisant l'API REST, mais aussi en utilisant une publication régulière.

Une autre approche qui permet d’économiser 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 parsings et crée un portail de développement.

Il y a un plugin ruby ​​/ rails plugin ruby API qui s’appliquera aux politiques au trafic à son arrivée – vous pouvez l’utiliser en conjonction avec le joyau oAuth . Vous pouvez également nous le faire en déposant le vernis devant l’application et en utilisant le mod de vernir lib: Varnish API Module .