From e61326ed7289a3cefb464fc4f1a3f600b45d4d12 Mon Sep 17 00:00:00 2001 From: Vincent Zanotti Date: Fri, 25 Apr 2008 17:34:51 +0200 Subject: [PATCH] Fixes XSRF vulnerabilities in password page, admin pages, and GoogleApps pages. Signed-off-by: Vincent Zanotti --- classes/csvimporter.php | 3 +++ classes/pltableeditor.php | 9 +++++-- modules/admin.php | 55 +++++++++++++++++++++++++++----------- modules/email.php | 4 ++- modules/googleapps.php | 18 ++++++++++--- modules/platal.php | 4 ++- templates/admin/ipwatcher.tpl | 3 ++- templates/admin/utilisateurs.tpl | 6 +++++ templates/admin/valider.tpl | 3 +++ templates/core/table-editor.tpl | 3 ++- templates/emails/redirect.tpl | 1 + templates/googleapps/index.tpl | 3 +++ templates/include/csv-importer.tpl | 1 + templates/platal/motdepasse.tpl | 1 + 14 files changed, 89 insertions(+), 25 deletions(-) diff --git a/classes/csvimporter.php b/classes/csvimporter.php index 6590df4..e065195 100644 --- a/classes/csvimporter.php +++ b/classes/csvimporter.php @@ -330,6 +330,9 @@ class CSVImporter $fields[] = $key; } if ($current == 'valid' && Env::has('csv_valid')) { + if (!Session::has_xsrf_token()) { + $page->kill("L'opération n'a pas pu être effectuée, merci de réessayer."); + } $this->run($_SESSION['csv_action'], $insert, $update); $page->assign('csv_done', true); $this->cleanSession($sesfields); diff --git a/classes/pltableeditor.php b/classes/pltableeditor.php index 7cfc2e8..cbd944a 100644 --- a/classes/pltableeditor.php +++ b/classes/pltableeditor.php @@ -192,7 +192,8 @@ class PLTableEditor { $page->changeTpl('core/table-editor.tpl'); $list = true; - if ($action == 'delete') { + + if ($action == 'delete' && Session::has_xsrf_token()) { if (!isset($this->delete_action)) { foreach ($this->jtables as $table => $j) XDB::execute("DELETE FROM {$table} WHERE {$j['joinid']} = {?}{$j['joinextra']}", $id); @@ -208,6 +209,8 @@ class PLTableEditor } else { $page->trig("Impossible de supprimer l'entrée."); } + } else if ($action == 'delete') { + $page->trig("Impossible de supprimer l'entrée, merci de réessayer."); } if ($action == 'edit') { $r = XDB::query("SELECT * FROM {$this->table} WHERE {$this->idfield} = {?} AND {$this->whereclause}",$id); @@ -237,7 +240,7 @@ class PLTableEditor } $list = false; } - if ($action == 'update') { + if ($action == 'update' && Session::has_xsrf_token()) { $values = ""; $cancel = false; foreach ($this->vars as $field => $descr) { @@ -286,6 +289,8 @@ class PLTableEditor if (!$this->auto_return) { return $this->apply($page, 'edit', $id); } + } else if ($action == 'update') { + $page->trig("Impossible de mettre à jour, merci de réessayer."); } if ($action == 'sort') { $this->sortfield = $id; diff --git a/modules/admin.php b/modules/admin.php index d878f03..336f848 100644 --- a/modules/admin.php +++ b/modules/admin.php @@ -413,6 +413,9 @@ class AdminModule extends PLModule // Check if there was a submission foreach($_POST as $key => $val) { + if (!Session::has_xsrf_token()) { + $page->kill("L'opération de modification de l'utilisateur a échouée, merci de réessayer."); + } switch ($key) { case "add_fwd": $email = trim(Env::v('email')); @@ -820,22 +823,27 @@ class AdminModule extends PLModule $page->assign('promo',$promo); - if ($validate) { + if ($validate && Session::has_xsrf_token()) { $new_deces = array(); $res = XDB::iterRow("SELECT user_id,matricule,nom,prenom,deces FROM auth_user_md5 WHERE promo = {?}", $promo); while (list($uid,$mat,$nom,$prenom,$deces) = $res->next()) { $val = Env::v($mat); - if($val == $deces || empty($val)) continue; - XDB::execute('UPDATE auth_user_md5 SET deces={?} WHERE matricule = {?}', $val, $mat); - $new_deces[] = array('name' => "$prenom $nom", 'date' => "$val"); - if($deces=='0000-00-00' or empty($deces)) { - require_once('notifs.inc.php'); - register_watch_op($uid, WATCH_DEATH, $val); - require_once('user.func.inc.php'); - user_clear_all_subs($uid, false); // by default, dead ppl do not loose their email - } + if($val == $deces || empty($val)) { + continue; + } + + XDB::execute('UPDATE auth_user_md5 SET deces={?} WHERE matricule = {?}', $val, $mat); + $new_deces[] = array('name' => "$prenom $nom", 'date' => "$val"); + if($deces == '0000-00-00' || empty($deces)) { + require_once('notifs.inc.php'); + register_watch_op($uid, WATCH_DEATH, $val); + require_once('user.func.inc.php'); + user_clear_all_subs($uid, false); // by default, dead ppl do not loose their email + } } $page->assign('new_deces',$new_deces); + } else if (!$validate) { + $page->trig("La mise à jour des dates de decès à échouée, merci de réessayer."); } $res = XDB::iterator('SELECT matricule, nom, prenom, deces FROM auth_user_md5 WHERE promo = {?} ORDER BY nom,prenom', $promo); @@ -919,7 +927,11 @@ class AdminModule extends PLModule if(Env::has('uid') && Env::has('type') && Env::has('stamp')) { $req = Validate::get_typed_request(Env::v('uid'), Env::v('type'), Env::v('stamp')); - if($req) { $req->handle_formu(); } + if($req && Session::has_xsrf_token()) { + $req->handle_formu(); + } else if ($req) { + $page->trig("L'opération a échoué, merci de réessayer."); + } } $r = XDB::iterator('SHOW COLUMNS FROM requests_answers'); @@ -1018,6 +1030,7 @@ class AdminModule extends PLModule $page->setRssLink('Changement Récents', '/Site/AllRecentChanges?action=rss&user=' . S::v('forlife') . '&hash=' . S::v('core_rss_hash')); } + // update wiki perms if ($action == 'update') { $perms_read = Post::v('read'); @@ -1100,8 +1113,12 @@ class AdminModule extends PLModule $page->assign('states', $states); switch (Post::v('action')) { - case 'create': + case 'create': if (trim(Post::v('ipN')) != '') { + if (!Session::has_xsrf_token()) { + $page->trig("L'ajout d'une IP à surveiller a échoué, merci de réessayer."); + break; + } Xdb::execute('INSERT IGNORE INTO ip_watch (ip, mask, state, detection, last, uid, description) VALUES ({?}, {?}, {?}, CURDATE(), NOW(), {?}, {?})', ip_to_uint(trim(Post::v('ipN'))), ip_to_uint(trim(Post::v('maskN'))), @@ -1109,16 +1126,24 @@ class AdminModule extends PLModule }; break; - case 'edit': + case 'edit': + if (!Session::has_xsrf_token()) { + $page->trig("L'édition de l'IP a échoué, merci de réessayer."); + break; + } Xdb::execute('UPDATE ip_watch SET state = {?}, last = NOW(), uid = {?}, description = {?}, mask = {?} WHERE ip = {?}', Post::v('stateN'), S::i('uid'), Post::v('descriptionN'), ip_to_uint(Post::v('maskN')), ip_to_uint(Post::v('ipN'))); break; - default: + default: if ($action == 'delete' && !is_null($ip)) { - Xdb::execute('DELETE FROM ip_watch WHERE ip = {?}', ip_to_uint($ip)); + if (Session::has_xsrf_token()) { + Xdb::execute('DELETE FROM ip_watch WHERE ip = {?}', ip_to_uint($ip)); + } else { + $page->trig("La suppression de l'adresse IP a échouée, merci de réssayer."); + } } } if ($action != 'create' && $action != 'edit') { diff --git a/modules/email.php b/modules/email.php index c6200bb..2642477 100644 --- a/modules/email.php +++ b/modules/email.php @@ -223,7 +223,7 @@ class EmailModule extends PLModule $redirect->modify_one_email_redirect($email, $rewrite); } - if (Env::has('emailop')) { + if (Env::has('emailop') && Session::has_xsrf_token()) { $actifs = Env::v('emails_actifs', Array()); print_r(Env::v('emails_rewrite')); if (Env::v('emailop') == "ajouter" && Env::has('email')) { @@ -234,6 +234,8 @@ class EmailModule extends PLModule $page->assign('retour', $redirect->modify_email($actifs, Env::v('emails_rewrite',Array()))); } + } else if (Env::has('emailop')) { + $page->trig('L\'ajout d\'une nouvelle redirection a échoué, merci de réessayer.'); } $res = XDB::query( diff --git a/modules/googleapps.php b/modules/googleapps.php index fda080f..72e3488 100644 --- a/modules/googleapps.php +++ b/modules/googleapps.php @@ -68,12 +68,18 @@ class GoogleAppsModule extends PLModule } else if ($subaction == 'nosync') { $account->set_password_sync(false); } else if (Post::has('response2') && !$account->sync_password) { - $account->set_password(Post::v('response2')); + if (Session::has_xsrf_token()) { + $account->set_password(Post::v('response2')); + } else { + $page->trig("Le changement de ton mot de passe Google Apps a échoué, merci de réessayer."); + } } } if ($action == 'suspend' && Post::has('suspend') && $account->active()) { - if ($account->pending_update_suspension) { + if (!Session::has_xsrf_token()) { + $page->trig("La demande de suspension de ton compte a échouée, merci de réessayer."); + } else if ($account->pending_update_suspension) { $page->trig("Ton compte est déjà en cours de désactivation."); } else { if ($redirect->modify_one_email('googleapps', false) == SUCCESS) { @@ -101,8 +107,12 @@ class GoogleAppsModule extends PLModule $password = Post::v('response2'); } - $account->create($password_sync, $password, $redirect_mails); - $page->trig("La demande de création de ton compte Google Apps a bien été enregistrée."); + if (Session::has_xsrf_token()) { + $account->create($password_sync, $password, $redirect_mails); + $page->trig("La demande de création de ton compte Google Apps a bien été enregistrée."); + } else { + $page->trig("La demande de création de ton compte Google Apps a échouée, merci de réessayer."); + } } } diff --git a/modules/platal.php b/modules/platal.php index 0fb4c19..a58398b 100644 --- a/modules/platal.php +++ b/modules/platal.php @@ -187,7 +187,7 @@ class PlatalModule extends PLModule { global $globals; - if (Post::has('response2')) { + if (Post::has('response2') && Session::has_xsrf_token()) { require_once 'secure_hash.inc.php'; $_SESSION['password'] = $password = Post::v('response2'); @@ -216,6 +216,8 @@ class PlatalModule extends PLModule $page->changeTpl('platal/motdepasse.success.tpl'); $page->run(); + } else if (Post::has('response2')) { + $page->trig('Le changement de ton mot de passe a échoué, merci de réessayer.'); } $page->changeTpl('platal/motdepasse.tpl'); diff --git a/templates/admin/ipwatcher.tpl b/templates/admin/ipwatcher.tpl index ae30afc..0a526b9 100644 --- a/templates/admin/ipwatcher.tpl +++ b/templates/admin/ipwatcher.tpl @@ -59,7 +59,7 @@ {icon name=page_edit title="Editer"} - {icon name=delete title="Supprimer"} + {icon name=delete title="Supprimer"} {/foreach} @@ -67,6 +67,7 @@ {elseif $action eq "create" || $action eq "edit"} [Retour à la liste des IPs surveillées]

+{xsrf_token_field} diff --git a/templates/admin/utilisateurs.tpl b/templates/admin/utilisateurs.tpl index cca5bc1..6829909 100644 --- a/templates/admin/utilisateurs.tpl +++ b/templates/admin/utilisateurs.tpl @@ -28,6 +28,7 @@ {if $smarty.post.u_kill_conf} + {xsrf_token_field}
Confirmer la suppression de {$smarty.request.user_id}   @@ -37,6 +38,7 @@ {else} + {xsrf_token_field}
Commenter une adresse IP
@@ -117,6 +119,7 @@ function ban_read() {/literal} + {xsrf_token_field}
@@ -272,6 +275,7 @@ Ne pas utiliser [Désinscrire] si le but est d'exclure la personne. Pour ceci changer ses permissions en 'disabled'.

+ {xsrf_token_field}
@@ -319,6 +323,7 @@ Pour ceci changer ses permissions en 'disabled'.

* à ne modifier qu'avec l'accord express de l'utilisateur !!!

+ {xsrf_token_field}
@@ -368,6 +373,7 @@ Pour ceci changer ses permissions en 'disabled'. {test_email forlife=$mr.forlife} + {xsrf_token_field} id()}style="display: none"{/if} id="edit_{$valid->id()}"> comments|@count eq 0}style="display: none"{/if} id="comment_{$valid->id()}"> {/if} @@ -100,6 +100,7 @@ {else} + {xsrf_token_field}
diff --git a/templates/admin/valider.tpl b/templates/admin/valider.tpl index 040473b..67ad572 100644 --- a/templates/admin/valider.tpl +++ b/templates/admin/valider.tpl @@ -73,6 +73,7 @@ function toggleField(name, id, obj) {
+ {xsrf_token_field}
{include file=$valid->editor()} @@ -106,6 +107,7 @@ function toggleField(name, id, obj) {
+ {xsrf_token_field}
@@ -131,6 +133,7 @@ function toggleField(name, id, obj) {
ruleText()}> + {xsrf_token_field}
Réponse préremplie :
{if !$readonly} {icon name=page_edit title='éditer'} - {icon name=delete title='supprimer'} + {icon name=delete title='supprimer'} {/if}
diff --git a/templates/googleapps/index.tpl b/templates/googleapps/index.tpl index 2c01f9e..f475428 100644 --- a/templates/googleapps/index.tpl +++ b/templates/googleapps/index.tpl @@ -122,6 +122,7 @@ {/if} + {xsrf_token_field} @@ -295,6 +296,7 @@ Si tu ne souhaites plus utiliser ton compte, tu peux le désactiver :

+ {xsrf_token_field}
@@ -379,6 +381,7 @@
diff --git a/templates/emails/redirect.tpl b/templates/emails/redirect.tpl index b492048..83cf386 100644 --- a/templates/emails/redirect.tpl +++ b/templates/emails/redirect.tpl @@ -188,6 +188,7 @@ Ajouter une adresse email :    + {xsrf_token_field}
Redirection des emails :
+ {xsrf_token_field}

Pour une sécurité optimale, ton mot de passe circule de manière sécurisée (https). diff --git a/templates/include/csv-importer.tpl b/templates/include/csv-importer.tpl index 506f4ef..0660a2c 100644 --- a/templates/include/csv-importer.tpl +++ b/templates/include/csv-importer.tpl @@ -61,6 +61,7 @@ {/literal} //]]>
+ {xsrf_token_field}
Import d'un CSV : {if $csv_page eq 'source'} diff --git a/templates/platal/motdepasse.tpl b/templates/platal/motdepasse.tpl index 6bd037b..390be6c 100644 --- a/templates/platal/motdepasse.tpl +++ b/templates/platal/motdepasse.tpl @@ -67,6 +67,7 @@

+{xsrf_token_field}

-- 2.1.4