{"id":"CVE-2017-20290","kind":"vulnerability","aliases":["CVE-2017-20290"],"related":[],"title":"Discourse: unsubscribe page reflects email parameter, runs script in browsers","description":"Discourse 1.9.0.beta2 before 1.9.0.beta13 contains a reflected cross-site scripting vulnerability that allows unauthenticated attackers to inject scripts through the email parameter of /email/unsubscribed. Attackers can craft GET requests with SVG onload payloads, which unsubscribed.html.erb renders unescaped via html_safe, executing JavaScript in victims' browsers. Exploitation evidence was first observed by the Shadowserver Foundation on 2023-10-19.","summary":"Discourse versions from 1.9.0.beta2 before 1.9.0.beta13 render the email parameter of the /email/unsubscribed page without escaping. An unauthenticated attacker can send a victim a crafted GET link with an SVG onload payload to run JavaScript in the victim's browser.","severity":"medium","cvss":6.1,"epss":0.00265,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["discourse","ruby-on-rails","runtime","self-hosted"],"not_affected_if":["default-config","managed-hosting"],"how_to_check":"- Check the installed Discourse version in the admin dashboard or the `version` file in the Discourse install directory\n- Look for `/email/unsubscribed` requests with `email=` values containing `<svg` or `onload` in web server access logs","fix":"- Upgrade Discourse to `1.9.0.beta13` or later, which the advisory names as the fixed release\n- Note: the sources do not give a specific current stable version to move to","status":"open","published_at":"2026-10-22T11:17:03+00:00","first_seen_at":"2026-10-23T21:57:30+00:00","triaged_at":"2026-10-25T04:03:23+00:00","updated_at":"2026-10-25T04:03:23+00:00","category":"runtime","confidence":0.8,"triage":{"at":"2026-10-25T04:03:23Z","model":"claude-haiku-5-5","output":{"fix":"- Upgrade Discourse to `1.9.0.beta13` or later, which the advisory names as the fixed release\n- Note: the sources do not give a specific current stable version to move to","reach":"internet","title":"Discourse: unsubscribe page reflects email parameter, runs script in browsers","impact":"medium","summary":"Discourse versions from 1.9.0.beta2 before 1.9.0.beta13 render the email parameter of the /email/unsubscribed page without escaping. An unauthenticated attacker can send a victim a crafted GET link with an SVG onload payload to run JavaScript in the victim's browser.","category":"runtime","nicknames":[],"who_cares":["discourse","self-hosted","ruby-on-rails"],"confidence":0.8,"needs_auth":"no","worst_case":"Victim browser runs attacker JavaScript in the Discourse origin","analyst_note":"Confirm the exact affected version range and fixed release against the Discourse advisory or NVD entry; sources here give only the beta version bounds.","how_to_check":"- Check the installed Discourse version in the admin dashboard or the `version` file in the Discourse install directory\n- Look for `/email/unsubscribed` requests with `email=` values containing `<svg` or `onload` in web server access logs","needs_analyst":true,"not_affected_if":["managed-hosting","default-config"],"who_is_affected":"Self-hosted Discourse instances running a version from 1.9.0.beta2 up to but not including 1.9.0.beta13 are exposed, because the flaw is in the unsubscribe template that any visitor can reach without logging in. Hosted Discourse services are maintained by their vendor, so the team running the instance should confirm the version it is on. Instances already on a later release are not affected.","user_interaction":"yes","needs_special_setup":"unknown","severity_if_unknown":"medium"},"cost_usd":0.000667,"input_tokens":3442,"output_tokens":646,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-10':127C '-19':128C '-2017':12A,15A '-20290':13A,16A '/email/unsubscribed':40B,94C '1.9.0':29B,32B,69C,72C '2023':126C 'allow':83C 'attack':46B,85C,95C 'beta13':33B,73C 'beta2':30B,70C 'browser':10A,67B,115C 'contain':74C 'craft':52B,97C 'cross':78C 'cross-sit':77C 'cve':11A,14A 'discours':1A,17B,26B,68C 'email':5A,36B,91C 'escap':43B 'evid':117C 'execut':111C 'exploit':116C 'first':119C 'foundat':124C 'get':53B,98C 'host':25B 'html':109C 'inject':87C 'javascript':62B,112C 'link':54B 'observ':120C 'onload':58B,102C 'page':3A,41B 'paramet':6A,37B,92C 'payload':59B,103C 'rail':21B 'reflect':4A,76C 'render':34B,106C 'request':99C 'rubi':19B 'ruby-on-rail':18B 'run':7A,61B 'runtim':22B 'safe':110C 'script':8A,80C,88C 'self':24B 'self-host':23B 'send':48B 'shadowserv':123C 'site':79C 'svg':57B,101C 'unauthent':45B,84C 'unescap':107C 'unsubscrib':2A 'unsubscribed.html.erb':105C 'version':27B 'via':108C 'victim':50B,65B,114C 'vulner':81C 'without':42B","nicknames":[],"mitigations":[],"who_affected":"Self-hosted Discourse instances running a version from 1.9.0.beta2 up to but not including 1.9.0.beta13 are exposed, because the flaw is in the unsubscribe template that any visitor can reach without logging in. Hosted Discourse services are maintained by their vendor, so the team running the instance should confirm the version it is on. Instances already on a later release are not affected.","tier":"C","verified":{},"analyst_revisit_at":null,"first_public_at":"2026-10-22T11:17:03+00:00","kev":null,"cvss_vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","cvss_by":"disclosure@vulncheck.com","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2017-20290","url":"https://nvd.nist.gov/vuln/detail/CVE-2017-20290","severity":null,"published_at":"2026-10-22T11:17:03+00:00","modified_at":"2026-10-22T11:17:03+00:00","first_seen_at":"2026-10-23T21:57:30+00:00","fetched_at":"2026-10-23T22:29:02+00:00","note":null},{"source":"epss","external_id":"CVE-2017-20290","url":"https://api.first.org/data/v1/epss?cve=CVE-2017-20290","severity":null,"published_at":null,"modified_at":null,"first_seen_at":"2026-10-24T07:15:51+00:00","fetched_at":"2026-10-24T07:15:51+00:00","note":null}],"documents":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}