{"id":"CVE-2026-121976","kind":"vulnerability","aliases":["CVE-2026-121976"],"related":[],"title":"Modula gallery plugin for WordPress: stored script injection via image links","description":"The Modula plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'items' parameter in versions up to, and including, 3.0.17 This is due to insufficient input sanitization of the per-image 'link' field in the save_merged_items() REST handler and Images\\Adapter::normalize_item_row(), which preserves unknown keys verbatim, combined with output escaping in Modula_Helper::generate_attributes() that applies only esc_attr() to the resulting anchor href and does not strip the 'javascript:' URL scheme. This makes it possible for authenticated attackers, with Author-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page and clicks the gallery tile.","summary":"The Modula plugin for WordPress up to and including 3.0.17 fails to sanitize the per-image link field, so a javascript: URL can be saved into a gallery. When a visitor clicks the gallery tile on the injected page, the script runs in their browser.","severity":"medium","cvss":6.4,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["modula","package","self-hosted","wordpress"],"not_affected_if":["no-untrusted-authors","plugin-not-installed"],"how_to_check":"- Check the installed Modula plugin version in the WordPress admin plugin list; versions `3.0.17` and below are in the stated range.\n- Review gallery image link fields for values beginning with `javascript:`.","fix":null,"status":"open","published_at":"2026-11-07T12:17:45+00:00","first_seen_at":"2026-11-07T12:47:09+00:00","triaged_at":"2026-11-07T12:49:02+00:00","updated_at":"2026-11-07T12:49:02+00:00","category":"package","confidence":0.7,"triage":{"at":"2026-11-07T12:49:02Z","model":"claude-haiku-5-5","output":{"fix":"unknown","reach":"internet","title":"Modula gallery plugin for WordPress: stored script injection via image links","impact":"medium","summary":"The Modula plugin for WordPress up to and including 3.0.17 fails to sanitize the per-image link field, so a javascript: URL can be saved into a gallery. When a visitor clicks the gallery tile on the injected page, the script runs in their browser.","audience":"businesses","category":"package","nicknames":[],"who_cares":["wordpress","modula","self-hosted"],"confidence":0.7,"fix_status":"unknown","needs_auth":"yes","worst_case":"Visitors' browsers run attacker scripts on the site","analyst_note":"Confirm the fixed version of the Modula plugin beyond 3.0.17 from the vendor or the NVD entry.","how_to_check":"- Check the installed Modula plugin version in the WordPress admin plugin list; versions `3.0.17` and below are in the stated range.\n- Review gallery image link fields for values beginning with `javascript:`.","plain_action":"","needs_analyst":true,"not_affected_if":["plugin-not-installed","no-untrusted-authors"],"who_is_affected":"Sites running the Modula gallery plugin at version 3.0.17 or earlier where Author-level or higher accounts can edit gallery content. Sites without the plugin, or without untrusted authors, have less exposure. The sources do not describe the fixed version.","user_interaction":"yes","needs_special_setup":"unknown","severity_if_unknown":"medium"},"cost_usd":0.000708,"input_tokens":4385,"output_tokens":538,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-121976':14A,17A '-2026':13A,16A '3.0.17':33B,93C 'access':164C,180C 'adapt':117C 'anchor':143C 'appli':136C 'arbitrari':169C 'attack':159C 'attr':139C 'attribut':134C 'authent':158C 'author':162C 'author-level':161C 'browser':69B 'click':56B,185C 'combin':126C 'cross':80C 'cross-sit':79C 'cve':12A,15A 'due':96C 'esc':138C 'escap':129C 'execut':176C 'fail':34B 'field':42B,107C 'galleri':2A,52B,58B,187C 'generat':133C 'handler':114C 'helper':132C 'host':22B 'href':144C 'imag':10A,40B,105C,116C 'includ':32B,92C 'inject':8A,62B,168C,182C 'input':99C 'insuffici':98C 'item':85C,112C,119C 'javascript':45B,150C 'key':124C 'level':163C 'link':11A,41B,106C 'make':154C 'merg':111C 'modula':1A,18B,25B,71C,131C 'normal':118C 'output':128C 'packag':19B 'page':63B,173C,183C 'paramet':86C 'per':39B,104C 'per-imag':38B,103C 'plugin':3A,26B,72C 'possibl':156C 'preserv':122C 'rest':113C 'result':142C 'row':120C 'run':66B 'sanit':36B,100C 'save':49B,110C 'scheme':152C 'script':7A,65B,82C,171C 'self':21B 'self-host':20B 'site':81C 'store':6A,78C 'strip':148C 'tile':59B,188C 'unknown':123C 'url':46B,151C 'user':179C 'verbatim':125C 'version':88C 'via':9A,83C 'visitor':55B 'vulner':76C 'web':170C 'whenev':177C 'wordpress':5A,23B,28B,74C","nicknames":[],"mitigations":[],"who_affected":"Sites running the Modula gallery plugin at version 3.0.17 or earlier where Author-level or higher accounts can edit gallery content. Sites without the plugin, or without untrusted authors, have less exposure. The sources do not describe the fixed version.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"none","audience":"businesses","plain_action":null,"pkeys":[],"ptokens":[],"labels":["medium","modula","package","selfhosted","wordpress"],"campaign_type":null,"search_a":"'-121976':14A,17A '-2026':13A,16A 'cve':12A,15A 'galleri':2A 'imag':10A 'inject':8A 'link':11A 'modula':1A 'plugin':3A 'script':7A 'store':6A 'via':9A 'wordpress':5A","search_b":"'3.0.17':33B 'browser':69B 'click':56B 'fail':34B 'field':42B 'galleri':52B,58B 'host':22B 'imag':40B 'includ':32B 'inject':62B 'javascript':45B 'link':41B 'modula':18B,25B 'packag':19B 'page':63B 'per':39B 'per-imag':38B 'plugin':26B 'run':66B 'sanit':36B 'save':49B 'script':65B 'self':21B 'self-host':20B 'tile':59B 'url':46B 'visitor':55B 'wordpress':23B,28B","search_c":"'3.0.17':93C 'access':164C,180C 'adapt':117C 'anchor':143C 'appli':136C 'arbitrari':169C 'attack':159C 'attr':139C 'attribut':134C 'authent':158C 'author':162C 'author-level':161C 'click':185C 'combin':126C 'cross':80C 'cross-sit':79C 'due':96C 'esc':138C 'escap':129C 'execut':176C 'field':107C 'galleri':187C 'generat':133C 'handler':114C 'helper':132C 'href':144C 'imag':105C,116C 'includ':92C 'inject':168C,182C 'input':99C 'insuffici':98C 'item':85C,112C,119C 'javascript':150C 'key':124C 'level':163C 'link':106C 'make':154C 'merg':111C 'modula':71C,131C 'normal':118C 'output':128C 'page':173C,183C 'paramet':86C 'per':104C 'per-imag':103C 'plugin':72C 'possibl':156C 'preserv':122C 'rest':113C 'result':142C 'row':120C 'sanit':100C 'save':110C 'scheme':152C 'script':82C,171C 'site':81C 'store':78C 'strip':148C 'tile':188C 'unknown':123C 'url':151C 'user':179C 'verbatim':125C 'version':88C 'via':83C 'vulner':76C 'web':170C 'whenev':177C 'wordpress':74C","first_public_at":"2026-11-07T12:17:45+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:L/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-121976","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-121976","severity":null,"published_at":"2026-11-07T12:17:45+00:00","modified_at":"2026-11-07T12:17:45+00:00","first_seen_at":"2026-11-07T12:47:09+00:00","fetched_at":"2026-11-07T12:47:09+00:00","note":null}],"documents":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}