diff --git a/docs/changelog/5.x.x.txt b/docs/changelog/5.x.x.txt index d660c3379..5bf47e90d 100644 --- a/docs/changelog/5.x.x.txt +++ b/docs/changelog/5.x.x.txt @@ -29,6 +29,8 @@ - Fixed bug [ 808704 ] Privilege API missing in Ruling WebGUI 5.4 - Updated the Norwegian translation. (Thanks to Nils-Magne Kvammen.) - Updated the German translation. (Thanks to Andreas Graf.) + - Fixed a security problem where users could access a forum they didn't have + privileges to view if they created a specific URL. 5.5.0 diff --git a/lib/WebGUI/Forum/UI.pm b/lib/WebGUI/Forum/UI.pm index ee9ee002d..df072b6eb 100644 --- a/lib/WebGUI/Forum/UI.pm +++ b/lib/WebGUI/Forum/UI.pm @@ -969,40 +969,47 @@ sub forumPropertiesSave { #------------------------------------------------------------------- -=head2 forumOp ( callback, title, description ) +=head2 forumOp ( caller ) Returns the output of the various www_ subroutines. =over -=item callback +=item caller -The URL to get back to the calling object. +A hash reference containing information passed from the calling object. The following are hash keys that should be passed: -=item title +callback: The URL to get back to the calling object. -The title of the parent object for display in the forum templates. +title: The title of the parent object for display in the forum templates. -=item description +description: The description of the parent object for display in the fourm templates. -The description of the parent object for display in the fourm templates. +forumId: The ID of the forum that is attached to the calling object. =back =cut sub forumOp { - my ($callback, $title, $description) = @_; - my $caller = { - callback=>$callback, - title=>$title, - description=>$description - }; + my ($caller) = @_; if ($session{form}{forumOp} =~ /^[A-Za-z]+$/) { + my $forumId = $session{form}{forumId}; + if ($session{form}{forumPostId}) { + my $post = WebGUI::Forum::Post->new($session{form}{forumPostId}); + $forumId = $post->getThread->get("forumId"); + } elsif ($session{form}{forumThreadId}) { + my $thread = WebGUI::Forum::Thread->new($session{form}{forumThreadId}); + $forumId = $thread->get("forumId"); + } + if ($forumId != $caller->{forumId}) { + WebGUI::ErrorHandler::security("view a forum (".$caller->{forumId}.") that does not belong to the calling object (".$caller->{callback}.")"); + return WebGUI::Privilege::insufficient(); + } my $cmd = "www_".$session{form}{forumOp}; return &$cmd($caller); } else { - WebGUI::ErrorHandler::security("execute an invalid forum operation: ".$session{form}{forumOp}); + return WebGUI::ErrorHandler::security("execute an invalid forum operation: ".$session{form}{forumOp}); } } diff --git a/lib/WebGUI/Wobject/Article.pm b/lib/WebGUI/Wobject/Article.pm index aa38d1653..0caab493e 100644 --- a/lib/WebGUI/Wobject/Article.pm +++ b/lib/WebGUI/Wobject/Article.pm @@ -193,7 +193,16 @@ sub www_view { $templateId = $_[0]->get("templateId"); } if ($session{form}{forumOp}) { - return WebGUI::Forum::UI::forumOp($callback,$_[0]->get("title"),$_[0]->get("description")); + unless ($!= $_[0]->get("wobjectId")) { + WebGUI::ErrorHandler::security("access a forum that was not related to this message board (".$_[0]->get("wobjectId").")"); + return WebGUI::Privilege::insufficient(); + } + return WebGUI::Forum::UI::forumOp({ + callback=>$callback, + title=>$_[0]->get("title"), + description=>$_[0]->get("description"), + forumId=>$_[0]->get("forumId") + }); } else { return $_[0]->processTemplate($templateId,\%var); } diff --git a/lib/WebGUI/Wobject/MessageBoard.pm b/lib/WebGUI/Wobject/MessageBoard.pm index 131993354..4ee994cf0 100644 --- a/lib/WebGUI/Wobject/MessageBoard.pm +++ b/lib/WebGUI/Wobject/MessageBoard.pm @@ -166,13 +166,16 @@ sub www_moveForumUp { sub www_view { my $callback = WebGUI::URL::page("func=view&wid=".$_[0]->get("wobjectId")); if ($session{form}{forumOp}) { - my ($title, $description); - if ($session{form}{forumId} ne "") { - ($title,$description) = WebGUI::SQL->quickArray("select title,description from MessageBoard_forums where forumId=".$session{form}{forumId}); - my $forumParam = "forumId=".$session{form}{forumId}; - $callback = WebGUI::URL::append($callback,$forumParam); - } - return WebGUI::Forum::UI::forumOp($callback,$title,$description); + my ($forumId, $title, $description) = WebGUI::SQL->quickArray("select forumId, title, description from MessageBoard_forums + where wobjectId=".$_[0]->get("wobjectId")." and forumId=".$session{form}{forumId}); + my $forumParam = "forumId=".$forumId; + $callback = WebGUI::URL::append($callback,$forumParam); + return WebGUI::Forum::UI::forumOp({ + callback=>$callback, + title=>$title, + description=>$description, + forumId=>$forumId + }); } my %var; $var{title} = $_[0]->get("title"); diff --git a/lib/WebGUI/Wobject/USS.pm b/lib/WebGUI/Wobject/USS.pm index d01a724c4..f4fca1252 100644 --- a/lib/WebGUI/Wobject/USS.pm +++ b/lib/WebGUI/Wobject/USS.pm @@ -545,7 +545,11 @@ sub www_viewSubmission { return $_[0]->www_view unless ($submission->{USS_submissionId}); my $callback = WebGUI::URL::page("func=viewSubmission&wid=".$_[0]->get("wobjectId")."&sid=".$submission->{USS_submissionId}); if ($session{form}{forumOp}) { - return WebGUI::Forum::UI::forumOp($callback,$submission->{title}); + return WebGUI::Forum::UI::forumOp({ + callback=>$callback, + title=>$submission->{title}, + forumId=>$submission->{forumId} + }); } WebGUI::SQL->write("update USS_submission set views=views+1 where USS_submissionId=$session{form}{sid}"); $var{title} = $submission->{title};