Security Vulnerability in wpForo Forum WordPress Plugin

Introduction

According to the wpForo Forum WordPress Plugin page: “wpForo Forums is the best WordPress forum plugin. Full-fledged yet easy and light forum solution for your WordPress website. Comes with modern and responsive forum layouts and styles. This WordPress forum plugin brings everything you need to run an efficient and professional community. Powerful and beautiful forum with unique features.”

According to WordPress, at the time of writing the Plugin had 10,000+ active installations.

This issue was patched within hours by the vendor in version 1.4.12. CVE assigned as CVE-2018-11709.

Description

Version 1.4.11, and below, of the wpForo Forum WordPress Plugin were found to be vulnerable to Reflected Cross-Site Scripting (XSS). The vulnerability was due to the Plugin using the $_SERVER['REQUEST_URI'] PHP variable to create a URL string that was later output within HTML without any output encoding.

Risk

To successfully exploit this vulnerability, an attacker would need to entice a user into clicking on a specially crafted link. The user would need to be using the Internet Explorer (IE) web browser, with the, enabled by default, XSS filter disabled, or the attacker would need to use a valid IE XSS filter bypass payload.

Affected Software

wpForo Forum <= 1.4.11 - https://wordpress.org/plugins/wpforo/

Technical Description

The wpforo_get_request_uri() function defined in the wpf-includes/functions.php file uses the $_SERVER['REQUEST_URI'] variable to construct a URL, without any validation or output encoding. The full function code is shown below:

function wpforo_get_request_uri($with_port = FALSE, $get_referer_when_ajax = TRUE){
	if( $get_referer_when_ajax && wpforo_is_ajax() ){
		if( isset($_SERVER['HTTP_REFERER']) ){ return $_SERVER['HTTP_REFERER']; }
	}
	$s = is_ssl() ? 's' : '';
    $sp = strtolower($_SERVER["SERVER_PROTOCOL"]);
    $protocol = substr($sp, 0, strpos($sp, "/")) . $s;
    $port = ($_SERVER["SERVER_PORT"] == "80") ? "" : (":".$_SERVER["SERVER_PORT"]);
    return $protocol . "://" . $_SERVER['HTTP_HOST'] . ($with_port ? $port : '') . $_SERVER['REQUEST_URI'];
}

Proof of Concept (PoC)

Click on the following link while using the Internet Explorer (IE) web browser, with the XSS filter disabled:

http://www.example.com/index.php/community/?%22%3E%3Cscript%3Ealert(/XSS/)%3C/script%3E

Alternatively, run the following cURL request and notice that the XSS payload is output within HTML, without any validation, or output encoding:

curl -s 'http://www.example.com/index.php/community/?"><script>alert(/XSS/)</script>' | grep "XSS"

Remediation

Vendor: Pass the constructed URL string through WordPress’ esc_url() function before returning the string. For example:

$url = $protocol . "://" . $_SERVER['HTTP_HOST'] . ($with_port ? $port : '') . $_SERVER['REQUEST_URI'];
return esc_url($url);

Users: Update to version 1.4.12, which fixes the vulnerability.

Timeline

  • 31/05/2018 10:00: Issue discovered by Ryan (Dewhurst Security).
  • 31/05/2018 11:28: Sent vendor details via email.
  • 31/05/2018 11:33: Vendor replies stating they will release a patched version very soon.
  • 31/05/2018 20:49: Receive email from vendor stating new patched version released.
  • 01/06/2018 12:15: Advisory publicly released.

References