From 453b5b46a370e3f01f2c948ac3eddf0bcd82c741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20H=C3=B6=C3=9Fl?= <tobias@hoessl.eu> Date: Sun, 18 Mar 2012 15:44:33 +0000 Subject: [PATCH] CSRF-Protection in the group-related form (creating, renaming and dropping a group, adding/removing members from it) --- include/security.php | 6 ++++++ js/main.js | 4 ++-- mod/group.php | 26 +++++++++++++++++++------- view/group_drop.tpl | 2 +- view/group_edit.tpl | 1 + 5 files changed, 29 insertions(+), 10 deletions(-) diff --git a/include/security.php b/include/security.php index 6ea515bff..45473445a 100755 --- a/include/security.php +++ b/include/security.php @@ -334,3 +334,9 @@ function check_form_security_token_redirectOnErr($err_redirect, $typename = "", goaway($a->get_baseurl() . $err_redirect ); } } +function check_form_security_token_ForbiddenOnErr($typename = "", $formname = 'form_security_token') { + if (!check_form_security_token($typename, $formname)) { + header('HTTP/1.1 403 Forbidden'); + killme(); + } +} \ No newline at end of file diff --git a/js/main.js b/js/main.js index c20455ad1..babd2a1c3 100755 --- a/js/main.js +++ b/js/main.js @@ -486,9 +486,9 @@ return a.join(''); } - function groupChangeMember(gid,cid) { + function groupChangeMember(gid, cid, sec_token) { $('body .fakelink').css('cursor', 'wait'); - $.get('group/' + gid + '/' + cid, function(data) { + $.get('group/' + gid + '/' + cid + "?t=" + sec_token, function(data) { $('#group-update-wrapper').html(data); $('body .fakelink').css('cursor', 'auto'); }); diff --git a/mod/group.php b/mod/group.php index 13401ef0d..a282dbccf 100755 --- a/mod/group.php +++ b/mod/group.php @@ -21,6 +21,8 @@ function group_post(&$a) { } if(($a->argc == 2) && ($a->argv[1] === 'new')) { + check_form_security_token_redirectOnErr('/group/new', 'group_edit'); + $name = notags(trim($_POST['groupname'])); $r = group_add(local_user(),$name); if($r) { @@ -35,6 +37,8 @@ function group_post(&$a) { return; // NOTREACHED } if(($a->argc == 2) && (intval($a->argv[1]))) { + check_form_security_token_redirectOnErr('/group', 'group_edit'); + $r = q("SELECT * FROM `group` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($a->argv[1]), intval(local_user()) @@ -62,7 +66,8 @@ function group_post(&$a) { } function group_content(&$a) { - + $change = false; + if(! local_user()) { notice( t('Permission denied') . EOL); return; @@ -83,14 +88,17 @@ function group_content(&$a) { return replace_macros($tpl, $context + array( '$title' => t('Create a group of contacts/friends.'), - '$gname' => array('groupname',t('Group Name: '),$group['name'], ''), + '$gname' => array('groupname',t('Group Name: '), '', ''), '$gid' => 'new', + '$form_security_token' => get_form_security_token("group_edit"), )); } if(($a->argc == 3) && ($a->argv[1] === 'drop')) { + check_form_security_token_redirectOnErr('/group', 'group_drop', 't'); + if(intval($a->argv[2])) { $r = q("SELECT `name` FROM `group` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval($a->argv[2]), @@ -108,6 +116,8 @@ function group_content(&$a) { } if(($a->argc > 2) && intval($a->argv[1]) && intval($a->argv[2])) { + check_form_security_token_ForbiddenOnErr('group_member_change', 't'); + $r = q("SELECT `id` FROM `contact` WHERE `id` = %d AND `uid` = %d and `self` = 0 and `blocked` = 0 AND `pending` = 0 LIMIT 1", intval($a->argv[2]), intval(local_user()) @@ -155,7 +165,8 @@ function group_content(&$a) { $drop_tpl = get_markup_template('group_drop.tpl'); $drop_txt = replace_macros($drop_tpl, array( '$id' => $group['id'], - '$delete' => t('Delete') + '$delete' => t('Delete'), + '$form_security_token' => get_form_security_token("group_drop"), )); $celeb = ((($a->user['page-flags'] == PAGE_SOAPBOX) || ($a->user['page-flags'] == PAGE_COMMUNITY)) ? true : false); @@ -166,6 +177,7 @@ function group_content(&$a) { '$gname' => array('groupname',t('Group Name: '),$group['name'], ''), '$gid' => $group['id'], '$drop' => $drop_txt, + '$form_security_token' => get_form_security_token('group_edit'), ); } @@ -177,14 +189,14 @@ function group_content(&$a) { 'label_members' => t('Members'), 'members' => array(), 'label_contacts' => t('All Contacts'), - 'contacts' => arraY(), + 'contacts' => array(), ); - + $sec_token = addslashes(get_form_security_token('group_member_change')); $textmode = (($switchtotext && (count($members) > $switchtotext)) ? true : false); foreach($members as $member) { if($member['url']) { - $member['click'] = 'groupChangeMember(' . $group['id'] . ',' . $member['id'] . '); return true;'; + $member['click'] = 'groupChangeMember(' . $group['id'] . ',' . $member['id'] . ',\'' . $sec_token . '\'); return true;'; $groupeditor['members'][] = micropro($member,true,'mpgroup', $textmode); } else @@ -199,7 +211,7 @@ function group_content(&$a) { $textmode = (($switchtotext && (count($r) > $switchtotext)) ? true : false); foreach($r as $member) { if(! in_array($member['id'],$preselected)) { - $member['click'] = 'groupChangeMember(' . $group['id'] . ',' . $member['id'] . '); return true;'; + $member['click'] = 'groupChangeMember(' . $group['id'] . ',' . $member['id'] . ',\'' . $sec_token . '\'); return true;'; $groupeditor['contacts'][] = micropro($member,true,'mpall', $textmode); } } diff --git a/view/group_drop.tpl b/view/group_drop.tpl index cbae1610f..2cbebbb8e 100755 --- a/view/group_drop.tpl +++ b/view/group_drop.tpl @@ -1,5 +1,5 @@ <div class="group-delete-wrapper button" id="group-delete-wrapper-$id" > - <a href="group/drop/$id" + <a href="group/drop/$id?t=$form_security_token" onclick="return confirmDelete();" id="group-delete-icon-$id" class="icon drophide group-delete-icon" diff --git a/view/group_edit.tpl b/view/group_edit.tpl index 3689db753..2fa2b1a55 100755 --- a/view/group_edit.tpl +++ b/view/group_edit.tpl @@ -3,6 +3,7 @@ <div id="group-edit-wrapper" > <form action="group/$gid" id="group-edit-form" method="post" > + <input type='hidden' name='form_security_token' value='$form_security_token'> {{ inc field_input.tpl with $field=$gname }}{{ endinc }} {{ if $drop }}$drop{{ endif }}