[wp-trac] [WordPress Trac] #62449: Bypassable Sanitization in the restfulAPI, which lead to the
WordPress Trac
noreply at wordpress.org
Fri Nov 15 19:52:36 UTC 2024
#62449: Bypassable Sanitization in the restfulAPI, which lead to the
--------------------------+-------------------------------
Reporter: samjhuseclab | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: REST API | Version: trunk
Severity: normal | Keywords: changes-requested
Focuses: rest-api |
--------------------------+-------------------------------
= WordPress Core Potential Issue: JSONP Sanitization Bypass in `wp_die` =
== Overview ==
This document describes a potential sanitization bug in WordPress Core,
specifically in the `_jsonp_wp_die_handler` function. The issue arises
when a plugin uses the `rest_jsonp_enabled` filter to modify the `_jsonp`
field after it has passed the `wp_check_jsonp_callback` validation. While
this issue is not a direct security vulnerability, it reveals a
sanitization flaw that can result in unexpected behavior.
== Details ==
=== Affected Function: `_jsonp_wp_die_handler` ===
The `_jsonp_wp_die_handler` function uses the `$_GET['_jsonp']` parameter
to generate the JSONP callback name. The callback is directly output in
the response without further validation after initial checks.
'''Key Code:'''
{{{
$jsonp_callback = $_GET['_jsonp'];
echo '/**/' . $jsonp_callback . '(' . $result . ');';
}}}
If the `$_GET['_jsonp']` contains malicious or invalid characters, it may
lead to unintended outputs.
=== Validation Process and the Problem ===
1. '''Validation via `wp_is_jsonp_request`:'''
- The function `wp_is_jsonp_request` validates `$_GET['_jsonp']` using
`wp_check_jsonp_callback`, ensuring the callback name only contains safe
characters (alphanumeric, underscores, and dots).
- '''Code:'''
{{{
preg_replace('/[^\w\.]/', '', $callback, -1, $illegal_char_count);
if ($illegal_char_count > 0) {
return false;
}
}}}
2. '''The Problem:'''
- After validation, the `rest_jsonp_enabled` filter is called:
{{{
$jsonp_enabled = apply_filters('rest_jsonp_enabled', true);
}}}
- At this stage, an attacker or a malicious plugin can modify
`$_GET['_jsonp']`, bypassing the sanitization performed by
`wp_check_jsonp_callback`.
3. '''Potential Outcome:'''
- The callback function name used in the response could contain
unsanitized or unexpected values.
- '''Example Output:'''
{{{
/**/maliciousCallback({...});
}}}
== Reproduction Steps ==
1. '''Create a Plugin to Exploit the Issue:'''
{{{
add_filter('rest_jsonp_enabled', function($enabled) {
$_GET['_jsonp'] = 'maliciousCallback';
return $enabled;
});
}}}
2. '''Trigger the Issue:'''
- Send a request to any endpoint that invokes `_jsonp_wp_die_handler`:
{{{
GET /wp-json?_jsonp=legitCallback
}}}
3. '''Observe the Response:'''
- Despite the original `legitCallback` passing validation, the plugin
modifies it to:
{{{
/**/maliciousCallback({...});
}}}
== Impact ==
=== Risk Assessment ===
- '''Threat Level:''' Low
- '''Requirements for Exploitation:'''
- A specific plugin must actively modify `$_GET['_jsonp']` after
validation.
- '''Actual Output:''' A standard HTTP JSON response, albeit with a
potentially unsanitized callback function.
=== Potential Implications ===
- '''Data Integrity:''' The final output does not match the originally
validated input.
- '''Third-Party Plugin Behavior:''' Malicious plugins could abuse this to
inject unexpected callback names.
== Example Fix Code ==
Below is the updated version of the `wp_is_jsonp_request` function:
{{{
function wp_is_jsonp_request() {
if (!isset($_GET['_jsonp'])) {
return false;
}
$jsonp_callback = $_GET['_jsonp'];
// Initial validation
if (!wp_check_jsonp_callback($jsonp_callback)) {
return false;
}
// Call filter
$jsonp_enabled = apply_filters('rest_jsonp_enabled', true);
// Revalidate after filter execution
if ($jsonp_enabled) {
$jsonp_callback_after_filter = $_GET['_jsonp'];
if (!wp_check_jsonp_callback($jsonp_callback_after_filter)) {
return false;
}
}
return $jsonp_enabled;
}
}}}
== Conclusion ==
This issue highlights a sanitization bug rather than a direct
vulnerability. While the risk is low, fixing this behavior ensures that
WordPress maintains robust input validation and output integrity, even in
edge cases involving plugins and filters.
If JSONP functionality is no longer required, it is recommended to disable
it entirely to mitigate any future risks.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/62449>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list