The open source publishing platform of choice for millions of websites worldwide—from creators and small businesses to enterprises.
The Wordpress framework has a JSONP endpoint to retrieve user data on /wp-json/wp/v2/users/[id]?_jsonp=functionName
. This JSONP returns a 200 OK
only if the user [id]
exists (This is mandatory for a script to load). The only restriction is that the _jsonp
parameter must match /[^\w\.]/
. This is enough to perform a SOME attack.
If needed, users id can be retrieved on /wp-json/wp/v2/users
.
<!-- user input -->
<script src="https://wordpress.org/wp-json/wp/v2/users/8213290?_jsonp=alert"></script>
Root Cause
function wp_is_jsonp_request() {
if ( ! isset( $_GET['_jsonp'] ) ) {
return false;
}
if ( ! function_exists( 'wp_check_jsonp_callback' ) ) {
require_once ABSPATH . WPINC . '/functions.php';
}
$jsonp_callback = $_GET['_jsonp'];
if ( ! wp_check_jsonp_callback( $jsonp_callback ) ) {
return false;
}
/** This filter is documented in wp-includes/rest-api/class-wp-rest-server.php */
$jsonp_enabled = apply_filters( 'rest_jsonp_enabled', true );
return $jsonp_enabled;
}
function wp_check_jsonp_callback( $callback ) {
if ( ! is_string( $callback ) ) {
return false;
}
preg_replace( '/[^\w\.]/', '', $callback, -1, $illegal_char_count );
return 0 === $illegal_char_count;
}
Related links:
Found by @paulosyibelo.