M'enfin ?!?

Aller au contenu | Aller au menu | Aller à la recherche

vendredi 31 octobre 2008

Encore plus de tips pour Vim

Dans la série des astuces pour Vim, voici le troisième épisode (le premier se trouve par ici et le second par là).

  • Jamis Buck, l'auteur de Capistrano, revient sous Vim après plusieurs années de textmate. La bonne nouvelle, c'est qu'il ne peut pas se passer de Cmd-T pour trouver des fichiers, et qu'il a donc développé un plugin Vim pour faire cela : Fuzzy File Finder. Je vous conseille fortement de l'essayer, ca simplifie vraiment la vie pour ouvrir des fichiers bien planqués dans des sous-répertoires.
  • La recherche sous Vim se fait en tapant / puis l'expression recherchée. Je suppose que vous connaissiez cette commande, mais saviez-vous que l'on peut spécifier un déplacement en tapant un deuxième / puis le déplacement voulu ? Par exemple, /foo/e+1 placera le curseur sur le premier caractère après foo. Ceci est très pratique quand on répète plusieurs fois la même recherche.
  • Si vous débuggez souvent des feuilles de style CSS, vous êtes amené à faire beaucoup d'allers-retours entre votre navigateur web et Vim. Et à chaque fois que vous faîtes une modification, vous êtes obligés de taper <ESC>:w<CR> pour la tester. Pour gagner quelques touches à chaque itération, je vous propose de rajouter la ligne suivante à votre fichier .vimrc :
autocmd FocusLost *.css :up

Elle enregistre automatiquement chaque fichier .css quand Vim perd le focus (et uniquement s'il y a des changements à enregistrer).

Screenshot de Gvim avec le plugin Merb

samedi 25 octobre 2008

Recherches Google

Voici quelques recherches google qui ont amenées des personnes sur ce blog :

  • php sql comme rails : il existe des ORM en PHP, mais franchement, ce n'est pas à la hauteur de Rails.
  • vim ^m : je suppose que cette personne a ouvert un fichier provenant de windows sous Vim. Dans ce cas, les retours à la ligne apparaissent en ^M. Pour les convertir en retour à la ligne UNIX, il est possible d'utiliser l'utilitaire dos2unix ou alors, directement depuis vim, taper :%s/^M//g (attention, pour taper ^M, il faut utiliser la combinaison CTRL-V CTRL-M, sinon cela ne fonctionne pas).
  • faire un copier coller avec un mac : Pomme-C Pomme-V, non ?
  • se qui me menque le plus : probablement un correcteur orthographique et grammatical.
  • "j'ai plus d'sou" : je ne vois pas ce que je peux y faire.
  • templeet : hein, il y a encore des gens qui cherchent ça ?!? Alors, pour info, c'est un framework PHP qui a pris un méchant coup de vieux ces 5 dernières années.
  • garder fenetre premier plan mac os x : je ne suis jamais arrivé à garder une fenêtre au premier plan sous Mac OSX. Les solutions ? Passer à un vrai window manager sous GNU/Linux ou utiliser des Post-its à la place.

mercredi 10 septembre 2008

RubyflowFr, premiers retours

RubyflowFr est en ligne depuis une dizaine de jours. C'est l'occasion de faire un premier retour dessus :

  • 18 posts
  • 8 utilisateurs enregistrés
  • environ 1500 pages vues
  • une trentaine de personnes suivent quotidiennement les flux RSS, d'après Feedburner
  • déjà des changements de CSS !

Merci à Nicolas Gruson pour ces modifications de CSS qui améliorent grandement la lisibilité du site. Bref, cela démarre pas mal, même si j'aimerais bien que plus de personnes proposent des liens (il n'y a pas besoin de compte pour cela).

jeudi 4 septembre 2008

PDF de l'article sur Rails et la sécurité

Ce très court billet est là juste pour vous dire que mon article, Rails et la sécurité, est maintenant disponible en PDF. Vous pouvez le télécharger là : Rails et la sécurité (PDF).

mardi 2 septembre 2008

RubyflowFr est en ligne

Rubyflow est une application de publications de liens à destination de la communauté Ruby. Peter Cooper a libéré le code source de cette application, aussi Ruby France a décidé d'en sortir une version française destinée à la communauté française des rubyistes et railers.

L'adresse du site est http://flow.rubyfrance.org/. Bien entendu, vous êtes encouragés à partager vos liens sur Ruby, Rails, Merb ou autres en les postant accompagnés d'une courte description. Vous savez ce qu'il vous reste à faire ;)

mardi 19 août 2008

Firefox & about:config

Firefox est le navigateur que j'utilise tous les jours, et ce depuis un certain nombre d'années. Au fil du temps, je me suis habitué à un certain nombre de préférences, dont certaines doivent être configurées depuis la page about:config. Pour ceux qui ne connaissent pas cette page, je dirais juste qu'il suffit de taper about:config dans la barre d'adresse de firefox pour accéder à un écran qui permet de modifier de nombreuses fonctionnalités avancées. Les noms et valeurs des préférences sont souvent obscurs. Il existe une liste relativement complète de ces préférences, mais voici ceux que j'utilise le plus souvent :

  • browser.tabs.closeButtons à 3 pour avoir un seul bouton fermer les onglets, tout à droite de la barre d'onglets, comme dans les anciennes versions de firefox.
  • browser.backspace_action à 0 pour que la touche backspace permette de revenir en arrière dans l'historique.
  • middlemouse.contentLoadURL à true pour pouvoir aller sur l'URL dans le presse-papier en cliquant juste sur le bouton du milieu de la souris (à la façon d'un coller sous UNIX).
  • browser.blink_allowed à false pour désactiver les clignotements provoqués par les balises <blink>.

Mise à jour : vous pouvez trouver 28 réglages sur Make Tech Easier.

vendredi 18 juillet 2008

Rails et la sécurité

Introduction

La sécurité des applications web est souvent un sujet délicat : peu de temps à y consacrer, mais cela peut avoir des conséquences assez graves. Pas de panique ! Ruby on Rails est bien armé et avec un peu de rigueur, on peut se protéger sans trop de difficultés. Nous allons voir les principaux types d'attaques et comment les éviter.

Injections SQL

Commençons par un grand classique : les injections SQL. Une injection SQL consiste simplement à envoyer des données non prévues dans une requête SQL. Prenons comme exemple une application web où les utilisateurs sont authentifiés de la manière suivante :

@current_user = User.find(:first, :conditions => "login='#{params[:login]}' AND password='#{params[:password]}'")

En temps normal, quand Joe s'authentifie, la requête SQL suivante est exécutée :

SELECT * FROM users WHERE login='Joe' AND password='0521bc575b0ff61daa62494c7ae9c5b6' LIMIT 1;

Mais supposons maintenant que Kevin, un Script Kiddie, passe dans le coin et décide de mettre "Joe'; --" dans le champ login. La requête SQL va alors ressembler à :

SELECT * FROM users WHERE login='Joe'; --' AND password='00000000000000000000000000000000' LIMIT 1;

Kevin a réussi à se faire passer pour Joe sans connaître son mot de passe !

Heureusement, Active Record permet de nous en protéger assez facilement. Pour cela, il suffit d'utiliser les formes échappées comme cela :

@current_user = User.find(:first, :conditions => ["login=? AND password=?", params[:login], params[:password]])

ou de façon équivalente :

@current_user = User.find(:first, :conditions => {:login => params[:login], :password => params[:password]})

Dans les 2 cas, Active Record rajoutera un caractère '\' devant chaque apostrophe de façon à éviter les injections SQL.

L'authentification et la gestion des droits

Pour la grande majorité des projets, l'authentification (et la gestion des droits qui vont avec) est un passage obligé. Pour cela, il existe un certain nombre de points importants à respecter comme le chiffrement des mots de passe stockés en base de données (ce que nous n'avons pas fait dans l'exemple précédent). Les erreurs sont vite arrivées, aussi je vous recommande d'utiliser des plugins reconnus comme Restful Authentication, OpenID Authentication et Authorization.

Il ne vous reste plus qu'à faire attention à un dernier détail : mettre en cache des pages nécessitant une authentification est une mauvaise idée. En effet, ces pages vont alors être servies par le serveur web sans passer Rails, et donc sans vérification de l'authentification.

Se protéger des données forgées

L'étape suivante consiste à bien sécuriser l'accès aux données, aussi bien en lecture qu'en écriture. En effet, Rails possède quelques raccourcis très pratiques, mais qui peuvent poser problème quand ils sont mal maîtrisés. Le plus courant est l'affectation de masse, technique qui consiste à créer un objet Active Record directement depuis les paramètres de la requête HTTP. Par exemple, la création d'un compte utilisateur pourra s'effectuer de la façon suivante :

@user = User.create(params[:user])

Supposons maintenant que la table 'users' comporte un champ 'admin' qui vaut 0 par défaut ou 1 pour les super-utilisateurs. Un utilisateur malveillant pourrait forger la requête HTTP pour ajouter un paramètre useradmin=1 afin de gagner les pouvoirs réservés aux admins. La première solution pour se protéger de cette attaque consiste à écrire explicitement quels sont les paramètres autorisés :

@user = User.create(
        :login => params[:user][:login],
        :email => params[:user][:email],
        :password => params[:user][:password],
        :cgu => params[:user][:cgu])

Mais ceci peut vite devenir pénible quand on commence à avoir des formulaires un peu conséquents. C'est pourquoi on lui préfère généralement la deuxième solution : la déclaration dans le modèle de la liste des attributs qui ne peuvent pas être modifiés. Cette déclaration se fait à l'aide de la méthode attr_protected comme suit :

class User < ActiveRecord::Base
        attr_protected :admin
        ...
end

Nous pouvons de nouveau utiliser l'affectation de masse sans craindre qu'un utilisateur se fasse passer pour un admin, Rails s'occupe de filtrer les paramètres.

Dans le même style, un attaquant peut essayer de forger des URL. Si, par exemple, l'utilisateur authentifié peut supprimer l'item n°123 qui lui appartient, en appelant l'URL /items/delete/123, alors que se passera-t-il s'il appelle la même URL pour l'item n°456 qui ne lui appartient pas ? La réponse dépend du code de la méthode delete. Une implémentation de base pourrait ressembler à :

class ItemsController < ApplicationController
        def delete
                Item.delete(params[:id])
        end
end

Pour se protéger des URL forgées, on pourrait la transformer en :

class ItemsController < ApplicationController
        def delete
                @item = @current_user.items.find(params[:id])
                @item.delete if @item
        end
end

Ce n'est pas parfait (on pourrait vérifier que c'est bien une requête de type POST), mais c'est déjà beaucoup mieux.

Un dernier petit truc pour la route avant de passer à autre chose. Si vous avez une API pour laquelle vous utilisez la sérialisation XML, il peut être intéressant de surcharger ActiveRecord#to_xml pour que le champ secret_field n'y apparaisse pas :

class Item < ActiveRecord::Base
        def to_xml(args={})
                super({:except => [:secret_field]}.merge(args))
        end
end

Cross-Site Scripting

Jusque maintenant, nous avons vu des attaques directes : un utilisateur essaye de s'en prendre à notre site. Il existe également des attaques plus pernicieuses que l'on classe sous le nom de Cross-Site Scripting (XSS en abrégé). Leur but est de s'en prendre aux utilisateurs de notre site en glissant des cochonneries sur notre site. Ceci peut aller du spammeur qui mettra une balise <iframe> vers son site dans tous les formulaires qui lui passent sous la main à l'injection de javascript non maîtrisé.

