From 46504fb3e0762660c86aa3b5d31dd836606f7eb3 Mon Sep 17 00:00:00 2001 From: Vincent Zanotti Date: Sun, 18 May 2008 20:51:21 +0200 Subject: [PATCH] Adds XSRF protection to the Email module. Signed-off-by: Vincent Zanotti --- htdocs/javascript/ajax.js | 4 +-- modules/email.php | 53 ++++++++++++++++++++++++++++++---------- plugins/function.test_email.php | 4 ++- templates/emails/alias.tpl | 4 ++- templates/emails/broken.tpl | 3 ++- templates/emails/duplicated.tpl | 3 ++- templates/emails/index.tpl | 2 +- templates/emails/send.tpl | 2 ++ templates/emails/submit_spam.tpl | 1 + 9 files changed, 56 insertions(+), 20 deletions(-) diff --git a/htdocs/javascript/ajax.js b/htdocs/javascript/ajax.js index 854c4ef..9eb6a60 100644 --- a/htdocs/javascript/ajax.js +++ b/htdocs/javascript/ajax.js @@ -140,9 +140,9 @@ function previewWiki(idFrom, idTo, withTitle, idShow) } } -function sendTestEmail(forlife) +function sendTestEmail(token, forlife) { - Ajax.update_html(null, 'emails/test' + (forlife == null ? '' : '/' + forlife), + Ajax.update_html(null, 'emails/test' + (forlife == null ? '' : '/' + forlife) + '?token=' + token, function() { showTempMessage('mail_sent', "Un mail a été envoyé avec succès" + (forlife == null ? " sur ton adresse." : " sur l'adresse de " + forlife), diff --git a/modules/email.php b/modules/email.php index 371ed49..e00cf76 100644 --- a/modules/email.php +++ b/modules/email.php @@ -50,6 +50,10 @@ class EmailModule extends PLModule $uid = S::v('uid'); if ($action == 'best' && $email) { + if (!S::has_xsrf_token()) { + return PL_FORBIDDEN; + } + // bestalias is the first bit : 1 // there will be maximum 8 bits in flags : 255 XDB::execute("UPDATE aliases SET flags=flags & (255 - 1) WHERE id={?}", $uid); @@ -99,7 +103,7 @@ class EmailModule extends PLModule $page->assign('demande', AliasReq::get_request($uid)); - if ($action == 'delete' && $value) { + if ($action == 'delete' && $value && S::has_xsrf_token()) { //Suppression d'un alias XDB::execute( 'DELETE virtual, virtual_redirect @@ -107,6 +111,8 @@ class EmailModule extends PLModule INNER JOIN virtual_redirect USING (vid) WHERE alias = {?} AND (redirect = {?} OR redirect = {?})', $value, $forlife.'@'.$globals->mail->domain, $forlife.'@'.$globals->mail->domain2); + } elseif ($action == 'delete' && $value) { + $page->trig("La suppression de ton alias a échouée, merci de réessayer."); } //Récupération des alias éventuellement existants @@ -121,7 +127,7 @@ class EmailModule extends PLModule list($alias, $visibility) = $res->fetchOneRow(); $page->assign('actuel', $alias); - if ($action == 'ask' && Env::has('alias') and Env::has('raison')) { + if ($action == 'ask' && Env::has('alias') && Env::has('raison') && S::has_xsrf_token()) { //Si l'utilisateur vient de faire une damande $alias = Env::v('alias'); @@ -167,10 +173,13 @@ class EmailModule extends PLModule $page->assign('success',$alias); return; } - } - elseif ($action == 'set' - && ($value == 'public' || $value == 'private')) - { + } elseif ($action == 'ask' && Env::has('alias') && Env::has('raison')) { + $page->trig("Ta demande d'alias n'a pas pu être enregistrée, merci de réessayer."); + } elseif ($action == 'set' && ($value == 'public' || $value == 'private')) { + if (!S::has_xsrf_token()) { + return PL_FORBIDDEN; + } + if ($value == 'public') { XDB::execute("UPDATE auth_user_quick SET emails_alias_pub = 'public' WHERE user_id = {?}", S::v('uid')); @@ -285,7 +294,7 @@ class EmailModule extends PLModule wiki_require_page('Xorg.Mails'); $page->changeTpl('emails/submit_spam.tpl'); - if (Post::has('send_email')) { + if (Post::has('send_email') && S::has_xsrf_token()) { $upload = PlUpload::get($_FILES['mail'], S::v('forlife'), 'spam.submit', true); if (!$upload) { $page->trig('Une erreur a été rencontrée lors du transfert du fichier'); @@ -307,6 +316,8 @@ class EmailModule extends PLModule $mailer->send(); $page->trig('Le message a été transmis à ' . $box); $upload->clear(); + } elseif (Post::has('send_email')) { + $page->trig("La soumission du spam a échouée, merci de réessayer."); } } @@ -320,6 +331,10 @@ class EmailModule extends PLModule // action si on recoit un formulaire if (Post::has('save')) { + if (!S::has_xsrf_token()) { + return PL_FORBIDDEN; + } + unset($_POST['save']); if (trim(preg_replace('/-- .*/', '', Post::v('contenu'))) != "") { $_POST['to_contacts'] = explode(';', @$_POST['to_contacts']); @@ -329,7 +344,7 @@ class EmailModule extends PLModule VALUES ({?}, {?})", S::i('uid'), $data); } exit; - } else if (Env::v('submit') == 'Envoyer') { + } else if (Env::v('submit') == 'Envoyer' && S::has_xsrf_token()) { function getEmails($aliases) { if (!is_array($aliases)) { @@ -396,6 +411,8 @@ class EmailModule extends PLModule } } } + } else if (Env::v('submit') == 'Envoyer') { + $page->trig("L'envoi de l'email a échoué, merci de réessayer."); } else { $res = XDB::query("SELECT data FROM email_send_save @@ -425,6 +442,9 @@ class EmailModule extends PLModule global $globals; require_once 'emails.inc.php'; + if (!S::has_xsrf_token()) { + return PL_FORBIDDEN; + } if (!S::has_perms() || !$forlife) { $forlife = S::v('bestalias'); } @@ -455,7 +475,7 @@ class EmailModule extends PLModule $page->changeTpl('emails/broken.tpl'); - if ($warn == 'warn' && $email) { + if ($warn == 'warn' && $email && S::has_xsrf_token()) { $email = valide_email($email); // vérifications d'usage $sel = XDB::query( @@ -494,7 +514,9 @@ L'équipe d'administration mail->domain . '>'; $mail->send(); $page->trig("Mail envoyé ! :o)"); } - } elseif (Post::has('email')) { + } elseif ($warn == 'warn' && $email) { + $page->trig("Nous n'avons pas pu prévenir ton correspondant, merci de réessayer."); + } elseif (Post::has('email') && S::has_xsrf_token()) { $email = valide_email(Post::v('email')); list(,$fqdn) = explode('@', $email); @@ -532,6 +554,8 @@ L'équipe d'administration mail->domain . '>'; $page->assign_by_ref('x', $x); } } + } elseif (Post::has('email')) { + $page->trig("Nous n'avons pas réussi à satisfaire ta demande, merci de réessayer."); } } @@ -545,8 +569,11 @@ L'équipe d'administration mail->domain . '>'; 'dangerous' => 'Usurpations par cette adresse'); $page->assign('states', $states); + if (Post::has('action') && !S::has_xsrf_token()) { + $page->kill("L'action n'a pas pu être réalisée, merci de réessayer."); + } switch (Post::v('action')) { - case 'create': + case 'create': if (trim(Post::v('emailN')) != '') { Xdb::execute('INSERT IGNORE INTO emails_watch (email, state, detection, last, uid, description) VALUES ({?}, {?}, CURDATE(), NOW(), {?}, {?})', @@ -554,13 +581,13 @@ L'équipe d'administration mail->domain . '>'; }; break; - case 'edit': + case 'edit': Xdb::execute('UPDATE emails_watch SET state = {?}, last = NOW(), uid = {?}, description = {?} WHERE email = {?}', Post::v('stateN'), S::i('uid'), Post::v('descriptionN'), Post::v('emailN')); break; - default: + default: if ($action == 'delete' && !is_null($email)) { Xdb::execute('DELETE FROM emails_watch WHERE email = {?}', $email); } diff --git a/plugins/function.test_email.php b/plugins/function.test_email.php index d9e68ff..80ad621 100644 --- a/plugins/function.test_email.php +++ b/plugins/function.test_email.php @@ -21,10 +21,12 @@ function smarty_function_test_email($params, &$smarty) { $label = isset($params['title']) ? $params['title'] : 'Envoyer un mail de test'; + $token = "'" . S::v('xsrf_token') . (isset($params['forlife']) ? "', " : "'"); $forlife = isset($params['forlife']) ? "'" . $params['forlife'] . "'" : ''; return '
' . '

' - . '
' + . ' ' + . ' ' . '
' . '
' . '
'; diff --git a/templates/emails/alias.tpl b/templates/emails/alias.tpl index 24f5060..929e443 100644 --- a/templates/emails/alias.tpl +++ b/templates/emails/alias.tpl @@ -42,7 +42,7 @@ @@ -82,6 +82,7 @@
+ {xsrf_token_field} @@ -120,6 +121,7 @@ {if $actuel} + {xsrf_token_field}
Demande d'alias
diff --git a/templates/emails/broken.tpl b/templates/emails/broken.tpl index 3d9f4f5..85e915d 100644 --- a/templates/emails/broken.tpl +++ b/templates/emails/broken.tpl @@ -44,7 +44,7 @@ correspondant si tu veux que nous puissions te répondre.

Nous pensons qu'il serait une bonne idée de le prévenir que cette adresse email ne fonctionne plus. Si tu veux que nous lui envoyions un mail automatique de ta part pour le prévenir, - clique sur ce lien. + clique sur ce lien.

{elseif $x}

Patte Cassée

@@ -68,6 +68,7 @@ correspondant si tu veux que nous puissions te répondre.
+ {xsrf_token_field}
Suppression d'alias
diff --git a/templates/emails/duplicated.tpl b/templates/emails/duplicated.tpl index eb9571d..3da2e30 100644 --- a/templates/emails/duplicated.tpl +++ b/templates/emails/duplicated.tpl @@ -57,7 +57,7 @@ {/foreach} @@ -65,6 +65,7 @@ {elseif $action eq "create" || $action eq "edit"} [Retour à la liste des doublons]

+{xsrf_token_field}
Adresse email défectueuse {icon name=page_edit title="Editer"} - {icon name=delete title="Supprimer"} + {icon name=delete title="Supprimer"}
diff --git a/templates/emails/index.tpl b/templates/emails/index.tpl index 849ab0b..d4d2159 100644 --- a/templates/emails/index.tpl +++ b/templates/emails/index.tpl @@ -39,7 +39,7 @@ Tes adresses polytechniciennes sont :

{iterate from=$aliases item=a} - + {if $a.a_vie}(**){/if}{if $a.cent_ans}(*){/if} {$a.alias}@{#globals.mail.domain#} et @{#globals.mail.domain2#} {if $a.expire}(expire le {$a.expire|date_format}){/if}
diff --git a/templates/emails/send.tpl b/templates/emails/send.tpl index 9219ee2..1a3095f 100644 --- a/templates/emails/send.tpl +++ b/templates/emails/send.tpl @@ -68,6 +68,7 @@ } $.post(platal_baseurl + "emails/send", { save: true, + token: '{xsrf_token}', from: form.from.value, to_contacts: toc, cc_contacts: ccc, @@ -155,6 +156,7 @@ + {xsrf_token_field}
Commenter le doublon
diff --git a/templates/emails/submit_spam.tpl b/templates/emails/submit_spam.tpl index cb932f6..c14730f 100644 --- a/templates/emails/submit_spam.tpl +++ b/templates/emails/submit_spam.tpl @@ -23,6 +23,7 @@

Soumettre un spam

+ {xsrf_token_field}
Destinataires
-- 2.1.4