{"id":"CVE-2026-64671","kind":"vulnerability","aliases":["CVE-2026-64671"],"related":[],"title":"Waline: unescaped commenter fields enable stored cross-site scripting","description":"Waline is a comment system with backend support. In versions 3.15.2 and prior, the @waline/client UserList widget builds its DOM by concatenating server-returned commenter fields directly into root.innerHTML with no HTML escaping. The commenter nick and link are stored and returned verbatim by the server (only the comment body is sanitized), and the link field is never sent to the spam filter. So an unauthenticated visitor who posts a comment with link = x\"><img src=x onerror=...> achieves stored cross-site scripting that executes, with no interaction, in the browser of every visitor to a page that embeds the UserList widget. At time of publication, there are no publicly available patches.","summary":"Waline's client UserList widget writes commenter nick and link fields into the page as raw HTML without escaping. An unauthenticated visitor can post a comment with a crafted link value that runs JavaScript in the browser of anyone who views a page embedding the widget.","severity":"high","cvss":7.2,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"@waline/client","fixed":[],"affected":"<= 3.15.2","ecosystem":"npm"}],"ecosystems":[],"tags":["@waline/client","comments","javascript","npm","package","userlist","waline","xss"],"not_affected_if":["auth-required","no-userlist-widget"],"how_to_check":"- Run npm ls @waline/client or check package.json and the lockfile; 3.15.2 and earlier are affected.\n- Search your code for the UserList widget (userList / user list component); the default CommentCard comment list is not affected.\n- Check your Waline server for comments whose link or nick contain quotes, angle brackets or onerror=.","fix":"No patched version listed in the maintainer advisory (GHSA-7w94-hxwm-gg99). Until one is published, stop rendering the UserList widget, or HTML-escape nick, link, avatar and label in packages/client/src/widgets/userList.ts. Newer @waline/client releases exist (3.16.2 on npm) but no source says they fix this; check the advisory before relying on one.","status":"open","published_at":"2026-11-11T05:19:51+00:00","first_seen_at":"2026-11-11T05:25:40+00:00","triaged_at":"2026-11-11T05:26:38+00:00","updated_at":"2026-11-11T05:27:10+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-11T05:26:38Z","model":"claude-haiku-5-5","output":{"fix":"- unknown","reach":"internet","title":"Waline: unescaped commenter fields enable stored cross-site scripting","impact":"medium","summary":"Waline's client UserList widget writes commenter nick and link fields into the page as raw HTML without escaping. An unauthenticated visitor can post a comment with a crafted link value that runs JavaScript in the browser of anyone who views a page embedding the widget.","audience":"developers","category":"package","nicknames":[],"who_cares":["waline","@waline/client","comments","javascript"],"confidence":0.7,"fix_status":"none","needs_auth":"no","worst_case":"script runs in every visitor's browser on embedding pages","analyst_note":"Confirm the fixed version and whether a patch exists, using the GitHub advisory linked from the NVD entry; sources say no patch was available at publication.","how_to_check":"- Check the installed `@waline/client` version in `package.json` and the lockfile; versions `3.15.2` and prior are described as affected.\n- Check whether the site embeds the UserList widget (the Waline user list component) on any public page.","plain_action":"","product_name":"","needs_analyst":true,"not_affected_if":["no-userlist-widget","auth-required"],"who_is_affected":"Sites that embed the @waline/client UserList widget and let anonymous visitors post comments are exposed, because the stored commenter link field is rendered unescaped to every visitor. Sites that do not use the UserList widget, or that run a patched version, can skip it. The sources state that no public patch existed at publication.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"high"},"cost_usd":0.000755,"input_tokens":4661,"output_tokens":578,"severity_before":"high"},"analyst_status":"done","analyst_note":"Confirm the fixed version and whether a patch exists, using the GitHub advisory linked from the NVD entry; sources say no patch was available at publication.","search":"'-2026':12A,15A '-64671':13A,16A '3.15.2':82C 'achiev':147C 'anyon':64B 'avail':180C 'backend':78C 'bodi':122C 'browser':62B,160C 'build':89C 'client':28B 'comment':3A,19B,32B,51B,75C,97C,107C,121C,143C 'concaten':93C 'craft':54B 'cross':8A,150C 'cross-sit':7A,149C 'cve':11A,14A 'direct':99C 'dom':91C 'emb':168C 'embed':69B 'enabl':5A 'escap':44B,105C 'everi':162C 'execut':154C 'field':4A,36B,98C,128C 'filter':135C 'html':42B,104C 'interact':157C 'javascript':20B,59B 'link':35B,55B,110C,127C,145C 'never':130C 'nick':33B,108C 'npm':21B 'packag':22B 'page':39B,68B,166C 'patch':181C 'post':49B,141C 'prior':84C 'public':175C,179C 'raw':41B 'return':96C,114C 'root.innerhtml':101C 'run':58B 'sanit':124C 'script':10A,152C 'sent':131C 'server':95C,118C 'server-return':94C 'site':9A,151C 'spam':134C 'store':6A,112C,148C 'support':79C 'system':76C 'time':173C 'unauthent':46B,138C 'unescap':2A 'userlist':23B,29B,87C,170C 'valu':56B 'verbatim':115C 'version':81C 'view':66B 'visitor':47B,139C,163C 'walin':1A,24B,26B,72C 'waline/client':17A,18B,86C 'widget':30B,71B,88C,171C 'without':43B 'write':31B 'x':146C 'xss':25B","nicknames":[],"mitigations":[],"who_affected":"Sites that load @waline/client and embed the UserList widget on a public page are exposed. Anyone can post a comment with a crafted link value (and nick when Akismet is off), and it runs script in every visitor's browser. If a logged-in user or admin views it, the script can read the Waline JWT in localStorage. Sites that only use the default comment list, or do not embed UserList, can skip it.","tier":"B","verified":{"fix":{"at":"2026-11-11T05:27:10Z","by":"analyst","doc":"https://github.com/walinejs/waline/security/advisories/GHSA-7w94-hxwm-gg99","run_id":3501},"products":{"at":"2026-11-11T05:27:10Z","by":"analyst","doc":"https://github.com/walinejs/waline/security/advisories/GHSA-7w94-hxwm-gg99","run_id":3501},"how_to_check":{"at":"2026-11-11T05:27:10Z","by":"analyst","doc":"https://github.com/walinejs/waline/security/advisories/GHSA-7w94-hxwm-gg99","run_id":3501},"who_affected":{"at":"2026-11-11T05:27:10Z","by":"analyst","doc":"https://github.com/walinejs/waline/security/advisories/GHSA-7w94-hxwm-gg99","run_id":3501}},"analyst_revisit_at":null,"fix_status":"none","audience":"developers","plain_action":null,"pkeys":["client"],"ptokens":["client","waline"],"labels":["client","comments","high","javascript","npm","package","userlist","waline","xss"],"campaign_type":null,"search_a":"'-2026':12A,15A '-64671':13A,16A 'comment':3A 'cross':8A 'cross-sit':7A 'cve':11A,14A 'enabl':5A 'field':4A 'script':10A 'site':9A 'store':6A 'unescap':2A 'walin':1A 'waline/client':17A","search_b":"'anyon':64B 'browser':62B 'client':28B 'comment':19B,32B,51B 'craft':54B 'embed':69B 'escap':44B 'field':36B 'html':42B 'javascript':20B,59B 'link':35B,55B 'nick':33B 'npm':21B 'packag':22B 'page':39B,68B 'post':49B 'raw':41B 'run':58B 'unauthent':46B 'userlist':23B,29B 'valu':56B 'view':66B 'visitor':47B 'walin':24B,26B 'waline/client':18B 'widget':30B,71B 'without':43B 'write':31B 'xss':25B","search_c":"'3.15.2':82C 'achiev':147C 'avail':180C 'backend':78C 'bodi':122C 'browser':160C 'build':89C 'comment':75C,97C,107C,121C,143C 'concaten':93C 'cross':150C 'cross-sit':149C 'direct':99C 'dom':91C 'emb':168C 'escap':105C 'everi':162C 'execut':154C 'field':98C,128C 'filter':135C 'html':104C 'interact':157C 'link':110C,127C,145C 'never':130C 'nick':108C 'page':166C 'patch':181C 'post':141C 'prior':84C 'public':175C,179C 'return':96C,114C 'root.innerhtml':101C 'sanit':124C 'script':152C 'sent':131C 'server':95C,118C 'server-return':94C 'site':151C 'spam':134C 'store':112C,148C 'support':79C 'system':76C 'time':173C 'unauthent':138C 'userlist':87C,170C 'verbatim':115C 'version':81C 'visitor':139C,163C 'walin':72C 'waline/client':86C 'widget':88C,171C 'x':146C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-07-05T06:59:02+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-advisories@github.com","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-64671","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-64671","severity":null,"published_at":"2026-11-11T05:19:51+00:00","modified_at":"2026-11-11T05:19:51+00:00","first_seen_at":"2026-11-11T05:25:40+00:00","fetched_at":"2026-11-11T05:25:40+00:00","note":null},{"source":"analyst","external_id":"CVE-2026-64671:3501","url":null,"severity":null,"published_at":"2026-11-11T05:27:10+00:00","modified_at":"2026-11-11T05:27:10+00:00","first_seen_at":"2026-11-11T05:27:10+00:00","fetched_at":"2026-11-11T05:27:10+00:00","note":"Read GHSA-7w94-hxwm-gg99: affected <= 3.15.2, patched versions none. npm latest is 3.16.2 but no source ties it to a fix; unverified."}],"documents":[{"id":122881,"url":"https://github.com/walinejs/waline/security/advisories/GHSA-7w94-hxwm-gg99","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-07-05T06:59:02+00:00","relation":"advisory","confidence":null,"note":"Vendor advisory: github.com"}],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}