Ticket #4690 (closed defect (bug): fixed)

Opened 5 years ago

Last modified 5 years ago

Wordpress options.php SQL Injection Vulnerability

Reported by: BenjaminFlesch Owned by: Nazgul
Priority: high Milestone: 2.0.11
Component: Security Version: 2.2.1
Severity: major Keywords: has-patch commit
Cc:

Description

Read here  http://mybeni.rootzilla.de/mybeNi/2007/wordpress_zeroday_vulnerability_roundhouse_kick_and_why_i_nearly_wrote_the_first_blog_worm/ beginning from the second point, in short:

in options.php the parameter page_options isnt filtered, patch:

case 'update':

$any_changed = 0;

check_admin_referer('update-options');

  • if ( preg_match("/['\"<>]/", $_POSTpage_options?) )
  • wp_die(('Cheatin&#8217; uh?'));

add the lines marked with a star in options.php.

Additionally, because of this Persistant XSS and information disclosure by opening options.php directly in the browser may occur. Better stop the database dump.

Attachments

4690.diff Download (563 bytes) - added by Nazgul 5 years ago.
4690.002.diff Download (1.6 KB) - added by markjaquith 5 years ago.
Patches to update_option/add_option

Change History

  • Keywords needs-patch added
  • Priority changed from highest omg bbq to high
  • Severity changed from critical to major
  • Milestone set to 2.3 (trunk)

First, there is a nonce protecting that page, so it can't be exploited remotely. Second, you need the "manage_options" capability which by default is only given to Administrators.

Administrators can do all sorts of "bad things" to their own blog by design. It should be fixed asap, but isn't critical in my opinion.

Nazgul5 years ago

  • Keywords has-patch needs-testing added; needs-patch removed
  • Owner changed from anonymous to Nazgul
  • Status changed from new to assigned

Patch adds the missing $wpdb->escapes, which should fix this issue.

It could use some extensive testing for regression bugs though.

Okay I know, but XSS flaws are existing everywhere and this can be used for persistant XSS. Append ' OR '"><script>alert(1)</script>'='"><script>alert(1)</script> to the page_options value in one of the options files (e.g. options-privacy.php) via WebDeveloper Toolbar and submit. Then, visit /options.php which dumps the whole database without output validation -> Persistant XSS flaws. Plus the step from XSS (Client/Webpage manipulation) to SQLInjection (Database Manipulation) is taken. This makes attacks like adding users much easier because the take less time the authenticated Admin needs to stay on the attacker's page. --beni

Nazgul, we can't use that fix now (although it is planned for 2.4) because it will break a lot of things. For now, we have to do our escaping outside of those functions.

Patches to update_option/add_option

Try that patch on for size. The issue here is that while add_option() and update_option() expect the option name to be unescaped, get_option() expects it to be pre-escaped. So we need to create a safe version of the option name to use when add/update_option call get_option().

This is seriously messed up, and will be fixed properly in 2.4 (by making ALL FUNCTIONS expect unescaped data).

New patch looks good to me.

  • Keywords commit added; needs-testing removed
  • Milestone changed from 2.3 (trunk) to 2.0.11

Targeting all three branches here.

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

(In [5829]) add_option()/update_option() should pass the option name to get_option() pre-escaped. fixes #4690 for trunk

(In [5830]) add_option()/update_option() should pass the option name to get_option() pre-escaped. fixes #4690 for 2.2.x

(In [5831]) add_option()/update_option() should pass the option name to get_option() pre-escaped. fixes #4690 for 2.0.x

Note: See TracTickets for help on using tickets.