From c9c929d9a6c74156a1b97e8b706312f67b853b89 Mon Sep 17 00:00:00 2001 From: Fil <fil@rezo.net> Date: Sun, 1 Jan 2006 17:20:03 +0000 Subject: [PATCH] Introduction d'un modele de securite a deux niveaux : - [(#TEXTE)] : on applique propre() et interdire_script() - [(#TEXTE*)] : on n'applique plus propre(), mais toujours interdire_script() - [(#TEXTE**)] : on n'applique plus rien ; question seccurite tout devient possible, au webmestre de filtrer comme il se doit pour eviter toute injection de php, javascript etc. Par ailleurs les appels a safehtml() se rationalisent un peu (mais pas encore definitif, je pense). --- inc-balises.php3 | 46 ------------------ inc-compilo-api.php3 | 30 ++++-------- inc-compilo-index.php3 | 106 ++++++++++++++++++++++++++++++++++------- inc-html-squel.php3 | 2 +- 4 files changed, 99 insertions(+), 85 deletions(-) diff --git a/inc-balises.php3 b/inc-balises.php3 index ea81174062..55ecbc422f 100644 --- a/inc-balises.php3 +++ b/inc-balises.php3 @@ -23,52 +23,6 @@ if (!defined("_ECRIRE_INC_VERSION")) return; -// -// Traitements standard de divers champs -// -function champs_traitements ($p) { - global $table_des_traitements; - - if (!is_array($table_des_traitements[$p->nom_champ])) - // old style - $ps = $table_des_traitements[$p->nom_champ]; - else { - if ($p->nom_boucle) - $type = $p->boucles[$p->nom_boucle]->type_requete; - else - $type = $p->type_requete; - $ps = $table_des_traitements[$p->nom_champ][$type]; - if (!$ps) - $ps = $table_des_traitements[$p->nom_champ][0]; - } - - if (!$ps) return $p->code; - if ($p->descr['documents']) { - $ps = 'traiter_doublons_documents($doublons, '.$ps.')'; - } - - // on supprime les < IMGnnn > tant qu'on ne rapatrie pas - // les documents distants joints.. - // il faudrait aussi corriger les raccourcis d'URL locales - return str_replace('%s', - (!$p->boucles[$p->id_boucle]->sql_serveur ? - $p->code : - ('supprime_img(' . $p->code . ')')), - $ps); -} - -// il faudrait savoir traiter les formulaires en local -// tout en appelant le serveur SQL distant. -// En attendant, cette fonction permet de refuser une authentification -// sur qqch qui n'a rien a voir. - -function balise_distante_interdite($p) { - $nom = $p->id_boucle; - if ($p->boucles[$nom]->sql_serveur) { - erreur_squelette($p->nom_champ .' '._T('zbug_distant_interdit'), $nom); - } -} - // // Definition des balises // diff --git a/inc-compilo-api.php3 b/inc-compilo-api.php3 index c544c0903d..6eaea401ce 100644 --- a/inc-compilo-api.php3 +++ b/inc-compilo-api.php3 @@ -252,26 +252,26 @@ $exceptions_des_jointures['titre_mot'] = 'titre'; $exceptions_des_jointures['type_mot'] = 'type'; global $table_des_traitements; -$table_des_traitements['BIO'][]= 'traiter_raccourcis(%s)'; -$table_des_traitements['CHAPO'][]= 'traiter_raccourcis(nettoyer_chapo(%s))'; +$table_des_traitements['BIO'][]= 'propre(%s)'; +$table_des_traitements['CHAPO'][]= 'propre(nettoyer_chapo(%s))'; $table_des_traitements['DATE'][]= 'vider_date(%s)'; $table_des_traitements['DATE_MODIF'][]= 'vider_date(%s)'; $table_des_traitements['DATE_NOUVEAUTES'][]= 'vider_date(%s)'; $table_des_traitements['DATE_REDAC'][]= 'vider_date(%s)'; -$table_des_traitements['DESCRIPTIF'][]= 'traiter_raccourcis(%s)'; +$table_des_traitements['DESCRIPTIF'][]= 'propre(%s)'; $table_des_traitements['LIEN_TITRE'][]= 'typo(%s)'; $table_des_traitements['LIEN_URL'][]= 'htmlspecialchars(vider_url(%s))'; -$table_des_traitements['MESSAGE'][]= 'traiter_raccourcis(%s)'; +$table_des_traitements['MESSAGE'][]= 'propre(%s)'; $table_des_traitements['NOM_SITE_SPIP'][]= 'typo(%s)'; $table_des_traitements['NOM_SITE'][]= 'typo(%s)'; $table_des_traitements['NOM'][]= 'typo(%s)'; $table_des_traitements['PARAMETRES_FORUM'][]= 'htmlspecialchars(lang_parametres_forum(%s))'; -$table_des_traitements['PS'][]= 'traiter_raccourcis(%s)'; +$table_des_traitements['PS'][]= 'propre(%s)'; $table_des_traitements['SOURCE'][]= 'typo(%s)'; $table_des_traitements['SOUSTITRE'][]= 'typo(%s)'; $table_des_traitements['SURTITRE'][]= 'typo(%s)'; $table_des_traitements['TAGS'][]= '%s'; -$table_des_traitements['TEXTE'][]= 'traiter_raccourcis(%s)'; +$table_des_traitements['TEXTE'][]= 'propre(%s)'; $table_des_traitements['TITRE'][]= 'typo(%s)'; $table_des_traitements['TYPE'][]= 'typo(%s)'; $table_des_traitements['URL_ARTICLE'][]= 'htmlspecialchars(vider_url(%s))'; @@ -287,21 +287,11 @@ $table_des_traitements['URL_SYNDIC'][]= 'htmlspecialchars(vider_url(%s))'; $table_des_traitements['ENV'][]= 'entites_html(%s)'; -// Securite supplementaire pour certaines tables - -// Articles syndiques : remplacer les filtres par safehtml() +// Articles syndiques : passage des donnees telles quelles, sans traitement typo +// A noter, dans applique_filtres la securite et compliance XHTML de ces champs +// est assuree par safehtml() foreach(array('TITRE','DESCRIPTIF','SOURCE') as $balise) if (!isset($table_des_traitements[$balise]['syndic_articles'])) - $table_des_traitements[$balise]['syndic_articles'] = 'safehtml(%s)'; - -// Forums & petitions : ajouter safehtml aux filtres existants -foreach(array('TITRE','TEXTE','AUTEUR','EMAIL_AUTEUR','NOM_SITE') as $balise) - if (!isset($table_des_traitements[$balise]['forums'])) - $table_des_traitements[$balise]['forums'] = - 'safehtml('.$table_des_traitements[$balise][0].')'; -foreach(array('NOM','NOM_SITE','MESSAGE','AD_EMAIL') as $balise) - if (!isset($table_des_traitements[$balise]['signatures'])) - $table_des_traitements[$balise]['signatures'] = - 'safehtml('.$table_des_traitements[$balise][0].')'; + $table_des_traitements[$balise]['syndic_articles'] = '%s'; ?> diff --git a/inc-compilo-index.php3 b/inc-compilo-index.php3 index 3d8a8ce785..7f59224208 100644 --- a/inc-compilo-index.php3 +++ b/inc-compilo-index.php3 @@ -246,28 +246,98 @@ function collecter_balise_dynamique($l, $p) { return $args; } -function applique_filtres($p) { - // pretraitements standards (explication dans inc-compilo-index) - switch ($statut) { - case 'num': - $code = "intval($code)"; - break; - case 'php': - break; - case 'html': - default: - $code = "trim($code)"; - break; +// il faudrait savoir traiter les formulaires en local +// tout en appelant le serveur SQL distant. +// En attendant, cette fonction permet de refuser une authentification +// sur qqch qui n'a rien a voir. + +function balise_distante_interdite($p) { + $nom = $p->id_boucle; + if ($p->boucles[$nom]->sql_serveur) { + erreur_squelette($p->nom_champ .' '._T('zbug_distant_interdit'), $nom); } +} + + +// +// Traitements standard de divers champs +// definis par $table_des_traitements, cf. inc-compilo-api.php3 +// +function champs_traitements ($p) { + global $table_des_traitements; + + if (!is_array($table_des_traitements[$p->nom_champ])) + // old style + $ps = $table_des_traitements[$p->nom_champ]; + else { + if ($p->nom_boucle) + $type = $p->boucles[$p->nom_boucle]->type_requete; + else + $type = $p->type_requete; + $ps = $table_des_traitements[$p->nom_champ][$type]; + if (!$ps) + $ps = $table_des_traitements[$p->nom_champ][0]; + } + + if (!$ps) return $p->code; + + // Si une boucle sous-jacente (?) traite les documents, on insere ici + // une fonction de remplissage du tableau des doublons -- mais seulement + // si on rencontre le filtre propre (qui traite les + // raccourcis <docXX> qui nous interessent) + if ($p->descr['documents'] + AND preg_match(',propre,', $ps)) + $ps = 'traiter_doublons_documents($doublons, '.$ps.')'; + + // De meme, en cas de sql_serveur, on supprime les < IMGnnn > tant + // qu'on ne rapatrie pas les documents distants joints.. + // il faudrait aussi corriger les raccourcis d'URL locales + if ($p->boucles[$p->id_boucle]->sql_serveur) + $p->code = 'supprime_img(' . $p->code . ')'; + + // Remplacer enfin le placeholder %s par le vrai code de la balise + return str_replace('%s', $p->code, $ps); +} + + +// +// Appliquer les filtres a un champ [(#CHAMP|filtre1|filtre2)] +// retourne un code php compile exprimant ce champ filtre et securise +// - une etoile => pas de processeurs standards +// - deux etoiles => pas de securite non plus ! +// +function applique_filtres($p) { + + // Traitements standards (cf. supra) + if ($p->etoile == '') + $code = champs_traitements($p); + else + $code = $p->code; -// processeurs standards (cf inc-balises) - $code = ($p->etoile ? $p->code : champs_traitements($p)); // Appliquer les filtres perso - if ($p->param) $code = compose_filtres($p, $code); - // post-traitement securite - if ($p->interdire_scripts) - $code = "interdire_scripts($code)"; + if ($p->param) + $code = compose_filtres($p, $code); + + // Securite + if ($p->interdire_scripts + AND $p->etoile != '**') { + + switch ($p->type_requete) { + // Passer |safehtml sur les boucles "sensibles" + case 'forums': + case 'signatures': + case 'syndic_articles': + $code = "safehtml($code)"; + break; + + // et |interdire_scripts sur les autres + default: + $code = "interdire_scripts($code)"; + break; + } + } + return $code; } diff --git a/inc-html-squel.php3 b/inc-html-squel.php3 index f6682e251a..fbf16bc301 100644 --- a/inc-html-squel.php3 +++ b/inc-html-squel.php3 @@ -28,7 +28,7 @@ define('TYPE_RECURSIF', 'boucle'); define('SPEC_BOUCLE','/\s*\(\s*([^\s)]+)(\s*[^)]*)\)/'); define('NOM_DE_BOUCLE', "[0-9]+|[-_][-_.a-zA-Z0-9]*"); # ecriture alambiquee pour rester compatible avec les hexadecimaux des vieux squelettes -define('NOM_DE_CHAMP', "#((" . NOM_DE_BOUCLE . "):)?(([A-F]*[G-Z_][A-Z_0-9]*)|[A-Z_]+)(\*?)"); +define('NOM_DE_CHAMP', "#((" . NOM_DE_BOUCLE . "):)?(([A-F]*[G-Z_][A-Z_0-9]*)|[A-Z_]+)(\*{0,2})"); define('CHAMP_ETENDU', '\[([^]\[]*)\(' . NOM_DE_CHAMP . '([^[)]*\)[^]\[]*)\]'); define('BALISE_INCLURE','<INCLU[DR]E[[:space:]]*\(([^)]*)\)'); -- GitLab