Carnet Wiki

ConseilsSecurite

Version 5 — 3 months ago JLuc

Cette page vise à recueillir et présenter les recommandations en matière d’injection de code dans SPIP.

Protégez le code php dans les squelettes

Cerdic : Si jamais on écrit du php dans un squelette :
-  TOUJOURS appliquer |texte_script a la fin d’un filtre qu’on injecte dans une variable PHP,
-  TOUJOURS utiliser des simples quotes

  1. $toto = '[(#TRUC|filtre_ce_que_tu_veux|texte_script)]’;

Protegez vos INCLURE

Dans le cas où le squelette inclus contient la balise #SELF ou #PAGINATION
et uniquement dans ce cas là, il est nécessaire de protéger self
dans l’appel à l’inclure, donc de mettre un argument du type {self=#SELF} dans la balise INCLURE.

Exemple :
<INCLURE{fond=inc-petition}{id_article}{self=#SELF}>

Notes :
-  ainsi on fonde l’url de cache du fragment inclu sur l’url de la page appelante
-  #PAGINATION en interne fait appel à #SELF

Refs : Fil sur spipdev, 5 et 6 Juin 06 (le début du thread étant là)


Accés restreint

Là c’est pas une protection contre l’injection de code donc c’est hors sujet.

Stéphane Laurent confie :
— “je fais généralement une première passe qui va definir les squelettes, css et gère la
sécurité ...
et derrière, j’ai une couche qui positionne les différents éléments inclus.
Si ces éléments sont complexes, ils nécessitent eux même plusieurs inclures ...”

Refs : Stéphane Laurent sur spipdev, 7 Juin 06

je ne sais pas si c’est une reference, mais bon, voici un exemple complet avec les articles :
j’ai des groupes de mot "techniques (je les préfixe par un _ pour pouvoir les exclure facilement des boucles mot) que j’affecte aux rubriques : _sq_squelette(un mot par squelette, par exemple “_toto”, “_titi”), _sq_securite (0,1 et 4, 0 etant reservé aux admins, 1 aux redacteurs et admins et 4 aux visiteurs authentifiés)

squelettes/article.html :

<BOUCLE_head(ARTICLES){statut=publie}{id_article}><?php 
         global $auteur_session;
         $statut="5";
         if ($auteur_session['statut']=="") $statut="5";
         else if ($auteur_session['statut']=="6forum") $statut="4";
         else $statut=substr($auteur_session['statut'],0,1);
        $sq_squelette='';
        $sq_id_rubrique=0;
        $sq_securite='5'; 
?><BOUCLE_HIERARCHIE(HIERARCHIE){id_rubrique}>
 <BOUCLE_MOT_COULEUR_PARENT(MOTS){id_rubrique}{type=_sq_couleurs}{0,1}><?php 
    if($sq_couleur=='') $sq_couleur='[(#TITRE|texte_script)]'; 
?></BOUCLE_MOT_COULEUR_PARENT>
 <BOUCLE_MOT_TYPO_PARENT(MOTS){id_rubrique}{type=_sq_typographies}{0,1}><?php 
         if($sq_typographie=='') $sq_typographie='[(#TITRE|texte_script)]'; 
?></BOUCLE_MOT_TYPO_PARENT>
 <BOUCLE_MOT_SQUELETTE_PARENT(MOTS){id_rubrique}{type=_sq_squelettes}{0,1}><?php
         if($sq_squelette=='') {
                 $sq_squelette='[(#TITRE|texte_script)]'; 
                 $sq_id_rubrique=[(#ID_RUBRIQUE)]; 
        }
?></BOUCLE_MOT_SQUELETTE_PARENT>
 <BOUCLE_MOT_SECU_PARENT(MOTS){id_rubrique}{type=_sq_securites}{0,1}><?php 
         if ('[(#TITRE|texte_script)]'<$sq_securite)
                         $sq_securite='[(#TITRE|texte_script)]';
 ?></BOUCLE_MOT_SECU_PARENT>
</BOUCLE_HIERARCHIE>
<BOUCLE_MOT_COULEUR(MOTS){id_rubrique}{type=_sq_securites}{0,1}><?php 
        $sq_couleur='[(#TITRE|texte_script)]'; 
?></BOUCLE_MOT_COULEUR>
<BOUCLE_MOT_TYPO(MOTS){id_rubrique}{type=_sq_typographies}{0,1}><?php 
         $sq_typographie='[(#TITRE|texte_script)]'; 
?></BOUCLE_MOT_TYPO>
<BOUCLE_MOT_SQUELETTE(MOTS){id_rubrique}{type=_sq_squelettes}{0,1}><?php 
        $sq_squelette='[(#TITRE|texte_script)]'; 
                $sq_id_rubrique=[(#ID_RUBRIQUE)]; 
?></BOUCLE_MOT_SQUELETTE>
<BOUCLE_MOT_SECU(MOTS){id_rubrique}{type=_sq_securites}{0,1}><?php 
         if ('[(#TITRE|texte_script)]'<$sq_securite)
                         $sq_securite='[(#TITRE|texte_script)]';
?></BOUCLE_MOT_SECU><?php 
if ($statut<=$sq_securite)
{        
        if($sq_couleur=='') $sq_couleur='defaut'; 
        if($sq_typographie=='') $sq_typographie='defaut';
        if($sq_squelette=='defaut') $sq_squelette='';
        $sq_squelette='article'.$sq_squelette; 
?><INCLURE(bloc_sq.php3){id_article}>
<?php 
} else {
?>
accès interdit
<?php 
}
?>
</BOUCLE_head>

Ce squelette va donc gerer la securité, et mettre en place les parametres de squelette, couleur et typo qui seront passés à la feuille de style.

squelettes/bloc_sq.php3 :

$delais=3600;
//secu basique
if (strstr($sq_squelette, '..') 
OR preg_match(',^formulaire_,i', $sq_squelette) {
                die ("securité !");
}
else $fond = "_".$sq_squelette;
if ($contexte_inclus['bloc_delais']) $delais = $contexte_inclus['bloc_delais'];


$contexte_inclus['sq_typographie']=$sq_typographie;
$contexte_inclus['sq_couleur']=$sq_couleur;
$contexte_inclus['sq_id_rubrique']=$sq_id_rubrique;


include ("inc-public.php3");

le squelette correspondant au mot clé sera appelé (par defaut _article.html) et les parametres mis dans le contexte.

=> Attention, il faut empecher l’accès direct à ces squelettes et à bloc_sq.php3 (.htaccess) et en particulier, “blinder” page.php3, par exemple :

// Securite 
if (strstr($fond, '/')
OR preg_match(',^_,i', $fond)) 
OR preg_match(',^formulaire_,i', $fond)) {
        die ("Faut pas se gener");
}

On aura donc le squelette _article_toto.html appelé si on a affecté le mot _sq_squelettes:_toto à la rubrique ou plus haut dans la hierarchie
dans les squelettes _article, j’appelle :

<link rel="stylesheet" href="style.php3?sq_typographie=[(#ENV{sq_typographie,defaut})]&sq_couleur=[(#ENV{sq_couleur,defaut})]&id_rubrique=[(#ENV{id_rubrique})]&sq_id_rubrique=[(#ENV{sq_id_rubrique})]" type="text/css">

style.php3 appelant un squelette style.html.
J’ai donc une feuille de style calculée et mise en cache par rubrique.