Opened 16 years ago
Closed 16 years ago
#7277 closed defect (bug) (fixed)
page_options doesn't work for plugin pages
Reported by: | Mr Pete | Owned by: | ryan |
---|---|---|---|
Milestone: | 2.7 | Priority: | normal |
Severity: | normal | Version: | |
Component: | General | Keywords: | |
Focuses: | Cc: |
Description
According to Codex, one sets up
page_options with options to be updated.
This does not pass the check in options.php line 48:
if( !isset( $whitelist_options[ $option_page ] ) ) wp_die( __( 'Error! Options page not found.' ) ); if( $option_page == 'options' ) { if( is_site_admin() ) { $options = explode(',', stripslashes( $_POST[ 'page_options' ] )); } else { die( 'Not admin' ); } } else { $options = $whitelist_options[ $option_page ]; }
As coded, page_options only applies to options.php, and $whitelist_options must contain any page name to be used.
Either the code needs to be repaired, or Codex documentation needs to be updated with four bits:
- Remove the section on page_options
- Revise the discussion of the nonce argument to say it should be called mypage-verb-options (eg. mypage==name of my plugin).
- Talk about a requirement to add a filter that augments $whitelist_options
- Talk about an input item needed, called option-page (to match the whitelist_options value and the nonce value without the -options suffix)
i.e.
echo "<input name='option_page' value='myplugin-update' />"; if (function_exists('wp_nonce_field')) wp_nonce_field('myplugin-update-options');
and code for the new whitelist_options filter
Attachments (1)
Change History (14)
#2
@
16 years ago
- Resolution invalid deleted
- Status changed from closed to reopened
Looks like a reasonably significant design difference between MU and 'regular'!
SO... the hard part is the two designs are mutually incompatible in their requirements for the nonce parameter:
MU requires myplugin-update-options (unique per plugin, with a filter)
Regular requires update-options (common across all plugins, with POST variable)
Who resolves incompatibilities?
#3
@
16 years ago
mu trac entry opened. The design incompatibility is highlighted:
http://trac.mu.wordpress.org/ticket/685
#4
@
16 years ago
There is an incompatibility but it exists because of a serious hole in MU security. Alex Concha showed that on an MU site any blog admin could change any blog option just by passing the correct list of options and the generic nonce. The admin could change the list of plugins which would allow them to upload a file and add that file to the plugin list (as happened in the most recent round of attacks on WP blogs).
When I added the whitelist to MU I presumed it would end up in WordPress too but I forgot to add a ticket here to discuss those changes.
It's not really an issue for WordPress as the local admin has access to everything anyway. Is it worth discussing merging the whitelist code into WordPress?
#5
@
16 years ago
If the whitelist code is useful for mu and having in the core means that plugins written for for WP work without changes on mu then lets get the whitelist merged and the info out there for plugin authors.
#6
@
16 years ago
Thanks, donncha (and core team!)
For future reference, here is generic backward-compatible plugin code that should handle all three cases correctly: no nonce, old nonce, whitelist nonce.
function myplug_validOptions() { global $whitelist_options; $whitelist_options['myplug-update'] = array( 'myplug_opt1','myplug_opt2'); } global $whitelist_options; // (Need this if inside a function) if (isset($whitelist_options)) { echo '<input name="option_page" value="myplug-update" type="hidden" />'; add_filter('whitelist_options', 'myplug_validOptions'); wp_nonce_field('myplug-update-options'); } else { echo '<input name="option_page" value="update" type="hidden" />'; echo '<input name="page_options" value="myplug_opt1,myplug_opt2" type="hidden" />'; if (function_exists('wp_nonce_field')) wp_nonce_field('update-options'); }
The code is formatted to highlight the three important bits:
- Set option_page ('update' in old scheme, unique in new).
- Define valid options via filter (new) or form field (old).
- Call wp_nonce_field using option_page value with '-options' appended.
#7
@
16 years ago
About to attach "optionwhitelist.diff" which is a diff of the options code in MU trunk and wp.org trunk at rev 8396. This is quite a huge change although I'm not sure how many plugins use options.php to store their options. I never thought of it, so let's hope most other plugin developers didn't either!
#8
@
16 years ago
Sigh. The code I posted on 07/21/08 needed testing in more environments.
Here's a better sample. NOTE: it's not clear to me what the best test is for the new security system. I'm checking for presence of a function that appears related. In any case, you can't normally test for presence of $whitelist_options in a plugin!
add_filter('whitelist_options', 'myplug_validOptions'); // Add filter globally function myplug_validOptions() { global $whitelist_options; $whitelist_options['myplug-update'] = array( 'myplug_opt1','myplug_opt2'); } if (function_exists('add_option_whitelist')) { echo '<input name="option_page" value="myplug-update" type="hidden" />'; wp_nonce_field('myplug-update-options'); } else { echo '<input name="option_page" value="update" type="hidden" />'; echo '<input name="page_options" value="myplug_opt1,myplug_opt2" type="hidden" />'; if (function_exists('wp_nonce_field')) wp_nonce_field('update-options'); }
The code you show belongs to WordPress MU and AFAIK, there's a
whitelist_options
filter where you can modify it.Please reopen if I'm mistaken.