Provide a framework for CSRF protection, with tests.

Add CSRF protection to Asset editSave, AssetManager, VersionTags and Group operations.
This commit is contained in:
Colin Kuskie 2009-07-06 16:58:57 +00:00
parent 4664ab7035
commit 5e4db3adb4
19 changed files with 362 additions and 62 deletions

View file

@ -290,7 +290,7 @@ A WebGUI::Session object
sub www_addGroupsToGroupSave {
my $session = shift;
return $session->privilege->adminOnly() unless (canEditGroup($session,$session->form->process("gid")));
return $session->privilege->adminOnly() unless (canEditGroup($session,$session->form->process("gid")) && $session->form->validToken);
my $group = WebGUI::Group->new($session,$session->form->process("gid"));
my @groups = $session->form->group('groups');
$group->addGroups(\@groups);
@ -314,7 +314,7 @@ A WebGUI::Session object
sub www_addUsersToGroupSave {
my $session = shift;
return $session->privilege->adminOnly() unless (canEditGroup($session,$session->form->process("gid")));
return $session->privilege->adminOnly() unless (canEditGroup($session,$session->form->process("gid")) && $session->form->validToken);
my @users = $session->form->selectList('users');
my $group = WebGUI::Group->new($session,$session->form->process("gid"));
$group->addUsers(\@users);
@ -419,10 +419,9 @@ sub www_deleteGroupGrouping {
=head2 www_deleteGrouping ( )
Deletes a set of users from a set of groups.
The user and group lists are expected to
be found in form fields names uid and gid, respectively. Visitors are not allowed to
perform this operation.
Deletes a set of users from a set of groups. The user and group lists are expected
to be found in form fields names uid and gid, respectively. Visitors are not
allowed to perform this operation.
=head3 $session
@ -432,7 +431,7 @@ A WebGUI::Session object
sub www_deleteGrouping {
my $session = shift;
return $session->privilege->adminOnly() unless (canEditGroup($session,$session->form->process("gid")));
return $session->privilege->adminOnly() unless (canEditGroup($session,$session->form->process("gid")) && $session->form->validToken);
if (($session->user->userId eq $session->form->process("uid") || $session->form->process("uid") eq '3') && $session->form->process("gid") eq '3') {
return $session->privilege->vitalComponent();
}
@ -476,6 +475,7 @@ sub www_editGroup {
-name => "op",
-value => "editGroupSave",
);
$f->csrfToken();
$f->hidden(
-name => "gid",
-value => $session->form->process("gid")
@ -657,7 +657,7 @@ sub www_editGroupSave {
my $session = shift;
my $gid = $session->form->process("gid");
return $session->privilege->adminOnly
unless canEditGroup($session, $gid);
unless canEditGroup($session, $gid) && $session->form->validToken;
my $g = WebGUI::Group->new($session, $gid);
# We don't want them to use an existing name. If needed, we'll add a number to the name to keep it unique.
my $groupName = $session->form->process("groupName");
@ -718,6 +718,7 @@ sub www_editGrouping {
my $i18n = WebGUI::International->new($session);
my $f = WebGUI::HTMLForm->new($session);
$f->submit;
$f->csrfToken();
$f->hidden(
-name => "op",
-value => "editGroupingSave"
@ -774,7 +775,7 @@ A WebGUI::Session object
sub www_editGroupingSave {
my $session = shift;
return $session->privilege->adminOnly() unless (canEditGroup($session,$session->form->process("gid")));
return $session->privilege->adminOnly() unless (canEditGroup($session,$session->form->process("gid")) && $session->form->validToken);
my $group = WebGUI::Group->new($session,$session->form->process("gid"));
$group->userGroupExpireDate($session->form->process("uid"),$session->datetime->setToEpoch($session->form->process("expireDate")));
$group->userIsAdmin($session->form->process("uid"),$session->form->process("groupAdmin"));
@ -805,6 +806,7 @@ sub www_emailGroup {
-name => "op",
-value => "emailGroupSend"
);
$f->csrfToken();
$f->hidden(
-name => "gid",
-value => $session->form->process("gid")
@ -853,7 +855,7 @@ A WebGUI::Session object
sub www_emailGroupSend {
my $session = shift;
return $session->privilege->adminOnly() unless (canEditGroup($session,$session->form->process("gid")));
return $session->privilege->adminOnly() unless (canEditGroup($session,$session->form->process("gid")) && $session->form->validToken);
my $mail = WebGUI::Mail::Send->create($session, {toGroup=>$session->form->process("gid"),subject=>$session->form->process("subject"),from=>$session->form->process("from")});
$mail->addHtml($session->form->process("message","HTMLArea"));
$mail->addFooter;
@ -958,6 +960,7 @@ sub www_manageGroupsInGroup {
return $session->privilege->adminOnly() unless (canEditGroup($session,$session->form->process("gid")));
my $f = WebGUI::HTMLForm->new($session);
$f->csrfToken();
$f->submit;
$f->hidden(
-name => "op",
@ -1014,6 +1017,7 @@ sub www_manageUsersInGroup {
return $session->privilege->adminOnly() unless (canEditGroup($session,$session->form->process("gid")));
my $i18n = WebGUI::International->new($session);
my $output = WebGUI::Form::formHeader($session,)
.WebGUI::Form::csrfToken($session,{})
.WebGUI::Form::hidden($session,{
name=>"gid",
value=>$session->form->process("gid")
@ -1036,7 +1040,6 @@ sub www_manageUsersInGroup {
name=>"uid",
value=>$row->{userId}
})
.$session->icon->delete('op=deleteGrouping;uid='.$row->{userId}.';gid='.$session->form->process("gid"))
.$session->icon->edit('op=editGrouping;uid='.$row->{userId}.';gid='.$session->form->process("gid"))
.'</td>';
$output .= '<td class="tableData"><a href="'.$session->url->page('op=editUser;uid='.$row->{userId}).'">'.$row->{username}.'</a></td>';
@ -1050,6 +1053,7 @@ sub www_manageUsersInGroup {
return _submenu($session,$output) unless ($session->form->process("doit") || $userCount < 250 || $session->form->process("pn") > 1);
my $f = WebGUI::HTMLForm->new($session);
$f->submit;
$f->csrfToken();
$f->hidden(
-name => "gid",
-value => $session->form->process("gid")

View file

@ -607,6 +607,7 @@ sub www_editSettings {
name => "op",
value => "saveSettings"
});
$tabform->csrfToken();
my $definitions = definition($session, $i18n);
foreach my $definition (@{$definitions}) {
@ -671,7 +672,7 @@ is in group Admin (3). Returns the user to the Edit Settings screen, www_editSe
sub www_saveSettings {
my $session = shift;
return $session->privilege->adminOnly() unless ($session->user->isAdmin);
return $session->privilege->adminOnly() unless ($session->user->isAdmin && $session->form->validToken);
my $i18n = WebGUI::International->new($session, "WebGUI");
my $setting = $session->setting;
my $form = $session->form;

View file

@ -154,7 +154,7 @@ sub www_approveVersionTag {
my $tag = WebGUI::VersionTag->new( $session, $session->form->param("tagId") );
return $session->privilege->insufficient
unless canApproveVersionTag( $session, $tag );
unless canApproveVersionTag( $session, $tag ) && $session->form->validToken;
my $instance = $tag->getWorkflowInstance;
my $activity = $instance->getNextActivity;
@ -217,6 +217,7 @@ sub www_editVersionTag {
-value=>"editVersionTagSave"
);
my $value = $tag->getId if defined $tag;
$f->csrfToken();
$f->hidden(
-name=>"tagId",
-value=>$value,
@ -271,7 +272,7 @@ A reference to the current session.
sub www_editVersionTagSave {
my $session = shift;
return $session->session->privilege->insufficient() unless canView($session);
return $session->session->privilege->insufficient() unless canView($session) && $session->form->validToken;
if ($session->form->param("tagId") eq "new") {
my $tag = WebGUI::VersionTag->create($session, {
name=>$session->form->process("name","text", "Untitled"),
@ -323,6 +324,7 @@ sub www_commitVersionTag {
# Commit comments form
my $f = WebGUI::HTMLForm->new($session);
$f->submit;
$f->csrfToken();
$f->readOnly(
label => $i18n->get("version tag name"),
hoverHelp => $i18n->get("version tag name description commit"),
@ -419,7 +421,7 @@ sub www_commitVersionTagConfirm {
my $tagId = $session->form->param("tagId");
if ($tagId) {
my $tag = WebGUI::VersionTag->new($session, $tagId);
if (defined $tag && $session->user->isInGroup($tag->get("groupToUse"))) {
if (defined $tag && $session->user->isInGroup($tag->get("groupToUse")) && $session->form->validToken) {
my $i18n = WebGUI::International->new($session, "VersionTag");
my $startTime = WebGUI::DateTime->new($session,$session->form->process("startTime","dateTime"))->toDatabase;
@ -653,8 +655,9 @@ sub www_manageRevisionsInTag {
$ac->addSubmenuItem($session->url->page('op=manageVersions'), $i18n->get("manage versions"));
# Process any actions
my $action = lc $session->form->get('action');
if ( $action eq "purge" ) {
my $action = lc $session->form->get('action');
my $validToken = $session->form->validToken;
if ( $action eq "purge" && $validToken) {
# Purge these revisions
my @assetInfo = $session->form->get('assetInfo');
for my $assetInfo ( @assetInfo ) {
@ -669,7 +672,7 @@ sub www_manageRevisionsInTag {
return www_manageVersions( $session );
}
}
elsif ( $action eq "move to:" ) {
elsif ( $action eq "move to:" && $validToken) {
# Get the new version tag
my $moveToTagId = $session->form->get('moveToTagId');
my $moveToTag;
@ -697,7 +700,7 @@ sub www_manageRevisionsInTag {
return www_manageVersions( $session );
}
}
elsif ( $action eq "update version tag" ) {
elsif ( $action eq "update version tag" && $validToken) {
my $startTime = WebGUI::DateTime->new($session,$session->form->process("startTime","dateTime"))->toDatabase;
my $endTime = WebGUI::DateTime->new($session,$session->form->process("endTime","dateTime"))->toDatabase;
@ -716,6 +719,7 @@ sub www_manageRevisionsInTag {
if (defined $instance) {
my $form = WebGUI::HTMLForm->new($session);
$form->submit;
$form->csrfToken;
$form->hidden(
name=>"tagId",
value=>$tagId
@ -769,6 +773,7 @@ sub www_manageRevisionsInTag {
.= WebGUI::Form::formHeader( $session, {} )
. WebGUI::Form::hidden( $session, { name => 'op', value=> 'manageRevisionsInTag' } )
. WebGUI::Form::hidden( $session, { name => 'tagId', value => $tag->getId } )
. WebGUI::Form::csrfToken( $session )
. '<table width="100%" class="content">'
. '<tr>'
. '<td colspan="5">'