auto_restrict 3.3 : toujours plus loin, toujours plus haut

Et allllleeeeez... encore une mise à jour pour ce script de sécurisation d'accès à une page php...   *bigfacepalm* 

Ben c'est pas ma faute !   

Comme je l'utilise tout le temps, je le confronte à de nouvelles situations qui me donnent des idées... pis voilà (on n'est jamais à l'abri d'avoir une idée, comme ça, subrepticement  )

 

Enfin, bref, pour les ceusses qui veulent plus se fracturer les rouleaux avec la sécurisation à chaque fois qu'ils veulent se faire un petit espace admin ou une page de config, je pose le bouzin ici

 


[épisodes précédents : , et ]

Quoi de neuf, cette fois ?!

  • ajout de la possibilité de préciser le root, ce qui permet à auto_restrict de toujours placer et chercher ses fichiers correctement quel que soit le script qui l'appelle et sa position dans l'arborescence
  • meilleure sécurisation du cookie: désormais, tout cookie correspond à un fichier token local, sinon, dehors...
  • les fichiers ne traînent plus un peu partout: le script crée son propre dossier de travail et y stocke les fichiers de passe, de salt, de bannissement, de token etc
  • ajout de la possibilité de filtrer automatiquement toute donnée $_POST ou $_GET via un strip_tags (deux variables booléennes de config font leur apparition: $auto_restrict['GET_striptags']$auto_restrict['POST_striptags']

 

Désormais, auto_restrict peut être configuré quel que soit le contexte d'appel: des fichiers php peuvent l'inclure de n'importe où dans l'appli et on peut même sécuriser des scripts appelés via ajax, donc dépourvus du contexte d'appel global.

 

J'ai eu besoin de ce genre de modifications dans une aplli d'évaluation en ligne pour les élèves (dont j'ai fait mention à plusieurs reprises) et que je suis en train d'améliorer pour y intégrer les versions en ligne des cours, des fiches de révision et de travail, les résultats en temps réel etc... 

Tous les scripts sensibles de la partie admin, du menu au moindre fichier appelé via ajax (basculer le trimestre, sauver temporairement le travail etc) en passant par toutes les pages destinées à créer du contenu sont sécurisés par des appels à auto_restrict... et ça fonctionne  


 

Comme à chaque fois, je vous renvoie vers le gihub pour vous faire une idée.

 


'tain, si ça continue, y'aura plus de versions de ta merde que d'épisodes de Grey's anatomy... pfff.

Vu la qualité de l'ensemble et la pertinence des modifications, j'aurais plutôt choisi Heroes pour la comparaison....

 

Dis-donc, c'est plus un come back les gars, c'est une véritable résurrection façon La nuit des morts vivants: vous poussez le soucis scrupuleux du détail jusqu'à l'imitation olfactive... quel professionnalisme !

 


Un tic-tac ?!

 

 

auto_restrict 3.1 : you shall not pass (at least without a token)

Voici une nouvelle version de ce script qu'il suffit d'inclure dans une page php pour en restreindre l'accès au seul admin.

 

Cette nouvelle version accroît la sécurité :

  • en incluant (enfin!) la gestion automatisée des tokens permettant de s'assurer que les données reçues proviennent bien du formulaire prévu et non d'un usurpateur de session.
  • en permettant d'implémenter une sécurité supplémentaire sur les formulaires sensibles.
  • en gérant de façon transparente le bannissement/débannissement des IP et les problèmes de referrer.

 

Si ça intéresse quelqu'un, c'est posé ici


 

De quoi-t-est-ce qu'il s'agit-il ?

J'ai déjà expliqué le fonctionnement de base de la version précédente, je vais donc me contenter de résumer rapidement:

auto_restrict est un script à inclure le plus tôt possible dans une page php, en tout cas avant les parties sensibles de la page (si j'ose dire).

 

C'est lui qui va prendre la main et gérer pour vous toute la sécurisation de l'accès à la page, de la création du passe lors du premier accès jusqu'à la gestion de la connexion/déconnexion en passant par les problèmes de session et de referrer.

 

 

Comment que ça fonctionne, mon bon monsieur ?

Utilisation de base: login/logout

On ajoute simplement <?php include('auto_restrict.php');?> à la page. Oui, c'est tout.

 

Sécuriser les formulaires

Pour sécuriser un formulaire en utilisant les tokens, on ajoute <?php newToken();?> dans le formulaire: le token sera généré, mis en session et ajouté au formulaire dans un input hidden.

Oui, c'est tout...

 

On peut bien entendu sécuriser également des données $_GET de la même façon...

et même se contenter d'ajouter le token sur une URL en passant le paramètre $token_only à true, par exemple: 

<a href="http://warriordudimanche.net/url/dune/page/securisee.php?token=<?php newToken(true);?>">Action téméraire !</a>

 

Histoire renforcer encore la sécurité sur les actions sensibles, on peut ajouter <?php adminPassword();?> dans le formulaire afin que l'usager soit obligé de taper le mot de passe pour que le formulaire soit traité.

Oui, c'est tout...

En effet, auto-restrict étant appelé avant le traitement des données sur la page d'origine, il va vérifier le mot de passe avant tout autre chose et stopper le script en cas de problème...

 

 

Autres aspects de sécurité

Le referrer

Auto_restrict bloquera toute action provenant d'une autre origine que celle du serveur sur lequel il est hébergé. Même s'il est possible de changer le referrer, ça ne mange pas de pain.

 

Le bannissement d'IP

Le script gère seul et de façon transparente les bannissements d'IP en cas de problème.

Il incrémente un compteur correspondant à l'IP du visiteur et bloque l'accès si le nombre de connexions frauduleuses a dépassé le quota.

Le débannissement est également automatique au bout d'un certain temps (paramétrable).

 

 

Configuration du script

J'ai prévu une configuration par défaut pour tous les paramètres, mais il est toujours possible de la modifier: il suffit de définir le tableau $auto_restrict avant l'inclusion du script.

$auto_restrict['session_expiration_delay'] // durée de vie de la session en minutes 
$auto_restrict['cookie_expiration_delay'] // durée de vie du cookie en jours
$auto_restrict['IP_banned_expiration_delay'] // durée de bannissement d'IP en secondes
$auto_restrict['max_security_issues_before_ban'])) //nombre maximum de problèmes de sécurité avant bannissement
$auto_restrict['just_die_if_not_logged'] // (défaut: false) si à true, ne charge pas le formulaire de login si aucun utilisateur n'est loggué (pour éviter de voir apparaître le formulaire de connexion lors d'un accès via Ajax à un script php protégé par exemple)
$auto_restrict['just_die_on_errors'] // (défaut: true) si à true, toute action dont la sécurité est compromise génère un simple message d'erreur et bloque le script; à false, la session est fermée et on est redirigé vers le formulaire de login.
$auto_restrict['tokens_expiration_delay'] // durée de vie des tokens en secondes
$auto_restrict['use_GET_tokens_too'] // utiliser également les tokens pour les variables $_GET
$auto_restrict['use_ban_IP_on_token_errors'] // utiliser le système de bannissement lors d'une erreur de token
            

 

 

Améliorations prévues ou possibles

  • Je pense ajouter un fichier log permettent de conserver une trace de toutes les actions provoquant un problème de sécurité (avec pourquoi pas une alerte lors de la connexion de l'admin)
  • je songe aussi à permettre la sécurisation automatique des données $_POST et $_GET (débrayable via la config)

 

 

Téléchargement, démo et tout ça

Pour voir le script en fonctionnement, rendez-vous sur la page de démo, qui permet de se faire une idée de ses différents aspects (login: demo / passe: demo)

 

Pour récupérer le zip, c'est direction le dépôt GitHub.

 

 


Pour terminer, je préciserai une nouvelle fois que je ne suis pas du tout spécialiste de la sécurité et que je serai heureux d'améliorer tout problème que vous me signalerez

Les modifications de cette version découlent d'ailleurs des remarques virulentes d'un utilisateur de GitHub qui m'avait fait un vigoureux retour... (vigoureux mais utile)

 

A+ les copains !

 

auto_galerie: insérer une galerie d'images en une ligne !

Et PAF ! \o/ le logo qui pique dans les yeux !  

Mouhouhaha !  

 

Plus sérieusement, sur la base de la fonction auto_thumb de la semaine dernière j'ai bricolé une routine qui génère une galerie d'image à partir du chemin de dossier contenant lesdites images.

C'est simple et ça fonctionne... si quelqu'un en veut, c'est posé là dessous


function auto_galerie($path=null,$title=null,$width=100,$height=100,$crop=false,$infos=false,$style=false){
    if (!$path){return false;}
    $liste=array_merge(glob($path.'/*.png'),glob($path.'/*.gif'),glob($path.'/*.jpg'),glob($path.'/*.jpeg'));
    $thumb_name='_THUMB_';$crop_name='_CROPPED_';$prop_name='_PROPORTION_';
    if (!empty($liste)){
        if ($style){
            echo '<style>
            div.galerie{margin:auto;width:600px;text-align:center;}
            div.photo{width:'.$width.'px;height:'.$height.'px;margin:5px;padding:5px;display:inline-block;vertical-align:top;border-radius:3px;}
            div.photo:hover{background:#79c;}
            div.galerie h1.title{}
            div.photo img{opacity:0.6}
            div.photo:hover img{opacity:1}
            div.photo .infos{display:none;cursor:default;}
            div.photo:hover .infos{display:block;position: relative;top: -100%;background-color:rgba(0,0,0,0.5); color:#eee;text-shadow:0 1px 1px #999}
            div.photo:hover{transform:scale(1.2,1.2);-webkit-transform:scale(1.2,1.2);-moz-transform:scale(1.2,1.2),-o-transform:scale(1.2,1.2); }
            div,div:hover{transition: all 300ms;}

            </style>
            ';
        }

        echo '<div class="galerie">';
        if ($title){echo'   <h1 class="title">'.$title.'</h1>';}

                    foreach($liste as $image){  
                        $i=basename($image);
                        if (stripos($i,$thumb_name)===false&&stripos($i,$crop_name)===false&&stripos($i,$prop_name)===false){               
                            echo "<div class='photo'>
                                <a href='http://warriordudimanche.net/$image' onclick='window.open(this.href);return false;'><img src='http://warriordudimanche.net/".auto_thumb($image,$width,$height,'_THUMB_',$crop)."' /></a>";
                                if ($infos==true){
                                    echo '<div class="infos">';
                                    echo '<div class="nom">'.basename($image).'</div>';
                                    $taille=round(filesize($image)/1000,1);

                                    echo '<div class="taille">'.$taille.' Ko</div>';
                                    echo '</div>';
                                }
                            echo '</div>';
                        }
                    }

        echo '<div style="clear:both"></div></div>';

    }else{echo '<p class="error">Pas d\'images dans <em>'.$path.'</em></p>';}

}

Cette fonction peut se contenter du seul chemin:

auto_galerie("images");

Mais peut prendre les paramètres suivants (dans l'ordre):

  • $title: le titre de la galerie
  • $width: la largeur des miniatures
  • $height: la hauteur des miniatures
  • $crop: recadrage des images ou pas (non recadrées par défaut)
  • $infos: affichage des infos (nom et taille de l'image, non affichés par défaut)
  • $style: style css de base (off par défaut)

 

Si vous voulez utiliser vos propres css, les ciblages sont enfantins:

  • div.galerie
  • div.photo
  • div.infos_photo
  • div.nom_photo
  • div.taille_photo

 

Comme d'habitude, voici la page de démo (la même que celle d'auto_thumb mais avec l'utilisation d'auto_galerie en plus) 

J'ai aussi refait un zip contenant tout le nécessaire, les fonctions étant regroupées dans le nouvel auto_thumbs.php...

 

Allez, à la semaine prochaine avec un plugin pluxml qui utilise tout ça

Auto_thumb 2.0: plus de mieux, moins de "pas bien"

Tout à mes petits projets, j'utilise régulièrement mes fonctions afin d'éviter de me retaper le boulot... Or, parfois, il s'avère qu'un dépoussiérage-amélioration s'avère nécessaire avant inclusion... 

J'y vois alors l'occasion de parfaire ladite fonction tout en essayant de lui conserver son aspect simple et réutilisable.

 

C'est le cas de la fonction auto_thumb qui créait des miniatures sans respecter les proportions des images, afin de coller aux dimensions demandées.

Après un an et demi à moisir dans la todo, cette feature s'est rappelée à moi...

 


Je redonne donc la page de démo, qui n'a pas trop changée et propose toujours:

l'intégration au sein d'une balise img:

<img src="http://warriordudimanche.net/<?php echo auto_thumb('i/image2.png',50,50); ?>" />

 

ou la génération de cette balise dans une boucle, pour une galerie par exemple:

// redimensionnement sans recadrage
for ($n=1 ; $n<10 ; $n++){                   
    echo "<div class='photo'><a href='http://warriordudimanche.net/$n.jpg' target='_BLANK'><img src='http://warriordudimanche.net/".auto_thumb('i/'.$n.'.jpg',139,139)."' alt='$n.jpg'/></a></div>";
}
// et avec recadrage (j'ai changé la chaine identifiant la miniature (_THUMB_ -> _CROPPED_  pour éviter d'écraser les miniatures de la version précédente
for ($n=1 ; $n<10 ; $n++){
        echo "<div class='photo'><a href='http://warriordudimanche.net/$n.jpg' target='_BLANK'><img src='http://warriordudimanche.net/".auto_thumb('i/'.$n.'.jpg',139,139,'_CROPPED_',true)."' alt='$n.jpg'/></a></div>";
}

auto_thumb($chemin_image, [$width=100], [$height=100], [$chaine_identifiant_miniature="_THUMB_"], [$cropped=false]);


Revoilà donc le zip mis à jour...

 

 

La semaine prochaine, une fonction qui utilise ça, ok ?

auto_dropzone: un script pour les uploader tous

Dans la série "Bronco veut régler un problème une fois pour toutes" il a décidé de faire un script qu'il suffit d'inclure dans une page pour ajouter une zone de drag&drop de fichiers.

 

Le script en question s'occupe de tout sans dépendances: il génère la dropzone, les css par défaut, le javascript qui gère le D&D et s'occupe même de l'upload pour vous.

Il est en outre possible de le configurer pour l'adapter... elle est pô belle  chouette la vie ?

 


 

Ce que ce script fait actuellement:

  • génération de la dropzone
  • config par défaut + css par défaut + classes par défaut
  • gestion de l'upload
  • possibilité d'upload dans des dossiers différents en fonction du type de fichiers
  • limitation de la taille et du format des fichiers.
  • gestion des erreurs de dossier inexistant/taille excessive/ type interdit/problème d'upload
  • configuration simple

 

Ce qu'il ne fait pas:

  • la gestion des fichiers une fois uploadés (effacement par exemple)
  • la gestion de l'écrasement d'un fichier (pas de renommage automatique)
  • un fallback pour les vieux navigateurs (zavez qu'à mettre à jour )

 


 

La config se fait, comme toujours, via un array (on peut ne préciser que les valeurs qu'on veut modifier, des valeurs par défaut seront attribuées aux keys manquantes)

$auto_dd_upload=array(
    'destination_filepath'=>'path/to/', 
    'dropzone_text'=>'D&D here !',
    'dropzone_class'=>'drop_images', 
    'dropzone_id'=>'drop_images', 
    'dropzone_style'=>'',
    'info_style'=>'',
    'allowed_filetypes'=>'png,gif,jpg,jpeg',
    'use_style'=>true, // false if you're using an css file
  );

 

Si on veut utiliser ses propres styles, il suffit de mettre use_style à false.

En ce qui concerne le chemin d'upload, il est aisé d'en spécifier un ou plusieurs (sans oublier le "/" final): 

$auto_dd_upload['destination_filepath']='upload/';

Ici, c'est une chaine, le même chemin sera utilisé pour tous les fichiers. 

 

 

$auto_dd_upload['destination_filepath']=array('gif'=>'upload/giffiles/','png'=>'upload/pngfiles/');

En en faisant un array, on donne un chemin d'upload différent pour chaque type de fichier. 

Le code est commenté et assez clair, je pense.

 


La dropzone générée possède ses propres classes et vous permet de les cibler simplement:

        <div class="DD_dropzone" id="dropArea" >
            <p class="DD_text">Drop files here</p>

            <div class="DD_info" >
                <div id="result"></div>
                <div id="DD_progressbar"></div>
            </div>
        </div>

A noter d'une part qu'il est possible d'ajouter une classe et de changer l'id de la div DD_dropzone via la variable de config et que d'autre part, on peut fixer l'attribut style de plusieurs éléments.

Les évènements drag, drop, upload etc ajoutent des classes donnant la possibilité de styler la zone en fonction d'eux.

  • .DD_hover (survol de la zone pendant le drag)
  • .DD_error
  • .DD_success
  • .DD_uploading


 

Si vous êtes intéressés par un petit test, vous pouvez faire un tour du côté du dépôt GitHub ou de la démo (les fichiers ne sont pas conservés)

 

 


 

 

Dis-donc, ça va pas mieux... le v'la qui se met à parler de lui à la troisème personne...

 

 

 

Tu sais les médocs qu'il t'a donné le docteur: ben faut les prendre !

 

 

 

 

 

J'hésite un peu: vos mères en ont vraisemblablement pris pendant la grossesse, on voit le résultat...

 
Fil RSS des articles de cette catégorie