New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ensure HTML output safety #1950
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👏🏻
@camertron can we please add this as a security advisory so dependabot can pick this up |
@reeganviljoen yes, that's the plan! I'll submit one as soon as this is merged and released 👍 |
What are your thoughts on backporting this fix to the v2 as well? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Co-authored-by: Blake Williams <blakewilliams@github.com>
@Spone we discussed that a bit internally and decided not to, but I could be persuaded otherwise. |
This addresses an XSS vector ViewComponent/view_component#1950
This addresses an XSS vector ViewComponent/view_component#1950
This addresses an XSS vector ViewComponent/view_component#1950
Well, I have half a dozen Rails apps that cannot be deployed today because bundler-audit is a mandatory step in my deployment pipeline:
I can either disable the bundler-audit check and open myself to vulnerabilities in other gems, or upgrade to ViewComponent 3.x, but given the slots breaking change, that would take hours if not days. EDIT: I just figured out about the ignore configuration file for bundler-audit, but I think it's still not ideal that these Rails apps will stay exposed until they are upgraded to VC 3. I'm pretty confident I'm not the only one in this case. |
What are you trying to accomplish?
This PR addresses a security concern affecting components that define a
#call
method. In most cases, HTML escaping is handled either by the template handler (ERB, Slim, HAML, etc) or by ActionView when the rendered string is appended to the output buffer. However, if a controller renders a component directly, the rendered string is not escaped and can be a vector for cross-site scripting (XSS) and similar attacks.Consider the following component:
If the component is rendered directly by the controller...
...and
params[:user_defined_input]
is the string<script>alert("foo")</script>
, the alert will be injected onto the page without being escaped, resulting in a browser alert. Sinceparams[:user_defined_input]
can contain arbitrary JavaScript code, cookies and other sensitive information can be exfiltrated to a 3rd-party.What approach did you choose and why?
This PR ensures that rendered output is HTML escaped, and if it is not, prints a warning and escapes it automatically. It does this for output from
#call
methods, output generated by template handlers, and for postambles.Finally, it examines the MIME type of the request and only performs automatic escaping when generating HTML. In other words, JSON generated by eg. jbuilder will not be automatically escaped.
Performance Impact
Performance is impacted, but not to a significant degree 👍