Ticket #4748 (closed defect (bug): fixed)
Unprivileged users can perform some actions on pages they aren't allowed to access
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Priority: | normal | Milestone: | 2.0.12 |
| Component: | Security | Version: | 2.2.2 |
| Severity: | normal | Keywords: | has-patch has-fix security privilege-escalation |
| Cc: |
Description
You control the access to administration pages on menu.php based on the value of $pagenow, however this variable can be manipulated via PATH_INFO.
if ( preg_match('#([^/]+\.php)$#', $PHP_SELF, $self_matches) ) {
$pagenow = $self_matches[1];
} elseif ( strpos($PHP_SELF, '?') !== false ) {
$pagenow = explode('/', $PHP_SELF);
$pagenow = trim($pagenow[(sizeof($pagenow)-1)]);
$pagenow = explode('?', $pagenow);
$pagenow = $pagenow[0];
} else {
$pagenow = 'index.php';
}
Proof of Concept:
- Log in to WP (a subscriber user is okay)
- Access to http://vulnerable/wp/wp-admin/themes.php/index.php
- Switch the current theme (you need to replace /wp-admin/themes.php/themes.php?action=... by /wp-admin/themes.php/index.php?action=...)
As you can see, this bug lets unprivileged users to switch current theme, de/activate plugins, etc.
Attachments
Change History
-
attachment
4748.patch
added
Security Hotfix for #4748 / admin privilege escalation
A more safer approach is to check access rights on the affected files (can_user_can), because the current implementation and the patch you propose could be bypassed (i.e. try this on a Windows box /wp-admin/themes.Php/index.php).
comment:5
markjaquith — 4 years ago
- Status changed from new to closed
- Resolution set to fixed
comment:7
in reply to:
↑ description
snakefoot — 4 years ago
This security fix should be applied to the 2.0 branch.
comment:9
foolswisdom — 4 years ago
- Status changed from closed to reopened
- Resolution fixed deleted
- Milestone changed from 2.3 to 2.0.12
comment:10
markjaquith — 4 years ago
- Status changed from reopened to closed
- Resolution set to fixed
Note: See
TracTickets for help on using
tickets.

I made an analysis of CVS source regarding the reported problem and created a fix:
Analysis:
// Fix empty PHP_SELF $PHP_SELF = $_SERVER['PHP_SELF']; if ( empty($PHP_SELF) ) $_SERVER['PHP_SELF'] = $PHP_SELF = preg_replace("/(\?.*)?$/",'',$_SERVER["REQUEST_URI"]);Possible Fallback Strategies:
Some possile Fallback strategies which came into my mind to hotfix this Issue. Most of them need to be discussed anyway:
Solving…
Because this is a hotfix only, it targets especially the describben problem above only. Any Usage of $PHP_SELF and $_SERVER['PHP_SELF'] is still dangerous and the places within the source should be clearly analyzed AFTER it has been said for once what MUST BE and IS in $PHP_SELF / $_SERVER['PHP_SELF'] (in the meaning of "inside wordpress" not "PHP in general"):
Questions that could be good to be answered in this clarification process:
First Hotfix Implementation:
I made this quite short and did not redirect. This could produce sideeffects and create critical holes sothat no-.php-file is transposed into index.php internally only. Everything unmatching is leading into a wp_die('Request Error. Please contact the Administrator.'). Logical problems will result in an Errorcode which is documented inside the according comments. If you encounter such codes while testing, visit trac and discuss. Do not short-ciruit here. Take care.
WARNING: This does only hotfix the describben Issue and will hide the proof of concept. It can not circumvent the existing design errors in wordpress lacking of missing documentation.
Fix Testing Report:
All tests performed successfully. Proof of Concept does not work any longer. Please hack deeper now.
Additional Information:
$pagenow is used on multiple places within the source and by both admin and non-admin code as far as I can see. It would make sense to open a further ticket to remove unneeded $pagenow declarations because some functions are importing $pagenow from the global scope but do not make use of the var then. This can be removed from source to make a further analysis more easy.
References: