HTML injection vulnerability in WordPress CformsII plugin.

The WordPress CformsII plugin, which has 10,000+ active installations, was prone to an HTML injection vulnerability affecting all email messages sent from its contact form.

Last month, we disclosed the details of an HTML injection vulnerability affecting the Pirate Forms plugin. CformsII v15.0.1 and below was prone to the same type of vulnerability.

Unauthenticated HTML injection

The vulnerable code is located in the ‘lib_aux.php’ script.
Inside the ‘cforms2_get_ip’ function, line 298, the plugin gets the user IP from untrusted sources: HTTP_X_FORWARDED_FOR or HTTP_CLIENT_IP:

function cforms2_get_ip() {
   if (isset($_SERVER)) {
      if (isset($_SERVER["HTTP_X_FORWARDED_FOR"]))
         $ip_addr = $_SERVER["HTTP_X_FORWARDED_FOR"];
      elseif (isset($_SERVER["HTTP_CLIENT_IP"]))
         $ip_addr = $_SERVER["HTTP_CLIENT_IP"];
      else
         $ip_addr = $_SERVER["REMOTE_ADDR"];
   } else {
      if (getenv('HTTP_X_FORWARDED_FOR'))
         $ip_addr = getenv('HTTP_X_FORWARDED_FOR');
      elseif (getenv('HTTP_CLIENT_IP'))
         $ip_addr = getenv('HTTP_CLIENT_IP');
      else
         $ip_addr = getenv('REMOTE_ADDR');
   }
   return $ip_addr;

}

Inside the ‘cforms2_check_default_vars’ function, line 230, the {IP} placeholder used in the email template is replaced with that user IP, but it is neither verified not sanitized:

if (isset($_SERVER['HTTP_REFERER']))
   $m = str_replace('{Referer}', $_SERVER['HTTP_REFERER'], $m);
$m = str_replace('{PostID}', $pid, $m);
$m = str_replace('{Form Name}', Cforms2\FormSettings::form($no)->name(), $m);
$m = str_replace('{Page}', $page, $m);
$m = str_replace('{Date}', $date, $m);
$m = str_replace('{Author}', $user_name, $m);
$m = str_replace('{Time}', $time, $m);
$m = str_replace('{IP}', cforms2_get_ip(), $m);
$m = str_replace('{BLOGNAME}', get_option('blogname'), $m);

Because CformsII forwards all email messages sent from the contact form to the admin mailbox using HTML format by default, any HTML code can be injected into the template.
We can see that line 223 the {Referer} placeholder is replaced with HTTP_REFERER (which too, is an unstrusted source because it’s a user input), and isn’t sanitized either. But unlike the user IP, it is not used in the default template though.

An unauthenticated attacker can inject code into the email body, for instance, a link pointing to a malicious login page URL in an attempt to steal the administrator credentials:

A CSRF attack could also be used against an authenticated administrator in order to trick the victim into performing an undesired action on their own website (that’s why, if you’re a WordPress plugin or theme developer, you should use security nonces to block this type of attack).

Timeline

The vulnerability was discovered and reported to the wordpress.org team on July 18, 2019.

Recommendations

Update as soon as possible if you have version 15.0.1 or below installed.
If you are using our web application firewall for WordPress, NinjaFirewall WP Edition (free) and NinjaFirewall WP+ Edition (premium), you are protected.
NinjaFirewall protects proactively against this type of vulnerability.

Stay informed about the latest vulnerabilities in WordPress plugins and themes: @nintechnet