{"id":"GHSA-rq8q-p985-fjq7","kind":"vulnerability","aliases":["GHSA-rq8q-p985-fjq7"],"related":[],"title":"Possible XSS vulnerability in Action View strip_tags","description":"### Impact\n`strip_tags` in Action View returns its sanitized output marked `html_safe`, but the underlying sanitizer encodes only `&`, `<` and `>`, leaving `\"` and `'` unencoded. Because ERB does not escape a string marked `html_safe`, untrusted input passed through `strip_tags` and rendered inside a quoted HTML attribute value could close the attribute and add new attributes, possibly leading to XSS. Applications that render `strip_tags` output from untrusted input inside an HTML attribute, for example in a `title` attribute or a `<meta content>` tag, are affected. Output rendered as element content is not affected.\n\n### Details\n`strip_tags` now encodes `\"` and `'` in its output, as well as `&`, `<` and `>`, without double-encoding existing entities. Applications that use `strip_tags` output outside HTML, such as in a text template or JSON, now see `&quot;` and `&#39;` where they saw `\"` and `'`; `CGI.unescapeHTML` decodes them. See the Action View CHANGELOG.\n\n### Workarounds\nPass `strip_tags` output to an attribute through a tag helper, which escapes attribute values, for example `tag.a(title: strip_tags(user_input))`.\n\n### Releases\nThe fixed releases are available at the normal locations.\n\nPatches for those who cannot upgrade at once:\n- 8.1: https://github.com/rails/rails/commit/568b19cb860322885593e308a7f27aceb779e9d7.patch\n- 8.0: https://github.com/rails/rails/commit/c3772a10f405f9644125cbb484adfd2aa7a25a59.patch\n\n### Credit\nThis issue was responsibly reported by HackerOne researcher [lucasluitjes](https://hackerone.com/lucasluitjes).","summary":"Action View's strip_tags marks its output html_safe while leaving double and single quotes unencoded. Untrusted input rendered inside a quoted HTML attribute can close the attribute and add new attributes, which can lead to cross-site scripting.","severity":"medium","cvss":6.1,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"actionview","fixed":["8.1.4.1"],"affected":">= 8.1, < 8.1.4.1","ecosystem":"rubygems"},{"name":"actionview","fixed":["8.0.5.2"],"affected":"< 8.0.5.2","ecosystem":"rubygems"}],"ecosystems":["rubygems"],"tags":["actionview","cwe-79","package","rails","ruby","self-hosted"],"not_affected_if":["element-content-only","no-strip-tags-in-attributes","tag-helper-for-attributes"],"how_to_check":"- Search application views and helpers for `strip_tags` whose output is placed inside an HTML attribute such as `title` or `<meta content>`.\n- Check the installed Action View version with `bundle exec rails -v` or `bundle list actionview`; versions `>= 8.1, < 8.1.4.1` and `< 8.0.5.2` are affected.","fix":"- Action View `8.1.4.1` for the 8.1 line.\n- Action View `8.0.5.2` for the 8.0 line.\n- Maintainer patches exist for 8.1 and 8.0 for teams that cannot upgrade yet.","status":"open","published_at":"2026-11-04T03:02:09+00:00","first_seen_at":"2026-11-09T22:53:29+00:00","triaged_at":"2026-11-09T22:55:06+00:00","updated_at":"2026-11-09T22:55:06+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-09T22:55:06Z","model":"claude-haiku-5-5","output":{"fix":"- Action View `8.1.4.1` for the 8.1 line.\n- Action View `8.0.5.2` for the 8.0 line.\n- Maintainer patches exist for 8.1 and 8.0 for teams that cannot upgrade yet.","reach":"internet","title":"Rails Action View: strip_tags output can break out of HTML attributes","impact":"medium","summary":"Action View's strip_tags marks its output html_safe while leaving double and single quotes unencoded. Untrusted input rendered inside a quoted HTML attribute can close the attribute and add new attributes, which can lead to cross-site scripting.","audience":"businesses","category":"package","nicknames":[],"who_cares":["rails","actionview","ruby","self-hosted"],"confidence":0.8,"fix_status":"available","needs_auth":"unknown","worst_case":"attacker injects scripts that run in victims' browsers","analyst_note":"","how_to_check":"- Search application views and helpers for `strip_tags` whose output is placed inside an HTML attribute such as `title` or `<meta content>`.\n- Check the installed Action View version with `bundle exec rails -v` or `bundle list actionview`; versions `>= 8.1, < 8.1.4.1` and `< 8.0.5.2` are affected.","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["element-content-only","tag-helper-for-attributes","no-strip-tags-in-attributes"],"who_is_affected":"Applications that render strip_tags output from untrusted input inside an HTML attribute value, for example a title attribute or a meta content tag, are exposed. Output rendered as element content is not affected. Teams that use the tag helper for attribute values, as the advisory's workaround shows, are protected.","user_interaction":"unknown","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"medium"},"cost_usd":0.000847,"input_tokens":5161,"output_tokens":662,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-79':23B '/lucasluitjes).':274C '/rails/rails/commit/568b19cb860322885593e308a7f27aceb779e9d7.patch':257C '/rails/rails/commit/c3772a10f405f9644125cbb484adfd2aa7a25a59.patch':261C '8.0':258C '8.1':254C 'action':5A,30B,75C,209C 'actionview':19A,20A,21B 'add':60B,123C 'affect':153C,161C 'applic':130C,181C 'attribut':54B,58B,62B,116C,121C,125C,142C,148C,219C,226C 'avail':241C 'cannot':250C 'cgi.unescapehtml':204C 'changelog':211C 'close':56B,119C 'content':158C 'could':118C 'credit':262C 'cross':68B 'cross-sit':67B 'cwe':22B 'decod':205C 'detail':162C 'doubl':42B,177C 'double-encod':176C 'element':157C 'encod':88C,166C,178C 'entiti':180C 'erb':95C 'escap':98C,225C 'exampl':144C,229C 'exist':179C 'fix':238C 'fjq7':13A,18A 'ghsa':10A,15A 'ghsa-rq8q-p985-fjq7':9A,14A 'github.com':256C,260C 'github.com/rails/rails/commit/568b19cb860322885593e308a7f27aceb779e9d7.patch':255C 'github.com/rails/rails/commit/c3772a10f405f9644125cbb484adfd2aa7a25a59.patch':259C 'hackeron':269C 'hackerone.com':273C 'hackerone.com/lucasluitjes).':272C 'helper':223C 'host':29B 'html':38B,53B,82C,102C,115C,141C,188C 'impact':71C 'input':48B,105C,138C,235C 'insid':50B,112C,139C 'issu':264C 'json':196C 'lead':65B,127C 'leav':41B,91C 'locat':245C 'lucasluitj':271C 'mark':35B,81C,101C 'new':61B,124C 'normal':244C 'output':37B,80C,135C,154C,170C,186C,216C 'outsid':187C 'p985':12A,17A 'packag':24B 'pass':106C,213C 'patch':246C 'possibl':1A,126C 'quot':45B,52B,114C 'rail':25B 'releas':236C,239C 'render':49B,111C,132C,155C 'report':267C 'research':270C 'respons':266C 'return':77C 'rq8q':11A,16A 'rubi':26B 'safe':39B,83C,103C 'sanit':79C,87C 'saw':202C 'script':70B 'see':198C,207C 'self':28B 'self-host':27B 'singl':44B 'site':69B 'string':100C 'strip':7A,33B,72C,108C,133C,163C,184C,214C,232C 'tag':8A,34B,73C,109C,134C,151C,164C,185C,215C,222C,233C 'tag.a':230C 'templat':194C 'text':193C 'titl':147C,231C 'under':86C 'unencod':46B,93C 'untrust':47B,104C,137C 'upgrad':251C 'use':183C 'user':234C 'valu':117C,227C 'view':6A,31B,76C,210C 'vulner':3A 'well':172C 'without':175C 'workaround':212C 'xss':2A,129C","nicknames":[],"mitigations":[],"who_affected":"Applications that render strip_tags output from untrusted input inside an HTML attribute value, for example a title attribute or a meta content tag, are exposed. Output rendered as element content is not affected. Teams that use the tag helper for attribute values, as the advisory's workaround shows, are protected.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"businesses","plain_action":null,"pkeys":["actionview"],"ptokens":["actionview"],"labels":["actionview","cwe79","medium","package","rails","ruby","rubygems","selfhosted"],"campaign_type":null,"search_a":"'action':5A 'actionview':19A,20A 'fjq7':13A,18A 'ghsa':10A,15A 'ghsa-rq8q-p985-fjq7':9A,14A 'p985':12A,17A 'possibl':1A 'rq8q':11A,16A 'strip':7A 'tag':8A 'view':6A 'vulner':3A 'xss':2A","search_b":"'-79':23B 'action':30B 'actionview':21B 'add':60B 'attribut':54B,58B,62B 'close':56B 'cross':68B 'cross-sit':67B 'cwe':22B 'doubl':42B 'host':29B 'html':38B,53B 'input':48B 'insid':50B 'lead':65B 'leav':41B 'mark':35B 'new':61B 'output':37B 'packag':24B 'quot':45B,52B 'rail':25B 'render':49B 'rubi':26B 'safe':39B 'script':70B 'self':28B 'self-host':27B 'singl':44B 'site':69B 'strip':33B 'tag':34B 'unencod':46B 'untrust':47B 'view':31B","search_c":"'/lucasluitjes).':274C '/rails/rails/commit/568b19cb860322885593e308a7f27aceb779e9d7.patch':257C '/rails/rails/commit/c3772a10f405f9644125cbb484adfd2aa7a25a59.patch':261C '8.0':258C '8.1':254C 'action':75C,209C 'add':123C 'affect':153C,161C 'applic':130C,181C 'attribut':116C,121C,125C,142C,148C,219C,226C 'avail':241C 'cannot':250C 'cgi.unescapehtml':204C 'changelog':211C 'close':119C 'content':158C 'could':118C 'credit':262C 'decod':205C 'detail':162C 'doubl':177C 'double-encod':176C 'element':157C 'encod':88C,166C,178C 'entiti':180C 'erb':95C 'escap':98C,225C 'exampl':144C,229C 'exist':179C 'fix':238C 'github.com':256C,260C 'github.com/rails/rails/commit/568b19cb860322885593e308a7f27aceb779e9d7.patch':255C 'github.com/rails/rails/commit/c3772a10f405f9644125cbb484adfd2aa7a25a59.patch':259C 'hackeron':269C 'hackerone.com':273C 'hackerone.com/lucasluitjes).':272C 'helper':223C 'html':82C,102C,115C,141C,188C 'impact':71C 'input':105C,138C,235C 'insid':112C,139C 'issu':264C 'json':196C 'lead':127C 'leav':91C 'locat':245C 'lucasluitj':271C 'mark':81C,101C 'new':124C 'normal':244C 'output':80C,135C,154C,170C,186C,216C 'outsid':187C 'pass':106C,213C 'patch':246C 'possibl':126C 'quot':114C 'releas':236C,239C 'render':111C,132C,155C 'report':267C 'research':270C 'respons':266C 'return':77C 'safe':83C,103C 'sanit':79C,87C 'saw':202C 'see':198C,207C 'string':100C 'strip':72C,108C,133C,163C,184C,214C,232C 'tag':73C,109C,134C,151C,164C,185C,215C,222C,233C 'tag.a':230C 'templat':194C 'text':193C 'titl':147C,231C 'under':86C 'unencod':93C 'untrust':104C,137C 'upgrad':251C 'use':183C 'user':234C 'valu':117C,227C 'view':76C,210C 'well':172C 'without':175C 'workaround':212C 'xss':129C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-04T03:02:09+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"ghsa-repo","external_id":"GHSA-rq8q-p985-fjq7","url":"https://github.com/rails/rails/security/advisories/GHSA-rq8q-p985-fjq7","severity":"medium","published_at":"2026-11-04T03:02:09+00:00","modified_at":"2026-11-04T03:02:09+00:00","first_seen_at":"2026-11-09T22:53:29+00:00","fetched_at":"2026-11-09T22:53:29+00:00","note":null}],"documents":[{"id":110669,"url":"https://github.com/rails/rails/security/advisories/GHSA-rq8q-p985-fjq7","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa-repo","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's 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"}