Skip to content
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

Toast: Escape toast HTML content that is not wrapped in "-pharos-" tag #818

Closed
wants to merge 7 commits into from

Conversation

ymouzakis
Copy link
Contributor

@ymouzakis ymouzakis commented Sep 24, 2024

User supplied strings can end up being part of a toast messages content. This is a XSS risk.

This change: (check at least one)

  • Adds a new feature
  • Fixes a bug
  • Improves maintainability
  • Improves documentation
  • Is a release activity

Is this a breaking change? (check one)

  • Yes
  • No

Is the: (complete all)

  • Title of this pull request clear, concise, and indicative of the issue number it addresses, if any?
  • Test suite(s) passing?
  • Code coverage maximal?
  • Changeset added?
  • Component status page up to date?

What does this change address?
A clear and concise description or a direct link to an issue [e.g. #15]
If adding a feature, a rationale for its addition goes here.

How does this change work?
A clear, detailed description of how this change addresses the issue.
This could be a bullet list if there are several moving parts.

Additional context
Add any other context here.

@ymouzakis ymouzakis requested a review from a team as a code owner September 24, 2024 16:45
@ymouzakis ymouzakis requested review from brentswisher, sirrah-tam and mtorres3 and removed request for a team September 24, 2024 16:45
Copy link

changeset-bot bot commented Sep 24, 2024

🦋 Changeset detected

Latest commit: fa7d891

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@ithaka/pharos Major
@ithaka/pharos-site Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Comment on lines +2 to +5
'@ithaka/pharos': major
---

Escape toast HTML content that is not wrapped in "-pharos-" tag
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if theres any way we could feel comfortable making this a patch release? It might not be possible but that will lower the barrier of entry to release the update

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can change it. I was erroring on the side of caution since this could be a breaking change.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could see us having a brief discussion with the group. I can definitely see where you were coming from as things could break but is it OK that they break if it fixes a semi-vulnerability?

Copy link
Member

@daneah daneah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have concerns about this change, which amount to:

  • It should generally be the responsibility of the consumer to ensure escaping of untrusted HTML content rather than rendering it to the browser. Cleaning HTML content here in Pharos does not ensure that the untrusted content isn't rendered somewhere else in some other way, and may in fact deliver surprising results to developers who will need to read the Toast code to understand why they're seeing what they're seeing.
  • Choosing this one place to avoid rendering untrusted content feels like a narrowly-scoped pattern that should be avoided; we would want to apply this kind of protection across many components if we wanted to go this direction, and I don't think the solution as-is can be iteratively expanded on to get to that approach since it's fairly surgical in nature. A broader useful pattern that could be more integrated would be necessary if we wanted to broadly apply protection from untrusted HTML.

Ultimately my recommendation would be to perform HTML escaping at the consumer level prior to applying Pharos for rendering components, whether server-side or in other client-side code.

@ymouzakis
Copy link
Contributor Author

@daneah Sounds reasonable to me. My thinking was to fix it here rather than depending on each consumer to clean HTML, but I hear where you're coming from.

@brentswisher
Copy link
Contributor

@daneah I agree that this pattern of using a library to manually sanitize HTML is generally problematic and isn't a pattern we want to adopt. I do however wonder if there is a middle ground here.

To your point about consumers being responsible for escaping content, many modern frontend frameworks (React, Vue) do provide built-in escaping of HTML to prevent XSS out of the box, and don't make it a responsibility of their consumer. Content is made safe by default and something like dangerouslySetInnerHTML is required if you want to pass it in and not have it be escaped. I'm curious if Lit does that as well?

From what I remember from the report which surfaced this, the same content that is causing issues in the Toast is displayed elsewhere on the page via Pharos components without the potential XSS, which makes me think it might. (@michael-iden does that sound right?)

From what I can tell, this instance in the Toast component is the only place in the codebase that the element.innerHTML function is used to set the content directly. Perhaps if we were to refactor it to use the normal output methods of Lit like the other components, we could get Lit's default handling of content, without needing to manually sanitize the output?

I haven't had a chance to look into it to verify my assumptions, but I'm curious if that makes any sense to you and is worth looking into?

@daneah
Copy link
Member

daneah commented Oct 1, 2024

@brentswisher good points and yes, I think that would be worth looking into! I am remembering some strife with using slots here, but as usual the details have been lost to the annals of time in my brain 😓

@ymouzakis
Copy link
Contributor Author

Right now the effort to deal with this pseudo-vulnerability is not really worth it in out opinion. Maybe we can come back to this later. For now I am closing this PR.

@ymouzakis ymouzakis closed this Oct 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants