WebDev (PHP et SEO) : Un peu de PHP, des regex, des tests et du référencement (il parait qu'il faut dire CEO ?).

PluXml : des url 100% configurables

PluXml

Cinq jours après la sortie de PluXml 5.1.6, nous sortons aujourd'hui un plugin qui vous permettra de configurer totalement les urls.

Il sera dorénavant possible de transformer vos urls l'articles :
http://amoweb.fr/article151/savoir-gerer-les-fichiers-d-un-projet en :
http://amoweb.fr/article151-savoir-gerer-les-fichiers-d-un-projet.html ou encore :
http://amoweb.fr/articles/151-savoir-gerer-les-fichiers-d-un-projet.html

Bon test.

Téléchargement : http://forum.pluxml.org/viewtopic.php?id=3344

PluXml en version 5.1.1 !

PluXml

Si vous n'avez pas encore essayé PluXml (prononcez [Plu X M L]), c'est le moment de vous lancer.
La remise en question permanente et la proximité avec les utilisateurs par le forum ont permis d'aller encore plus loin pour cette version.
Il est désormais possible de redimensionner les images. L'interface a été aussi entièrement repensées, rajeunie, et rendue beaucoup plus pratique. Par exemple l'upload de multiples fichiers n'est plus limité. On note aussi le gestionnaire de plugins afin de décupler les possibilité (simplifier l'installation d'éditeur wysiwyg par exemple). PluXml est aussi disponible en 7 langues : Polonais, Espagnole, Allemand, Portugais, Russe, Roumain, Néerlandais, en plus du Francais.
Tout cela en conservant un poids plume, aucune base de donnée, une installation simple.

Si vous voulez en savoir plus, jetez un œil au changelog.
Téléchargement et informations, comme toujours, sur PluXml.org.

Que faire si j'ai trouvé une faille sur un site à 3M de visiteurs par mois ?

Le 26/05/2011 à 15h

dailybooth inc.

Connaissez-vous Dailybooth ?
Il s'agit d'un réseau social à la Twitter, sauf qu'il est centré sur les images. Il ne comptait pas moins de 3 millions de visiteurs uniques par mois en 2009.
Sur un compte, j'ai découvert une curieuse erreur dans la sidebar.

Je regarde donc le code source de la page pour en savoir plus :
Il se trouve que j'ai accès à un dump d'un certain nombre de variables, dont :

  • Le nom d'utilisateur
  • L'adresse email du compte
  • Le hash du mot de passe (le mot de passe sous une forme crypté)
En a peine 3 minutes sur un moteur de recherche, je trouve le mot de passe. (allez-y, confiez vos infos personnelles à n'importe qui).

Et maintenant, je fais quoi ?

Je viens de contacter dailybooth par Twitter, et par courriel. J'espère qu'ils sauront être réactif. J'ai aussi contacté les utilisateurs concernés pour qu'ils changent les mots de passe de leur autres comptes (pas celui de Dailybooth, j'y ai accès).

Une erreur très critique qui touche plusieurs comptes

Je découvre d'autres comptes atteints. Ça frise la catastrophe.

Il faut attendre qu'ils corrigent la faille

Maintenant, il n'y a plus qu'une chose à faire : attendre qu'ils corrigent la faille. Il ne faut surtout pas alerter d'autres personnes. D'ailleurs, je pense que mon twit est de trop. J'écris cet article en attendant, mais le laisse bien sagement dans les brouillons.

Temps de réaction

  • h+0h39 : Pas de réponse, le message d'erreur est toujours visible.
  • h+1h00 : toujours rien. Si j'avais été black hat, qu'aurais-je eu le temps de faire ? Ça laisse rêveur, mais l'éthique vaut beaucoup plus.
  • h+24h : Rien. Contact de deux employés par Twitter et about.me.
  • h+29h : Le contact avec les deux employés semble avoir porté ses fruits. Voilà les erreurs ne s'affichent plus.
  • h+33 : J'ai une réponse de Brian, le directeur général de Dailybooth me remerciant. Ils se chargent de corriger le problème.

Des conclusions ?

Encore un exemple de ce que tout le monde répète depuis des années : utilisez des mots de passes différents pour tous les services ! Il ne faut pas oublier que si on a le mot de passe d'une boite mail, on peut accéder à quasi n'importe quel service qui y sont reliés (facebook, youtube...).

Deuxième conclusion, j'aurai peut être fais gagner 24h à l'entreprise si j'avais contacté directement les employés, bien qu'après tout, ce n'est peut être pas à moi de faire ça : je n'ai même pas de compte sur ce réseau ! Mais c'est l'esprit white hat, que voulez-vous !

Un service de partage de Blocnote en ligne - Les Sources

Suite aux demandes de Tom et Lewo, je met aujourd'hui en ligne le code de mon Simple Black Board en Ajax (PHP et fichiers textes).
Il permet, par l'intermédiaire d'un lien unique de partager un texte et de permettre la modification et la visualisation des modifications en temps réel par les visiteurs.
Le code est largement inspiré d'un tutoriel du SdZ.

Demo
Télécharger sources (GNU GPL)

Plus d'infos sur Simple Black Board

Anti-XSS : Méthode de vérification de contenu normalisé

Ceux qui développent des sites Internet, ou plus simplement les personnes qui suivent l'actualité on déjà entendu parler de Cross-site scripting (abrégé XSS... vous aussi vous cherchez le X dans Cross ?).
Le principe est simple : arriver à faire exécuter un script non prévus par une application. Par exemple un pirate souhaitant aider les personnes agées qui auraient du mal à retenir leur mot passe... (!)

La faille la plus courante est l'affichage directe d'une variable entrée par l'utilisateur. Le PHP étant un langage "à la volé", l'entrée utilisateur peut être interprétée comme du code PHP ou JavaScript et être exécuté.
Dans la plus part des cas un htmlspecialchars($_GET['var 1']) est suffisant.
Ce problème réside d'une loi qui peut paraitre radicale, mais qui se révèle très adapté à l'informatique : Tout ce qui n'est pas prévus est potentiellement dangereux.
Rien ne nous prouve qu'un utilisateur ne va jamais écris un chiffre au lieu d'une lettre, ou pire, un script au lieu d'un simple texte.
Dans cet article nous allons voir plusieurs méthode automatiques de vérification du contenu des variables. Elles ont pour but de remplacer les méthodes manuelles qui sont sources d'oublis.

Méthode manuelle fonctionnelle :

Cette méthode est relativement courante, elle nécessite de "passer" toutes les variables dans des fonctions de vérifications. Il faut donc créer une fonction pour chaque type : checkInt(), checkHtml(), checkUrl()...

Par exemple pour checkInt() : nous pouvons utiliser le code :

checkInt($entier) {
  return intval($entier);
}
ou avec une expression régulière :
checkInt($entier) {
  if(preg_match('/^[0-9]+$/', $entier))
    return $entier;
  else
    return 0;
}
Dans ces deux cas l'entrée d'un valeur autre qu'un chiffre retournera 0.

Méthode singulière :

Cette méthode est la plus simple à mettre en place car elle ne nécessite pas la modification du code. Cependant le script ne doit pas contenir deux variables de même nom contenant des choses différentes.
Cette méthode est dite singulière car les règles sont fixées individuellement pour chaque variable.

Exemple : Ce code doit être appelé en début de programme :

# Tableau de règles
$type_var = array(
  'id' => '/^[0-9]+$/',
  'level' => '/^[0-9]{4}$/',
  'name' => '/^[a-zA-Z]+$/'
);

# Vérification des variables reçues en $_GET :
foreach ($_GET as $key => $value)
  if(!preg_match($type_var[$key],$value) || isset($type_var[$key])) 
    unset($_GET[$key]);
Dans cette solution nous vérifions si les variables sont bien présentes dans le tableau et si leur contenu correspond bien à la règle. Dans le cas échéant nous supprimons les variables.
Cette solution permet de ne pas oublier de variable, mais peut cependant devenir très lourde avec un grand nombre de variables.

Méthode typée :

Cette méthode part d'un constat simple : il n'est pas toujours possible de répertorier toutes les variables. Nous allons donc mettre un place un système de typage complet.
Adaptons l'exemple précédent avec cette méthode :

# Tableau de règles
$type_var = array(
  '_int' => '/^[0-9]+$/',
  '_4int' => '/^[0-9]{4}$/',
  '_alpha' => '/^[a-zA-Z]+$/'
);

# Vérification des variables reçues en $_GET :
foreach ($_GET as $key => $value)
  if(!preg_match($type_var[strrchr($key,"_")],$value))
    unset($_GET[$key]);
Avec cette solution les variables de l'exemple précédent id, level, name deviendraient id_int, level_4int, name_alpha.
Cette méthode nous oblige à renommer toutes la variables du projet mais peut s'avérer terriblement efficace. Ici nous supprimons les variables non valides, mais rien ne nous empêche de stocker dans notre tableau une valeur de remplacement par défaut. Il serait aussi possible de mélanger la méthode singulier avec la méthode typée. Cela permettrait de traiter à part des variables sans que le type ne soit dans son nom.

Méthode typée : Le cas particulier de l'URL :

Un URL est un cas particulier de notre Méthode typée, car il devient difficile de définir une regex pour une URL quand elle contient des paramètres. Nous allons donc analyser toutes les variables de l'URL, à l'aide de notre tableau. Nous ajoutons un type _url très peu restrictif qui fait un pré-tri.

$_GET["url_url"] = "http://amoweb.fr/index.php?i_int=31d2&c_alpha=abcde&b_int=332";

# Tableau de règles
$type_var = array(
  '_int' => '/^[0-9]+$/',
  '_4int' => '/^[0-9]{4}$/',
  '_alpha' => '/^[a-zA-Z]+$/',
  '_url' => '/^http(s)?:\/\/[-\/.\w?&]{0,64}$/i'

);

# Vérification d'une url :

# Extraction de la partie URL :
$url = explode("?",urldecode($_GET['url_url']), 2);
$_GET['url_url'] = $url[0] . "?";

# Vérifie chaque variable passée en paramètre
foreach (explode("&",$url[1]) as $param) {
	$varGET = explode("=",$param);
	# On fabrique l'URL avec les paramètre valides : dont le contenu correspond au type
	if(preg_match($type_var[strrchr($varGET[0],"_")],$varGET[1]))
		$_GET['url_url'] .= $varGET[0] . "=" . $varGET[1] . "&";
}

# Supprimer le caractère final : soit '?' soit '&'
$_GET["url_url"] = substr($_GET["url_url"], 0, -1);

# Et voilà le travail :
echo $_GET["url_url"]; # http://amoweb.fr/index.php?c_alpha=abcde&b_int=332