{"id":"CVE-2026-120739","kind":"vulnerability","aliases":["CVE-2026-120739"],"related":[],"title":"Optimole WordPress plugin: unauthenticated stored script injection via image srcsets","description":"The Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 's (missing_srcsets[*][*].s)' parameter in all versions up to, and including, 4.2.18 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page. The HMAC signature required to pass the REST endpoint's authorization check is published in plaintext to unauthenticated visitors inside the inline optimoleDataOptimizer JavaScript object on any page with an incomplete profile, making the effective authentication barrier nonexistent.","summary":"The Optimole image optimization plugin for WordPress fails to sanitize the missing_srcsets parameter, so an unauthenticated attacker can store arbitrary scripts that run in the browser of anyone who opens an affected page. The plugin also exposes the HMAC signature needed to pass its REST endpoint check in page source, removing the authentication barrier.","severity":"high","cvss":7.2,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"optimole-wp","fixed":["4.2.19"],"affected":"<= 4.2.18","ecosystem":"wordpress"}],"ecosystems":[],"tags":["optimole","package","php","plugin","unauthenticated","wordpress","xss"],"not_affected_if":["plugin-not-installed","plugin-updated"],"how_to_check":"- In WordPress admin > Plugins, check the Optimole version; 4.2.18 and earlier are affected, 4.2.19 is the patched release per Wordfence.\n- Or run: wp plugin get optimole-wp --field=version\n- View page source for the inline optimoleDataOptimizer object (exposes the HMAC); present on pages with an incomplete profile.","fix":"Update the Optimole plugin (optimole-wp) to 4.2.19 or later.","status":"open","published_at":"2026-11-07T04:17:13+00:00","first_seen_at":"2026-11-07T04:45:47+00:00","triaged_at":"2026-11-07T04:47:50+00:00","updated_at":"2026-11-07T04:49:04+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-07T04:47:50Z","model":"claude-haiku-5-5","output":{"fix":"unknown","reach":"internet","title":"Optimole WordPress plugin: unauthenticated stored script injection via image srcsets","impact":"medium","summary":"The Optimole image optimization plugin for WordPress fails to sanitize the missing_srcsets parameter, so an unauthenticated attacker can store arbitrary scripts that run in the browser of anyone who opens an affected page. The plugin also exposes the HMAC signature needed to pass its REST endpoint check in page source, removing the authentication barrier.","audience":"businesses","category":"package","nicknames":[],"who_cares":["wordpress","optimole","php"],"confidence":0.6,"fix_status":"unknown","needs_auth":"no","worst_case":"attacker runs scripts in visitors' browsers on the site","analyst_note":"Confirm the fixed version and whether a patched release exists; the NVD entry is the only source given.","how_to_check":"- Check the installed version of the Optimole plugin in the WordPress admin plugin list; versions up to and including `4.2.18` are affected.\n- Look for the inline `optimoleDataOptimizer` JavaScript object in page source on sites where the Optimole profile is incomplete.","plain_action":"","needs_analyst":true,"not_affected_if":["plugin-updated","plugin-not-installed"],"who_is_affected":"Sites running the Optimole plugin for WordPress at version 4.2.18 or earlier are exposed, and the exposure is worst where the Optimole profile is incomplete because the signature is then printed on public pages. Sites without the plugin, or running a newer version, are not affected according to the sources. The sources do not say whether a fixed version exists.","user_interaction":"yes","needs_special_setup":"unknown","severity_if_unknown":"high"},"cost_usd":0.000747,"input_tokens":4404,"output_tokens":614,"severity_before":"high"},"analyst_status":"done","analyst_note":"Confirm the fixed version and whether a patched release exists; the NVD entry is the only source given.","search":"'-120739':13A,16A '-2026':12A,15A '4.2.18':119C 'access':148C 'affect':59B 'also':63B 'anyon':55B 'arbitrari':47B,137C 'attack':44B,134C 'authent':80B,187C 'author':162C 'avif':88C 'barrier':81B,188C 'browser':53B 'cdn':89C 'check':74B,163C 'convert':86C 'cross':102C 'cross-sit':101C 'cve':11A,14A 'due':120C 'effect':186C 'endpoint':73B,160C 'escap':127C 'execut':144C 'expos':64B 'fail':34B 'hmac':66B,153C 'imag':9A,29B,85C,92C 'includ':118C 'incomplet':182C 'inject':7A,136C,150C 'inlin':173C 'input':123C 'insid':171C 'insuffici':122C 'javascript':175C 'lazi':90C 'load':91C 'make':129C,184C 'miss':38B,108C 'need':68B 'nonexist':189C 'object':176C 'open':57B 'optim':30B,84C,93C 'optimol':1A,20B,28B,83C 'optimole':18A 'optimole-wp':17A 'optimoledataoptim':174C 'output':126C 'packag':21B 'page':60B,76B,141C,151C,179C 'paramet':40B,111C 'pass':70B,157C 'php':22B 'plaintext':167C 'plugin':3A,23B,31B,62B,94C 'possibl':131C 'profil':183C 'publish':165C 'remov':78B 'requir':155C 'rest':72B,159C 'run':50B 'sanit':36B,124C 'script':6A,48B,104C,139C 'signatur':67B,154C 'site':103C 'sourc':77B 'srcset':10A,39B,109C 'store':5A,46B,100C 'unauthent':4A,24B,43B,133C,169C 'user':147C 'version':114C 'via':8A,105C 'visitor':170C 'vulner':98C 'web':138C 'webp':87C 'whenev':145C 'wordpress':2A,25B,33B,96C 'wp':19A 'xss':26B","nicknames":[],"mitigations":[],"who_affected":"Sites running the Optimole plugin for WordPress at version 4.2.18 or earlier are exposed, and the exposure is worst where the Optimole profile is incomplete because the signature is then printed on public pages. Sites without the plugin, or running a newer version, are not affected according to the sources. The sources do not say whether a fixed version exists.","tier":"B","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"businesses","plain_action":null,"pkeys":["optimolewp"],"ptokens":["optimole","wp"],"labels":["high","optimole","package","php","plugin","unauthenticated","wordpress","xss"],"campaign_type":null,"search_a":"'-120739':13A,16A '-2026':12A,15A 'cve':11A,14A 'imag':9A 'inject':7A 'optimol':1A 'optimole':18A 'optimole-wp':17A 'plugin':3A 'script':6A 'srcset':10A 'store':5A 'unauthent':4A 'via':8A 'wordpress':2A 'wp':19A","search_b":"'affect':59B 'also':63B 'anyon':55B 'arbitrari':47B 'attack':44B 'authent':80B 'barrier':81B 'browser':53B 'check':74B 'endpoint':73B 'expos':64B 'fail':34B 'hmac':66B 'imag':29B 'miss':38B 'need':68B 'open':57B 'optim':30B 'optimol':20B,28B 'packag':21B 'page':60B,76B 'paramet':40B 'pass':70B 'php':22B 'plugin':23B,31B,62B 'remov':78B 'rest':72B 'run':50B 'sanit':36B 'script':48B 'signatur':67B 'sourc':77B 'srcset':39B 'store':46B 'unauthent':24B,43B 'wordpress':25B,33B 'xss':26B","search_c":"'4.2.18':119C 'access':148C 'arbitrari':137C 'attack':134C 'authent':187C 'author':162C 'avif':88C 'barrier':188C 'cdn':89C 'check':163C 'convert':86C 'cross':102C 'cross-sit':101C 'due':120C 'effect':186C 'endpoint':160C 'escap':127C 'execut':144C 'hmac':153C 'imag':85C,92C 'includ':118C 'incomplet':182C 'inject':136C,150C 'inlin':173C 'input':123C 'insid':171C 'insuffici':122C 'javascript':175C 'lazi':90C 'load':91C 'make':129C,184C 'miss':108C 'nonexist':189C 'object':176C 'optim':84C,93C 'optimol':83C 'optimoledataoptim':174C 'output':126C 'page':141C,151C,179C 'paramet':111C 'pass':157C 'plaintext':167C 'plugin':94C 'possibl':131C 'profil':183C 'publish':165C 'requir':155C 'rest':159C 'sanit':124C 'script':104C,139C 'signatur':154C 'site':103C 'srcset':109C 'store':100C 'unauthent':133C,169C 'user':147C 'version':114C 'via':105C 'visitor':170C 'vulner':98C 'web':138C 'webp':87C 'whenev':145C 'wordpress':96C","first_public_at":"2026-11-07T04:17:13+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N","cvss_by":"security@wordfence.com","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-120739","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-120739","severity":null,"published_at":"2026-11-07T04:17:13+00:00","modified_at":"2026-11-07T04:17:13+00:00","first_seen_at":"2026-11-07T04:45:47+00:00","fetched_at":"2026-11-07T04:45:47+00:00","note":null},{"source":"analyst","external_id":"CVE-2026-120739:1952","url":"https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/optimole-wp/optimole-4218-unauthenticated-stored-cross-site-scripting-via-page-profiler-srcset-descriptor","severity":null,"published_at":"2026-11-07T04:49:04+00:00","modified_at":"2026-11-07T04:49:04+00:00","first_seen_at":"2026-11-07T04:49:04+00:00","fetched_at":"2026-11-07T04:49:04+00:00","note":"Wordfence (researcher mamgad, published 2026-11-06) lists patched version 4.2.19, affected <= 4.2.18; WPSec shows 4.2.19 released 2026-11-04 for a sibling Optimole issue. No vendor changelog or wordpress.org advisory could be read (changelog tab not in fetched text), so nothing marked verified. No exploitation or PoC found. X not searched. Sibling CVE-2026-120677 (comment XSS) has the same affected range.","cites":["https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/optimole-wp/optimole-4218-unauthenticated-stored-cross-site-scripting-via-page-profiler-srcset-descriptor","https://wpsec.com/vuln/WPSEC-2026-2623/"]}],"documents":[{"id":92831,"url":"https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/optimole-wp/optimole-4218-unauthenticated-stored-cross-site-scripting-via-page-profiler-srcset-descriptor","title":"Optimole <= 4.2.18 - Unauthenticated Stored XSS via Page Profiler srcset Descriptor (Wordfence)","kind":"advisory","source":"analyst","publisher":null,"text":null,"published_at":null,"relation":"advisory","confidence":null,"note":null},{"id":92832,"url":"https://wpsec.com/vuln/WPSEC-2026-2623/","title":"WPSec: Optimole <= 4.2.18 Contributor+ stored XSS, fixed in 4.2.19","kind":"other","source":"analyst","publisher":null,"text":null,"published_at":null,"relation":"mentions","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"}