Par exemple, quelqu'un crée un item dont la description est la suivante :

<script>document.location='http://www.programmez.com/';</script>

Si maintenant un visiteur affiche la description de cet item, il sera redirigé vers le site www.programmez.com. Vous vous dites que c'est ennuyeux mais pas bien méchant ? Oui, mais la même technique permet de voler les cookies et donc les sessions associées. Nous allons donc chercher à nous protéger de ces failles XSS.

Pour cela, il est important de faire une distinction entre 2 cas : est-ce que le champ que vous allez afficher peut contenir des balises HTML ou non ? Pour afficher le nom d'un item, on sera dans le premier cas, à savoir pas de balises HTML : on veut juste afficher le nom tel que l'a rentré son propriétaire. Par contre, on peut souhaiter être plus souple pour la description de l'item et laisser la possibilité d'avoir un titre (balise <h1>), du gras (<b>) ou de l'italique (<i>). Ces 2 cas ne se traitent pas de la même façon. Pour le premier cas, Rails nous offre un moyen simple de nous en protéger : le helper h. En pratique, à chaque fois que l'on souhaitera afficher le titre d'un item, on procédera de la manière suivante :

<%=h @item.title %>

Ce h va convertir les caractères qui pourraient être interprétés par un navigateur web en l'entité HTML correspondante. Problème résolu.

Le deuxième cas est par contre plus difficile à traiter. Vous pouvez être tenté d'utiliser un moteur de formatage de texte comme RedCloth. Attention, cela ne suffit pas à filtrer toutes les attaques ! Pour votre tranquillité, il vaut mieux utiliser le plugin WhiteList. Depuis Rails 2.0, ce plugin fait partie du framework et peut s'utiliser de la façon suivante :

<%= sanitize @item.description, :tags => %w(b i h1) %>

Il est possible de déclarer les balises autorisées de manière globale : je vous renvoie à la documentation officielle. Et pour ceux qui veulent être sûrs de ne pas oublier d'appel à h ou à sanitize, il existe des moteurs de template alternatifs comme Safe ERB ou Erubis. Ces moteurs adoptent l'approche opposée : ils filtrent par défaut tous les éléments <%= %>, charge au développeur d'indiquer explicitement ceux pour lequel le moteur ne fera pas de filtrage.

Cross-Site Request Forgeries

Juste avant de finir, je voudrais juste dire un mot sur un dernier type d'attaques. Les CSRF, abréviation de Cross-Site Request Forgery, sont des attaques complexes qui visent à forcer l'utilisateur à envoyer une requête HTTP vers notre site lorsque celui-ci visitera le site de l'attaquant. Je vous renvoie à wikipedia si vous voulez comprendre comment fonctionne ce type d'attaques. Sachez que Rails vous protège de celles-ci depuis la version 2.0 et qu'il existe un plugin pour les versions plus anciennes : CSRF-killer.

Conclusion

Nous avons pu voir qu'en prenant quelques bonnes habitudes, on pouvait développer des applications sûres en Rails. Il reste cependant des sujets que je n'ai pas abordés comme l'administration de Rails, apache ou MySQL (suite), la manipulation des fichiers ou encore le filtrage des informations sensibles dans les logs. Il est également important de se tenir au courant des mises à jour de sécurité de Rails et des plugins que vous utilisez.

Je remercie Benoît Sibaud pour sa relecture attentive.

Références

samedi 28 juin 2008

LinuxFR.org a dix ans, soirée Firefox 3 et autres joyeusetés

Je n'ai pas pour habitude de faire des billets en vrac, mais ce sera exceptionnellement le cas. Je souhaite en effet vous parler de plusieurs points qui n'attendront pas :

LinuxFR a 10 ans !

Hé oui, c'est aujourd'hui, le 28 juin, que LinuxFR fête 10 ans de dépêches, journaux et autres informations autour de Linux et des Logiciels Libres. J'espère que LinuxFR pourra continuer à animer la vie de la communauté du Logiciel Libre pour encore quelques années.

