WordPress publishes a list of users at https://<domain>/wp-sitemap-users-1.xml. For small blogs this exposes the admin account username, which can simplify brute force attacks. For large blogs incorporating SCIM technology, it exposes your entire directory to the Internet.
The advantage of doing this at Nginx-level (rather than within WordPress’ PHP code) is that it’ll survive WordPress upgrades.
Blocking via Nginx .conf
Add the below to your site’s .conf
file.
location ~ wp-sitemap-users-1.xml$ {
deny all;
index index.html index.htm index.php;
}
Blocking via Puppet
Prerequisite is you’re using the Vox Pupuli module.
nginx::resource::location { "${name}_wp-sitemap-users-1_xml":
ensure => present,
server => $name,
location => '~ wp-sitemap-users-1.xml$',
location_deny => ['all']
}
The $name
variable should correspond to a nginx::resource::server
definition. For example, here’s the full config this blog uses in Puppet. web.pp defines an nginx_php_server and site.pp simply invokes it if it should be applied to a node.
web.pp
$full_web_path = '/var/www'
$fastcgi_pass = 'unix:/var/opt/remi/php82/run/php-fpm/www.sock'
# Configure an Nginx server with PHP
define web::nginx_php_server (
$php = true,
$wordpress = false,
$www_root = "${::full_web_path}/${name}/public_html",
$location_cfg_append = undef,
) {
nginx::resource::server { $name:
ensure => present,
use_default_location => false, # https://github.com/voxpupuli/puppet-nginx/issues/639
listen_port => 80,
www_root => $www_root,
owner => 'nginx',
group => 'nginx',
mode => '0755',
access_log => "/var/log/nginx/${name}_access.log",
error_log => "/var/log/nginx/${name}_error.log",
location_cfg_append => {
try_files => '$uri $uri/ =404'
},
index_files => [ 'index.php' ],
}
if $php {
nginx::resource::location { "${name}_root":
ensure => present,
server => $name,
location => '/',
try_files => ['$uri', '$uri/', '/index.php?q=$uri&$args'],
}
nginx::resource::location { $name:
ensure => present,
server => $name,
location => '~ \.php$',
index_files => ['index.php', 'index.html', 'index.htm'],
proxy => undef,
fastcgi => $::fastcgi_pass,
fastcgi_script => undef,
location_cfg_append => {
fastcgi_split_path_info => '^(.+\.php)(/.+)$',
fastcgi_index => 'index.php',
fastcgi_connect_timeout => '3m',
fastcgi_read_timeout => '3m',
fastcgi_send_timeout => '3m'
}
}
}
if $wordpress {
# block access to users sitemap, e.g. https://blog.abctaylor.com/wp-sitemap-users-1.xml
nginx::resource::location { "${name}_wp-sitemap-users-1_xml":
ensure => present,
server => $name,
location => '~ wp-sitemap-users-1.xml$',
location_deny => ['all']
}
}
}
site.pp
... omitted for brevity
web::nginx_php_server { "blog.abctaylor.com":
wordpress => true,
}
... omitted for brevity
Test
https://blog.abctaylor.com/wp-sitemap-users-1.xml returns error 403.
Let’s see if Google was able to index my user list. Looking at the sitemap I submitted (https://blog.abctaylor.com/wp-sitemap.xml) in Search Console, it pulls all the sitemaps listed at the top level, but not the user list.