En fait, faute d'avoir réussi à bien l'expliquer, je pense que personne n'a vraiment compris mon problème ;) parce que Mais je l'ai résolu, avec une méthode pas du tout originale, mais je n'y avais pas pensé plus tôt à force de vouloir faire des trucs RESTful-truc standard ^^ Plutôt que de contrôler a posteriori l'url, le referer, etc. sur la base d'info fondamentalement pas fiables, j'ai mis en place un around_filter :context_checker qui vérifie l'existence d'un « contexte » d'exécution pour une action donnée. Si le contexte est présent, l'action est exécutée, sinon, on gère l'erreur. Le contexte est remis à zéro après chaque action pour laquelle il a été demandé d'effectuer context_checker.
Typiquement, le contexte est initié par la méthode index d'un contrôleur (requête auprès du modèle, qui retourne juste ce qu'il faut), mais tout est possible. Il consiste en un hash associant des id autorisés à des tokens aléatoires (base64 de ActiveSupport::SecureRandom). On peut avoir un token commun, ou bien un token par groupe d'id, ou bien un token par id, selon la finesse de contrôle souhaitée. Ce hash est disponible dans la view associée à l'action créant le contexte (index.haml par exemple) : la view se charge de faire en sorte que chaque lien/boutton (remote ou pas) renvoyant vers une action contrôlée passe le token associé à l'id manipulé (params[:context_token]). Les token sont visibles dans les sources, mais comme ils caractérisent *ponctuellement* un id *spécifique* *autorisé* (params[:id]) de manière *aléatoire*, on ne peut rien en faire à part les utiliser pour faire ce à quoi ils sont censés servir : donner l'accès ponctuel à une action spécifique pour un id spécifique. En gros, si, pour un couple params[:id] donné et un params[:context_token], et à condition que params[:id] soit géré par le contexte courant, si on matche bien le couple id/token présent dans le hash de contrôle, l'action est validée. Si on tente un accès à une action pour laquelle il y a un contrôle du contexte, que ce soit par url directe sans contexte défini, par url directe avec un contexte périmé, par url directe avec un mauvais token et/ou id, ou bien par referer interne avec contexte périmé, ou mauvais token et/ou id, ça bloque. Pour le moment, ça ne gère pas les routes imbriquées qui utiliseraient plusieurs id et plusieurs actions, mais je n'en utilise pas (pas encore) dans mon projet. Au final, rien d'exceptionnel, mais si ça intéresse quelqu'un, je peux réfléchir à en faire un plugin par exemple. Merci pour vos conseils dans tous les cas, j'ai appris des choses ^^ On 10 juil, 11:26, tongman <[email protected]> wrote: > Je ne suis pas sur de comprendre l'idée qu'il y derrière interdire > l'action à des methodes d'un controller : > Si il s'agit de méthode qui ne doivent pas accessible à quiconque, > alors il ne faut pas les présenter ! Il faudrait probalement ajouter > ces méthodes dans la partie privée de ton controller. > Sinon, dans le cas d'un accés filtré, il faudrait probablement ... > filtrer avec un système de droit. > > Les remarques de Meshak sont justes : limiter les routes et n'exposer > que ce que l'utilisateur a le droit de faire semble logique. > > Je ne vois vraiment pas de cas d'usages où les méthodes du controller > ne devant être utilisées que par le serveur lui-même doivent > absolument rester publiques (et par la même correspondre à une URL) > > Bon courage > --- > Mathieu > > On 8 juil, 13:54, Frédéric Jay <[email protected]> wrote: > > > Et en testant request.host_with_port ? > > > Le 7 juillet 2009 23:37, Meshak <[email protected]> a écrit : > > > > Si une action est déclenchée via le navigateur de l'internaute, celui- > > > ci pourra toujours "tricher" sur les requêtes. Avec les bons plugins > > > dans Firefox, on peut facilement simuler n'importe quelle requête GET/ > > > POST avec les referer/locale/user-agent... que l'on souhaite. > > > > Même :protect_from_forgery est contournable : j'ai déjà eu affaire à > > > un bot qui validait mes formulaires. > > > > Donc les seules solutions fiables (comme dit plus haut) : > > > > 1. Limiter les actions des routes, exemple : > > > # Ni création, ni suppression d'objets "Configuration" > > > map.resources :configurations, :except => [:new, :create, :destroy] > > > > 2. Mettre un système d'authentification : plusieurs gems/plugins sont > > > disponibles, autrement ça peut être du fait-maison. > > > > 3. Mettre un système de droits, et resteindre les actions autorisées > > > dans les contrôleurs, exemple : > > > # Seul un admin pourra utiliser l'action destroy > > > before_filter :check_user_is_admin, :only => [:destroy] > > > > 4. Coder RESTful ses actions custom, cela évite beaucoup de fausses > > > manipulations. Exemple : > > > # Mon action supprime des choses, donc j'évite à tout prix le :get, je > > > préfère du :delete > > > map.remove_item_associations '/items/:id/ > > > remove_assocations', :conditions => { :method => :delete } > > > > Julien > > > > On 7 juil, 19:26, jd <[email protected]> wrote: > > > > Une note : j'ai testé l'affaire en suivant les indications dehttp:// > > > guides.rubyonrails.org/security.htmlethttp://baseunderattack.com/2008/04/18/ruby-on-rails-and-csrf-protection/ > > > , > > > > et Rails semble bien distinguer ce qui a été déclenché par une url > > > > directe avec manipulation du referer, de ce qui a été déclenché en > > > > interne avec referer « local » à l'application. Comme ce n'est > > > > vraiment pas ma spécialité, je ne saurais dire si ça tient la route, > > > > mais je ne vois pas trop comment faire autrement. --~--~---------~--~----~------------~-------~--~----~ Vous avez reçu ce message, car vous êtes abonné au groupe "Railsfrance" de Google Groups. Pour transmettre des messages à ce groupe, envoyez un e-mail à l'adresse [email protected] Pour résilier votre abonnement envoyez un e-mail à l'adresse [email protected] -~----------~----~----~----~------~----~------~--~---
