Firewall Rule To Block WordPress REST API User Enumeration

Hello, I am trying to block certain queries to my web server but unsure how to, this is what I got so far.

(lower(http.request.full_uri) contains “/wp-json/wp/v2/users/”) or (lower(http.request.full_uri) contains “/?rest_route=/wp/v2/users/”) or (lower(http.request.full_uri) contains “/?rest_route=/wp/v2/users”) or (lower(http.request.full_uri) contains “/wp-json/wp/v2/users”)

I would like to block anything before the BLOCK/wp-… in the query right, for example the above format blocks /?rest_route=/wp/v2/usErs or /?rest_route=/wp/v2/usERS etc, however when added for example /section/news?rest_route=/wp/v2/usErs or /dasdasd/gdfgdf?rest_route=/wp/v2/usErs the request is not blocked.

Thanks very much!

Your examples do not really match your expression.

It seems you want to block requests which contain rest_route in the query string. Is that right?
In that case this should work

(http.request.uri.query contains "rest_route=/wp/v2")
3 Likes

Either install this:

Or do something like this:

1 Like

This is why I don’t do Wordpress.

Have in mind, some plugins use REST API, so would need either to block all (401 auth) and allow specific ones as needs.

Or, as @sandro mentioned, I use similar way to block user enumeration, either with ?author using this few conditions inside my existing Firewall rule:
(http.request.uri.path contains "/wp-json/wp/v2/users") or (http.request.uri.query contains "/author") or (http.request.uri.query contains "/?author=")

@intr0 provided links to install a plugin and solve it with a “single click” :wink:

And having this one in functions.php file of my theme:

/* 2016 */
// API WP 4.4
// REST API callback() in header
//add_filter('rest_enabled', '__return_false'); // maybe some issues with displaying images if uncommented
//add_filter('rest_jsonp_enabled', '__return_false'); // maybe some issues with displaying images if uncommented
remove_action( 'wp_head', 'rest_output_link_wp_head', 10 );
remove_action( 'wp_head', 'wp_oembed_add_discovery_links', 10 );
remove_action( 'template_redirect', 'rest_output_link_header', 11, 0 );

function my_deregister_scripts(){
    wp_deregister_script( 'wp-embed' );
}
add_action( 'wp_footer', 'my_deregister_scripts' );

// REST API
//add_filter( 'json_enabled', '__return_false' );
//add_filter( 'json_jsonp_enabled', '__return_false' );
remove_action( 'xmlrpc_rsd_apis', 'rest_output_rsd' );
add_filter('rest_endpoints', function($endpoints) {
  if ( isset( $endpoints['/wp/v2/users'] ) ) {
      unset( $endpoints['/wp/v2/users'] );
  }
  if ( isset( $endpoints['/wp/v2/posts'] ) ) {
      unset( $endpoints['/wp/v2/posts'] );
  }
  if ( isset( $endpoints['/wp/v2/pages'] ) ) {
      unset( $endpoints['/wp/v2/pages'] );
  }
  return $endpoints;
});
1 Like

Wordpress related topics really should go into a Wordpress forum though :wink:

2 Likes

Thanks guys! , I agree @sandro I should have put this in Wordpress … my excuse is that I am very new to this forum and didn’t know there was such section so I just published it in the main area. Apologise for that.

So… at the moment what I am able to do is block these easy enough:
/?rest_route=/wp/v2/users ; and /?rest_route=/wp/v2/users/1 …etc
/wp-json/wp/v2/users ; and /?rest_route=/wp/v2/users/1 …etc

for case insensitive which is quite important :
it also blocks them if they try to bypass it like using /?rest_route=/wp/v2/usErs/

So all the above i’m happy about, what I can’t do is this :
I want to be able to block anything they add before this /ANYTHING/?rest_route=/wp/v2/users/
Example /section/news?rest_route=/wp/v2/users
By using this they can enumerate and see all the users, it doesn’t have to be /section/news , it can be any gibberish like /dassdfd/■■■■?rest_route=/wp/v2/users , So this is why I want somehow to block anything before that / … I tried things like */?rest_route=/wp/v2/users or ^/?rest_route=/wp/v2/users , I’m not familiar with the regex …

Thanks alot guys!

You can’t use regular expressions unless you are on a Business plan.

What exactly do you want to block? Can you post examples?

The expression I posted will take care of the query string URL but you also mentioned a /wp-json path. If you provide a list of URLs you want to block a proper expression could be built.

Based on what you mentioned so far this might work

(http.request.uri.query contains "rest_route=/wp/v2") or (http.request.uri.path contains "/wp-json/wp/v2/users/")

Of course you can add lower() wherever you deem it appropriate.

But yeah, Wordpress specific questions should be addressed in a Wordpress forum, the forum here really is only for Cloudflare specific topics.

2 Likes

@sandro Yeah that did the trick… so now its being blocked. Thanks alot!

I will keep in mind from now on to post on the Wordpress section.

Also thanks @intr0 for input, I am not looking to block the whole rest api just focus on the user enumeration bit.

1 Like

My pleasure, just check it and maybe add some exceptions (e.g. cf.client.bot) if you discover you are blocking too much.

2 Likes

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.