Make WordPress Core

Opened 11 years ago

Closed 11 years ago

#27805 closed defect (bug) (fixed)

Widget Customizer: Eliminate reliance on create_function()

Reported by: westonruter's profile westonruter Owned by: nacin's profile nacin
Milestone: 3.9 Priority: normal
Severity: normal Version: 3.9
Component: Customize Keywords: has-patch commit
Focuses: Cc:

Description

There are concerns that create_function could be used in a RCE exploit, even though var_export is used to ensure the string supplied to the function body format is a valid PHP string literal.

The code in question is:

/*
 * @todo Replace the next two lines with the following once WordPress supports PHP 5.3.
 *
 * $self = $this; // not needed in PHP 5.4
 *
 * $function = function ( $value ) use ( $self, $setting_id ) {
 *              return $self->manager->widgets->prepreview_added_widget_instance( $value, $setting_id );
 * };
 */
$body     = sprintf( 'global $wp_customize; return $wp_customize->widgets->prepreview_added_widget_instance( $value, %s );', var_export( $setting_id, true ) );
$function = create_function( '$value', $body );

Attachments (2)

27805-01.patch (5.5 KB) - added by westonruter 11 years ago.
https://github.com/x-team/wordpress-develop/commit/75b430546e368745a54dfebe51377c6724dd86ac https://github.com/x-team/wordpress-develop/pull/11
27805-02.patch (6.0 KB) - added by westonruter 11 years ago.
Simplify logic for prepreview_added_widget_instance. (And re-use JS variable instead of running another query.) https://github.com/x-team/wordpress-develop/commit/c43440262a5f16dd0518296b57c1c054689013ae

Download all attachments as: .zip

Change History (10)

#1 @westonruter
11 years ago

  • Keywords has-patch added
  • Owner set to nacin
  • Status changed from new to assigned

@westonruter
11 years ago

Simplify logic for prepreview_added_widget_instance. (And re-use JS variable instead of running another query.) https://github.com/x-team/wordpress-develop/commit/c43440262a5f16dd0518296b57c1c054689013ae

#2 follow-up: @Denis-de-Bernardy
11 years ago

Perhaps use some indirection with a class that has a method like:

function __call($name, $args) {
   if (preg_match("/widget_settings_handler_([a-zA-Z0-9_]+)/", $name, $match) {
      return $this->widget_settings_handler($match[1], $args);
   }
   else {
       trigger_error(…);
   }
}
Last edited 11 years ago by Denis-de-Bernardy (previous) (diff)

#3 in reply to: ↑ 2 @westonruter
11 years ago

Replying to Denis-de-Bernardy:

Perhaps use some indirection with a class that has a method like:

function __call($name, $args) {
   if (preg_match("/widget_settings_handler_([a-zA-Z0-9_]+)/", $name, $match) {
      return $this->widget_settings_handler($match[1], $args);
   }
   else {
       trigger_error(…);
   }
}

Did you see my patch?

#4 @Denis-de-Bernardy
11 years ago

Oh, right, I had missed the new function. Ya, something like that should work.

This ticket was mentioned in IRC in #wordpress-dev by nacin. View the logs.


11 years ago

#6 @ocean90
11 years ago

  • Keywords commit added

27805-02.patch tested with active theme and previewed theme. And single widget. Works.

#7 @nacin
11 years ago

Thanks for this, Weston. Eliminating create_function() may sound academic but these are prone to mistakes later that introduce the nastiest of vulnerabilities. It's just safer to never use it, the same way we'd never use /e for preg_replace() anymore. Cheers.

#8 @nacin
11 years ago

  • Resolution set to fixed
  • Status changed from assigned to closed

In 28143:

Widgets: Remove create_function() from the customizer class.

props westonruter.
fixes #27805.

Note: See TracTickets for help on using tickets.