{"id":"CVE-2026-87112","kind":"vulnerability","aliases":["CVE-2026-87112"],"related":[],"title":"WordPress QA Assistants plugin: unauthenticated object injection leads to code execution","description":"The QA Assistants – Driven by data plugin for WordPress is vulnerable to PHP Object Injection in all versions up to, and including, 5.3.0 via the 'dlevent_ver' parameter. This is due to unrestricted PHP deserialization via wrap_unserialize_static() calling unserialize() without an allowed_classes restriction, combined with serialize_escape() failing to sanitize path traversal sequences in the raw_name parameter. This makes it possible for unauthenticated attackers to inject a PHP Object. The Guzzle FileCookieJar gadget present in the plugin's bundled Composer dependencies can be leveraged to perform an Arbitrary File Write, writing attacker-controlled content to an attacker-chosen filename, which can result in Remote Code Execution. Exploitation requires triggering the qahm_cron_data_manage scheduled event via wp-cron.php to invoke the deserialization sink against a planted queue file, but this endpoint requires no authentication and fires automatically on a two-minute schedule.","summary":"The QA Assistants plugin for WordPress unserializes attacker-supplied data through the dlevent_ver parameter without restriction, letting an unauthenticated attacker inject a PHP object. A Guzzle gadget in the bundled dependencies can then write attacker-chosen files, which can lead to remote code execution on the site.","severity":"high","cvss":8.8,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"qa-heatmap-analytics","fixed":["5.3.0.1"],"affected":"<= 5.3.0","ecosystem":"wordpress"}],"ecosystems":[],"tags":["package","php","self-hosted","wordpress"],"not_affected_if":["patched-5.3.0.1+","plugin-not-installed"],"how_to_check":"- In WordPress admin, Plugins > Installed Plugins: look for 'QA Assistants – Driven by data' (slug qa-heatmap-analytics). Version 5.3.0 or earlier is vulnerable (the plugin header or wp plugin get qa-heatmap-analytics --field=version shows it).\n- 5.3.0.1 is the fixed version; 5.3.0.2 is current.\n- Also check the web root for unexpected PHP files written under the plugin's data directories, and look for requests to wp-cron.php with odd parameters.","fix":"Update QA Assistants – Driven by data (slug qa-heatmap-analytics) to 5.3.0.1 or later; 5.3.0.2 is current and fixes a separate XSS.","status":"open","published_at":"2026-11-07T07:17:05+00:00","first_seen_at":"2026-11-07T07:46:07+00:00","triaged_at":"2026-11-07T07:47:00+00:00","updated_at":"2026-11-07T07:48:33+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-07T07:47:00Z","model":"claude-haiku-5-5","output":{"fix":"unknown","reach":"internet","title":"WordPress QA Assistants plugin: unauthenticated object injection leads to code execution","impact":"high","summary":"The QA Assistants plugin for WordPress unserializes attacker-supplied data through the dlevent_ver parameter without restriction, letting an unauthenticated attacker inject a PHP object. A Guzzle gadget in the bundled dependencies can then write attacker-chosen files, which can lead to remote code execution on the site.","audience":"businesses","category":"package","nicknames":[],"who_cares":["wordpress","php","self-hosted"],"confidence":0.7,"fix_status":"unknown","needs_auth":"no","worst_case":"Attacker writes files and achieves remote code execution on the server","analyst_note":"Sources list only NVD; confirm the fixed version and any vendor advisory for the QA Assistants plugin.","how_to_check":"- Check the installed version of the QA Assistants – Driven by data plugin in the WordPress admin plugin list or its main plugin file header.\n- Confirm whether the installed version is `5.3.0` or earlier, since all versions up to and including `5.3.0` are described as vulnerable.","plain_action":"","needs_analyst":true,"not_affected_if":["plugin-not-installed"],"who_is_affected":"Any WordPress site with the QA Assistants – Driven by data plugin installed and active is described as exposed, because the sources say the flaw is reachable without authentication through wp-cron.php. Sites that do not run this plugin are not affected. The sources do not state which configuration options, if any, change exposure.","user_interaction":"no","needs_special_setup":"no","severity_if_unknown":"high"},"cost_usd":0.000742,"input_tokens":4477,"output_tokens":589,"severity_before":"high"},"analyst_status":"done","analyst_note":"Sources list only NVD; confirm the fixed version and any vendor advisory for the QA Assistants plugin.","search":"'-2026':13A,16A '-87112':14A,17A '5.3.0':100C 'allow':121C 'analytics':21A 'arbitrari':169C 'assist':3A,30B,80C 'attack':36B,49B,65B,145C,174C,180C 'attacker-chosen':64B,179C 'attacker-control':173C 'attacker-suppli':35B 'authent':217C 'automat':220C 'bundl':59B,160C 'call':117C 'chosen':66B,181C 'class':122C 'code':10A,73B,188C 'combin':124C 'compos':161C 'content':176C 'control':175C 'cron':195C 'cve':12A,15A 'data':38B,83C,196C 'depend':60B,162C 'deseri':112C,205C 'dlevent':41B,103C 'driven':81C 'due':108C 'endpoint':214C 'escap':127C 'event':199C 'execut':11A,74B,189C 'exploit':190C 'fail':128C 'file':67B,170C,211C 'filecookiejar':153C 'filenam':182C 'fire':219C 'gadget':56B,154C 'guzzl':55B,152C 'heatmap':20A 'host':26B 'includ':99C 'inject':7A,50B,92C,147C 'invok':203C 'lead':8A,70B 'let':46B 'leverag':165C 'make':140C 'manag':197C 'minut':225C 'name':137C 'object':6A,53B,91C,150C 'packag':22B 'paramet':43B,105C,138C 'path':131C 'perform':167C 'php':23B,52B,90C,111C,149C 'plant':209C 'plugin':4A,31B,84C,158C 'possibl':142C 'present':155C 'qa':2A,19A,29B,79C 'qa-heatmap-analytics':18A 'qahm':194C 'queue':210C 'raw':136C 'remot':72B,187C 'requir':191C,215C 'restrict':45B,123C 'result':185C 'sanit':130C 'schedul':198C,226C 'self':25B 'self-host':24B 'sequenc':133C 'serial':126C 'sink':206C 'site':77B 'static':116C 'suppli':37B 'travers':132C 'trigger':192C 'two':224C 'two-minut':223C 'unauthent':5A,48B,144C 'unrestrict':110C 'unseri':34B,115C,118C 'ver':42B,104C 'version':95C 'via':101C,113C,200C 'vulner':88C 'without':44B,119C 'wordpress':1A,27B,33B,86C 'wp-cron.php':201C 'wrap':114C 'write':63B,171C,172C","nicknames":[],"mitigations":[],"who_affected":"Any WordPress site running the QA Assistants – Driven by data plugin (qa-heatmap-analytics) version 5.3.0 or earlier. Wordfence describes it as reachable without login through wp-cron.php, which runs automatically, and a bundled Guzzle gadget can write a file, leading to code execution. Sites without the plugin, or on 5.3.0.1 or later, can skip it.","tier":"B","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"businesses","plain_action":null,"pkeys":["qaheatmapanalytics"],"ptokens":["analytics","heatmap","qa"],"labels":["high","package","php","selfhosted","wordpress"],"campaign_type":null,"search_a":"'-2026':13A,16A '-87112':14A,17A 'analytics':21A 'assist':3A 'code':10A 'cve':12A,15A 'execut':11A 'heatmap':20A 'inject':7A 'lead':8A 'object':6A 'plugin':4A 'qa':2A,19A 'qa-heatmap-analytics':18A 'unauthent':5A 'wordpress':1A","search_b":"'assist':30B 'attack':36B,49B,65B 'attacker-chosen':64B 'attacker-suppli':35B 'bundl':59B 'chosen':66B 'code':73B 'data':38B 'depend':60B 'dlevent':41B 'execut':74B 'file':67B 'gadget':56B 'guzzl':55B 'host':26B 'inject':50B 'lead':70B 'let':46B 'object':53B 'packag':22B 'paramet':43B 'php':23B,52B 'plugin':31B 'qa':29B 'remot':72B 'restrict':45B 'self':25B 'self-host':24B 'site':77B 'suppli':37B 'unauthent':48B 'unseri':34B 'ver':42B 'without':44B 'wordpress':27B,33B 'write':63B","search_c":"'5.3.0':100C 'allow':121C 'arbitrari':169C 'assist':80C 'attack':145C,174C,180C 'attacker-chosen':179C 'attacker-control':173C 'authent':217C 'automat':220C 'bundl':160C 'call':117C 'chosen':181C 'class':122C 'code':188C 'combin':124C 'compos':161C 'content':176C 'control':175C 'cron':195C 'data':83C,196C 'depend':162C 'deseri':112C,205C 'dlevent':103C 'driven':81C 'due':108C 'endpoint':214C 'escap':127C 'event':199C 'execut':189C 'exploit':190C 'fail':128C 'file':170C,211C 'filecookiejar':153C 'filenam':182C 'fire':219C 'gadget':154C 'guzzl':152C 'includ':99C 'inject':92C,147C 'invok':203C 'leverag':165C 'make':140C 'manag':197C 'minut':225C 'name':137C 'object':91C,150C 'paramet':105C,138C 'path':131C 'perform':167C 'php':90C,111C,149C 'plant':209C 'plugin':84C,158C 'possibl':142C 'present':155C 'qa':79C 'qahm':194C 'queue':210C 'raw':136C 'remot':187C 'requir':191C,215C 'restrict':123C 'result':185C 'sanit':130C 'schedul':198C,226C 'sequenc':133C 'serial':126C 'sink':206C 'static':116C 'travers':132C 'trigger':192C 'two':224C 'two-minut':223C 'unauthent':144C 'unrestrict':110C 'unseri':115C,118C 'ver':104C 'version':95C 'via':101C,113C,200C 'vulner':88C 'without':119C 'wordpress':86C 'wp-cron.php':201C 'wrap':114C 'write':171C,172C","first_public_at":"2026-11-07T07:17:05+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","cvss_by":"security@wordfence.com","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-87112","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-87112","severity":null,"published_at":"2026-11-07T07:17:05+00:00","modified_at":"2026-11-07T07:17:05+00:00","first_seen_at":"2026-11-07T07:46:07+00:00","fetched_at":"2026-11-07T07:46:07+00:00","note":null},{"source":"analyst","external_id":"CVE-2026-87112:2084","url":"https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/qa-heatmap-analytics/qa-assistants-530-unauthenticated-php-object-injection-to-remote-code-execution-via-raw-name-and-dlevent-ver-parameters","severity":null,"published_at":"2026-11-07T07:48:33+00:00","modified_at":"2026-11-07T07:48:33+00:00","first_seen_at":"2026-11-07T07:48:33+00:00","fetched_at":"2026-11-07T07:48:33+00:00","note":"Wordfence and Patchstack (both third-party) give fixed version 5.3.0.1; the wordpress.org changelog (maintainer QuarkA) lists 5.3.0.1 as 'Security and internal improvements' without naming the CVE, and 5.3.0.2 is the latest (a further security fix). Nothing marked verified because no maintainer page names this CVE. No exploitation or PoC found; Patchstack expects mass exploitation. Wordfence vector says PR:L although the text says unauthenticated. X not checked.","cites":["https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/qa-heatmap-analytics/qa-assistants-530-unauthenticated-php-object-injection-to-remote-code-execution-via-raw-name-and-dlevent-ver-parameters","https://wordpress.org/plugins/qa-heatmap-analytics/","https://patchstack.com/database/wordpress/plugin/qa-heatmap-analytics/vulnerability/wordpress-qa-assistants-driven-by-data-plugin-5-3-0-unauthenticated-php-object-injection-to-remote-code-execution-vulnerability"]}],"documents":[{"id":93983,"url":"https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/qa-heatmap-analytics/qa-assistants-530-unauthenticated-php-object-injection-to-remote-code-execution-via-raw-name-and-dlevent-ver-parameters","title":"Wordfence: QA Assistants <= 5.3.0 unauthenticated PHP object injection to RCE","kind":"advisory","source":"analyst","publisher":null,"text":null,"published_at":null,"relation":"advisory","confidence":null,"note":null},{"id":93984,"url":"https://wordpress.org/plugins/qa-heatmap-analytics/","title":"QA Assistants – Driven by data (wordpress.org, changelog)","kind":"release","source":"analyst","publisher":null,"text":null,"published_at":null,"relation":"fix","confidence":null,"note":null},{"id":93985,"url":"https://patchstack.com/database/wordpress/plugin/qa-heatmap-analytics/vulnerability/wordpress-qa-assistants-driven-by-data-plugin-5-3-0-unauthenticated-php-object-injection-to-remote-code-execution-vulnerability","title":"Patchstack: QA Assistants <= 5.3.0 deserialization","kind":"advisory","source":"analyst","publisher":null,"text":null,"published_at":null,"relation":"advisory","confidence":null,"note":null}],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}