如果你正在测试WordPress网站的安全性,你很可能要看一下REST端点。默认情况下,用户可以通过路由"/wp-json/wp/v2/users "列出。在最新的WordPress版本中,开启后你会得到用户名和哈希的电子邮件。有经验的WordPress管理员和用户都知道这种潜在的泄露。因此,我们可以在网上看到各种关于如何隐藏这些信息的教程。推荐的方法是完全禁用REST API,安装一个禁用特定路径的安全插件,或者阻止特定的请求路径。
1. HTTP 参数“rest_route”
我们展示的第一个绕过是滥用替代路径到达同一端点。虽然 Worpdress 默认配置为支持 URL 重写,以使用搜索引擎的 URL
https://website.com/2020/12/breaking-news
代替
https://website.com/?p=2678
在后台,发送到 /wp-json/ 的每个请求都进入索引页面,参数“rest_route”设置为/wp/v2/users.
https://****.com/blog/wp-json/wp/v2/users 已屏蔽
https://****.com/blog/?rest_route=/wp/v2/users 绕过
2. WordPress.com API
第二种方法已经在之前关于 Jetpack 电子邮件公开披露的博客文章中进行了描述。虽然您可能有一个安全插件,例如 iThemes security,但这并不意味着另一个插件不会破坏其他地方的信息。对于 Jetpack 插件,包括用户列表在内的数据会导出到 wordpress.com 并通过公共 REST API 提供。
https://blog.*******.com/wp-json/wp/v2/users 已屏蔽 https://public-api.wordpress.com/rest/v1.1/sites/blog.*******.com/posts 绕过
3. 拼接
有多个路由是指向用户资源的。下面的PHP代码将禁用列出所有用户的路由("wp/v2/users")
add_filter( 'rest_endpoints', function( $endpoints ){
if ( isset( $endpoints['/wp/v2/users'] ) ) {
unset( $endpoints['/wp/v2/users'] );
} return $endpoints;
});
然而,有第二个端点可以被遗忘。"/wp/v2/users/(?P[\d]+)",这是一个按id获取用户详细信息的资源。
在下面的表格中,我们可以看到,有一台主机拒绝提供完整的用户名单。然而,我们意识到,针对一个特定的用户并没有被阻止。
https://www.*****.org/wp-json/wp/v2/users 已屏蔽 https://www.*****.org/wp-json/wp/v2/users/1 绕过
4. 大小写敏感性
在REST请求中,路由是用来定义所选资源的。请记住,WordPress是模块化的。资源(或服务)将取决于所安装的插件和WordPress的配置。参数rest_route与所有处理程序提供的路由列表相匹配。匹配是使用不区分大小写的正则表达式进行的。
foreach ( $routes as $route => $handlers ) {
$match = preg_match( '@^' . $route . '$@i', $path, $matches );
if ( ! $match ) {
continue;
}
$args = array();
来源:class-wp-rest-server.php
由于这个原因,一个有效的WAF规则也需要不区分大小写。
RewriteCond %{QUERY_STRING} \bwp/v2/users\b [NC] RewriteRule ^ - [F
很容易添加WAF规则而忘记启用不敏感度。
RewriteCond %{QUERY_STRING} \bwp/v2/users\
在下面的例子中,我们看到一个网站似乎有一个像之前的Apache规则那样的过滤器,对大小写敏感。我们可以看到,通常的REST路线被阻止了,但用一个大写字母或更多的字符更新路径会骗过重写规则。
https://blog.*****.com/section/news?rest_route=/wp/v2/users 已屏蔽 https://blog.*****.com/section/news?rest_route=/wp/v2/usErs 绕
5. 搜索
在少数情况下,我们遇到了没有明确阻止的API,但/wp/v2/users端点没有返回avatar_urls属性。这是由第三方安全插件或手动禁用头像(设置>讨论>头像)造成的。
设置,将在网页和REST响应中隐藏头像。
我们也找到了一个解决这些问题的方法。该端点支持参数 "搜索"。它的值与所有用户的字段匹配,包括电子邮件地址。通过简单的自动化,有可能发现每个电子邮件地址。与匹配的电子邮件相关的用户信息将在JSON响应中返回。根据经验,我们可以估计,揭示一个电子邮件地址需要200到400个请求。
https://api.*****.com/wp-json/wp/v2/users 已屏蔽 https://api.*****.com/wp-json/wp/v2/users?search=r@initech.com https://api.*****.com/wp-json/wp/v2/users?search=er@initech.com https://api.*****.com/wp-json/wp/v2/users?search=ter@initech.com https://api.*****.com/wp-json/wp/v2/users?search=eter@initech.com https://api.*****.com/wp-json/wp/v2/users?search=peter@initech.com 绕过
6. Yoast SEO
Yoast SEO是一个WordPress插件,可以帮助博客作者预览博客在搜索引擎中的显示方式,同时对完成关键的网站元数据有一定帮助。安装该插件后,每个页面都会包含JSON信息形式的元数据。关于帖子作者的元数据也包括在内,将返回其gravatar URL。
Yoast JSON元数据的例子
<script type='application/ld+json' class='yoast-schema-graph yoast-schema-graph--main'>{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https:// ***** /#website","url":"https://www.******.com/","name":"*****",
[...]
},
{
"@type":["Person"],
"@id":"https://www.****.com/#/schema/person/7367999b66**********",
"name":"Fred",
"image":{
"@type":"ImageObject",
"@id":"https://www.******.com/#authorlogo",
"url":"https://secure.gravatar.com/avatar/de04459893a29***********?s=96&d=mm&r=g",
"caption":"****"
},
"sameAs":[]
}]
</script>