Page MenuHomePhabricator

FanBoxes: classic CSRF in Special:UserBoxes
Closed, ResolvedPublicSecurity

Description

Special:UserBoxes, the special page used to create new social user boxes and edit existing ones (pages in the UserBox: namespace), does not check for the presence of an anti-CSRF token, it will happily create/update the requested page as long as the request was POSTed and the desired form fields are set.

Quick patch:

diff --git a/includes/specials/SpecialFanBoxes.php b/includes/specials/SpecialFanBoxes.php
index aac26be..7835e2d 100644
--- a/includes/specials/SpecialFanBoxes.php
+++ b/includes/specials/SpecialFanBoxes.php
@@ -115,6 +115,7 @@ class FanBoxes extends SpecialPage {
                        $output .= Html::hidden( 'textColorLeftSideColor', $update_fan->getFanBoxLeftTextColor(), [ 'id' => 'textColorLeftSideColor' ] ) . "\n";
                        $output .= Html::hidden( 'bgColorRightSideColor', $update_fan->getFanBoxRightBgColor(), [ 'id' => 'bgColorRightSideColor' ] ) . "\n";
                        $output .= Html::hidden( 'textColorRightSideColor', $update_fan->getFanBoxRightTextColor(), [ 'id' => 'textColorRightSideColor' ] ) . "\n";
+                       $output .= Html::hidden( 'wpEditToken', $user->getEditToken() );
 
                        $fantag_image_tag = '';
                        if ( $update_fan->getFanBoxImage() ) {
@@ -254,6 +255,8 @@ class FanBoxes extends SpecialPage {
                        <input type="hidden" name="bgColorRightSideColor" id="bgColorRightSideColor" value="" />
                        <input type="hidden" name="textColorRightSideColor" id="textColorRightSideColor" value="" />';
 
+                       $output .= Html::hidden( 'wpEditToken', $user->getEditToken() );
+
                        if ( !$destination ) {
                                $output .= '<h2 class="fanbox-form-label">' . $this->msg( 'fanbox-title' )->escaped() . '</h2>
                                        <div class="create-fanbox-title">
@@ -330,6 +333,13 @@ class FanBoxes extends SpecialPage {
 
                // Send values to database and create fantag page when form is submitted
                if ( $request->wasPosted() ) {
+                       // Protect against CSRF
+                       if ( !$user->matchEditToken( $request->getVal( 'wpEditToken' ) ) ) {
+                               $out->addWikiMsg( 'sessionfailure' );
+                               $out->addReturnTo( $this->getPageTitle() );
+                               return;
+                       }
+
                        if ( !$fanboxId ) {
                                // @phan-suppress-next-line PhanTypeMismatchArgumentNullable
                                $fan = FanBox::newFromName( $title );