Soirée Firefox 3

Hier soir avait lieu la soirée Firefox 3. Je dois avouer que j'ai été déçu par la soirée : peu de monde, pas de musique, l'ambiance n'était pas au rendez-vous :/ Tristan Nitot a pris des photos de la soirée.

RMLL du 1er au 5 juillet

La semaine prochaine, ce sera RMLL. Ca se passe à Mont-de-Marsan, et j'y serais pour tenir le stand de Ruby France et donner une conférence sur LinuxFR. J'espère y croiser des lecteurs de mon blog ;)

Un gros merci à AF83 qui me laisse y aller pendant mes jours de boulot.

Do You Buzz

Do You Buzz est un nouveau service en ligne pour publier son CV. Chose intéressante, c'est le premier site développé avec le framework Turbulences en dehors d'AF83.

Le site est encore en bêta privée, mais il marche déjà très bien et l'interface est vraiment agréable à utiliser. J'en sais quelque chose, car je fais parti des premiers beta-testeurs (mon CV est visible sur http://www.doyoubuzz.com/bruno-mich...).

vendredi 30 mai 2008

Github theme for Vim

Scott Becker has made a Github theme for Textmate, so I've decided to made a Github theme for ViM.

It's available on github: Github Vim Theme.

Screenshot of the Github theme for Vim

samedi 10 mai 2008

Outils pour tracer des graphes

Je cherche depuis un certain temps un outil pour tracer des graphes. En général, j'utilise la suite Graphviz pour faire cela. Le principe est relativement simple : on décrit le graphe dans un fichier au format dot, puis on utilise un des 5 outils (dot, neato, fdp, circo et twopi) pour générer une image. Cela marche plutôt bien, mais les graphes générés sont sobres, pour ne pas dire moches (voir la galerie).

Je connaissais également LGL, mais il est surtout adapté pour tracer des graphes avec beaucoup de noeuds et/ou arêtes. Il existe aussi des outils pour tracer des diagrammes (genre Dia) qui peuvent être utilisés pour tracer des graphes, mais je préfère de loin l'approche de graphviz.

Et récemment, je suis tombé sur Nodebox : le choc, des jolis graphes ! Malheureusement, Nodebox fonctionne sous MacOSX. Il existe bien un port pour GNU/Linux sous QT, mais je n'arrive pas à utiliser le module Graph avec celui-ci :/ Shoebox est une réécriture de nodebox (sous Cairo ce coup-ci), mais j'ai l'impression qu'il n'est pas encore assez avancé pour faire quelque chose d'utile avec.

Toujours à partir de Nodebox, j'ai découvert NetworkX, mais, si j'ai bien compris, c'est une surcouche à Graphviz. Les exemples de la gallerie me semblent quand même plus jolis que ceux de GraphViz. Est-ce que l'auteur de NetworkX a passé du temps pour faire ces exemples ou est-ce que je me suis trompé sur NetworkX ? Je ne saurais dire, mais cela vaudrait sûrement le coup que j'y rejette un coup d'oeil à l'occasion.

Enfin, la solution viendra peut être du Javascript. Le JavaScript Information Visualization Toolkit (JIT) est une bibliothèque pour tracer des graphes. Ce n'est pas aussi simple que GraphViz et, pour le moment, limité aux arbres, mais cela pourrait devenir une solution intéressante. Le projet Processing.js montre que l'on peut utiliser la balise Canvas pour faire un rendu qui n'a rien à envier au Desktop. Alors qui sait, peut être que JIT pourra vraiment devenir la solution pour tracer de jolis graphes même si l'utilisation de javascript peut surprendre pour cela...

Mise à jour : je viens de découvrir un nouveau venu : Ubigraph. Les démos sont impressionnantes, mais le serveur n'est malheureusement pas sous une licence libre.

- page 3 de 5 -