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

ER: Potential XSS Vulnerability in wins.js #5654

Open
2 of 5 tasks
jaasonw opened this issue Oct 3, 2023 · 13 comments
Open
2 of 5 tasks

ER: Potential XSS Vulnerability in wins.js #5654

jaasonw opened this issue Oct 3, 2023 · 13 comments
Assignees
Labels
Added to dev/pm agenda Complexity: Medium Complexity: See issue making label See the Issue Making label to understand the issue writing difficulty level Draft Issue is still in the process of being created ER Emergent Request Feature: Refactor JS / Liquid Page is working fine - JS / Liquid needs changes to become consistent with other pages Issue Making: Level 2 Make issue(s) from an ER or Epic role: front end Tasks for front end developers size: 1pt Can be done in 4-6 hours
Milestone

Comments

@jaasonw
Copy link
Member

jaasonw commented Oct 3, 2023

Emergent Requirement - Problem

I originally submitted this as a security advisory, but @roslynwythe said there isn't a way to convert it to an issue so I'm reposting it here

Original text:

Summary

The usage of innerHTML to dynamically modify DOM elements in wins.js may introduce a vulnerability to Cross-Site Scripting (XSS) attacks if wins-data.json is compromised, not properly sanitized, or not adequately vetted.

Details

The vulnerability exists on the following lines of code where DOM elements are dynamically modified using external data.

https://github.com/hackforla/website/blob/gh-pages/assets/js/wins.js#L339
https://github.com/hackforla/website/blob/gh-pages/assets/js/wins.js#L340
https://github.com/hackforla/website/blob/gh-pages/assets/js/wins.js#L498
https://github.com/hackforla/website/blob/gh-pages/assets/js/wins.js#L501
https://github.com/hackforla/website/blob/gh-pages/assets/js/wins.js#L504

To address this vulnerability, it is recommended to avoid using innerHTML and prefer safer DOM manipulation methods like createElement and textContent

Additionally, the unformatted nature of wins-data.json can make it difficult to spot changes in the file with a git diff. Consider reformatting the JSON file to be more human-readable and version control-friendly.

PoC

The vulnerability audit states that "User input strings remain strings and escape injection through decodeURIComponent()" however, in my testing this is not the case and strings parsed through decodeURIComponent() are still susceptible to XSS.
Proof of concept: https://codepen.io/jaasonw/pen/GRPBzGJ

Impact

Potential defacement of the website or visitors being subject to phishing attacks.

Issue you discovered this emergent requirement in

Date discovered

10/1/2023

Did you have to do something temporarily

  • YES
  • NO

Who was involved

@

What happens if this is not addressed

Potential defacement of the website or visitors being subject to phishing attacks.

Resources

https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement
https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent
https://medium.com/front-end-weekly/javascript-innerhtml-innertext-and-textcontent-b75ec895cbe3
https://jekyllrb.com/docs/datafiles/

Recommended Action Items

  • Make a new issue
  • Discuss with team
  • Let a Team Lead know

Potential solutions [draft]

option 1

Update code that does DOM manipulation. Instead of using innerHTML, we should update the code to use safer DOM manipulation methods like createElement and textContent

option 2
Alternatively, I noticed a lot of the data on the website is loaded in on page load with javascript rather than at build time. Seeing as we already use Jekyll, I suggest using its built-in functionality with the strip_html filter to load data into the HTML at build time statically, as this has benefits to both page load times and accessibility benefits to visitors to the site that have javascript disabled

@jaasonw jaasonw added Feature Missing This label means that the issue needs to be linked to a precise feature label. role missing size: 0.25pt Can be done in 0.5 to 1.5 hours Complexity: Medium labels Oct 3, 2023
@github-actions

This comment was marked as outdated.

@jaasonw jaasonw added role: front end Tasks for front end developers size: 1pt Can be done in 4-6 hours ready for dev lead Issues that tech leads or merge team members need to follow up on and removed role missing size: 0.25pt Can be done in 0.5 to 1.5 hours Feature Missing This label means that the issue needs to be linked to a precise feature label. labels Oct 3, 2023
@roslynwythe
Copy link
Member

roslynwythe commented Oct 16, 2023

  • Great work @jaasonw pointing out several excellent suggestions. Regarding the XSS vulnerability, would you be willing to write an issue to update wins.js? Regarding the formatting of _wins-data.json, I agree completely and have written Update wins Google Apps Script to format wins json feed #4035 for that purpose. If you have any comments on that issue, they would be welcome.

Finally regarding your suggestion to load wins data at build time rather than on page load, I will discuss that with Bonnie to see if she is interested in pursuing that. Thanks again for your contributions; we are very happy that you are on the website team!

@ExperimentsInHonesty ExperimentsInHonesty added the Feature Missing This label means that the issue needs to be linked to a precise feature label. label Oct 29, 2023
@ExperimentsInHonesty ExperimentsInHonesty added this to the 02. Security milestone Nov 6, 2023
@roslynwythe
Copy link
Member

roslynwythe commented Nov 8, 2023

@jaasonw Regarding your comment

Alternatively, I noticed a lot of the data on the website is loaded in on page load with javascript rather than at build time. Seeing as we already use Jekyll, I suggest using its built-in functionality with the strip_html filter to load data into the HTML at build time statically, as this has benefits to both page load times and accessibility benefits to visitors to the site that have javascript disabled

I wonder if you could indicate which pages load data on page load. I checked wins.js and project.js and both load data at build time using a liquid assign tag.

@jaasonw
Copy link
Member Author

jaasonw commented Nov 8, 2023

@roslynwythe Sorry, I should clarify that by "load data" I meant the actual creation of DOM elements based on the data. Currently, data is retrieved when the visitor loads the page, and client-side javascript is used to generate the DOM elements. This becomes apparent when Javascript is disabled when visiting the website. When Javascript is disabled, the following pages fail to render properly:

The events page does not display meeting times
image

Projects on the project page do not render
image

Wins on the wins page do not render
image

@ExperimentsInHonesty ExperimentsInHonesty added Feature: Refactor JS / Liquid Page is working fine - JS / Liquid needs changes to become consistent with other pages and removed Feature Missing This label means that the issue needs to be linked to a precise feature label. labels Nov 12, 2023
@roslynwythe
Copy link
Member

@jaasonw Thanks for the explanation.

We are open to the idea of using safer DOM manipulation methods like createElement and textContent in place of innerHTML. We should start with a relatively simple page, perhaps Events. We have been planning to update the code in the Events page, because meeting data is being retrieved JS via an API call to VRMS instead of using _data/external/vrms-data.json, which is obviously inefficient. So one option would be to write an issue for making both changes: using Jekyll to assign data from _data/external/vrms-data.json and also avoiding use of innerHTML in favor of the safer alternatives you mention. Or we could make those two separate issues.

But it sounds like alternatively, we could completely eliminate the JS that generates the DOM, instead using Jekyll to build the complete HTML at build time. And I assume that by using strip_html, that eliminates any risk of injection in the case that the JSON data source was corrupted?

Could you offer pros and cons for that alternative? Or should we create an issue to explore those pros and cons?

We really appreciate your contributions and look forward to working with you further on these issues.

@JessicaLucindaCheng JessicaLucindaCheng added the ER Emergent Request label Jan 26, 2024
@ExperimentsInHonesty
Copy link
Member

Make an issue to do option 1 so that we reduce vulnerability immediately and silence the warning.

Make an epic that looks into the refactoring option and identifies all the places on the site that it would be required.

This comment was marked as outdated.

@freaky4wrld
Copy link
Member

freaky4wrld commented Feb 20, 2024

@roslynwythe roslynwythe added Issue Making: Level 2 Make issue(s) from an ER or Epic Complexity: See issue making label See the Issue Making label to understand the issue writing difficulty level labels Feb 20, 2024
@roslynwythe roslynwythe removed the ready for dev lead Issues that tech leads or merge team members need to follow up on label Feb 20, 2024
@ExperimentsInHonesty
Copy link
Member

ExperimentsInHonesty commented Feb 25, 2024

@roslynwythe This ER is only partially resolved, we still need to do

Make an epic that looks into the refactoring option and identifies all the places on the site that it would be required.

@roslynwythe
Copy link
Member

@ExperimentsInHonesty
Copy link
Member

ExperimentsInHonesty commented Mar 4, 2024

@freaky4wrld I am still confused. It looks like this issues are both addressing the change of using createElement and textContent instead of innerHTML

And I what I was saying was missing was the issue or epic to do option 2 after option was complete.

Alternatively, I noticed a lot of the data on the website is loaded in on page load with javascript rather than at build time. Seeing as we already use Jekyll, I suggest using its built-in functionality with the strip_html filter to load data into the HTML at build time statically, as this has benefits to both page load times and accessibility benefits to visitors to the site that have javascript disabled

Basically, option 1 is the fast, temporary fix, option 2 is the long term solution.

So can you make the issues or epics for option 2 and we can put a dependency on them of the two above issues being complete. Or is there something else I don't understand.

@freaky4wrld
Copy link
Member

@ExperimentsInHonesty the issue #6303, is the issue for the fast and temporary fix that we require for the ER

  • the epic is aimed to do an audit, but we might not require it as @roslynwythe suggests we have full control over the html files
  • the issue is aimed to remove innerHTML with textContent and createElement where needed
  • we should discuss the scope of the epic

So can you make the issues or epics for option 2 and we can put a dependency on them of the two above issues being complete. Or is there something else I don't understand.

Yes we would be making those issues.....

@roslynwythe
Copy link
Member

roslynwythe commented Mar 8, 2024

@freaky4wrld - Bonnie is suggesting that in addition to refactoring the use of innerHTML where needed, we also write an epic to explore option 2:

Alternatively, I noticed a lot of the data on the website is loaded in on page load with javascript rather than at build time. Seeing as we already use Jekyll, I suggest using its built-in functionality with the strip_html filter to load data into the HTML at build time statically, as this has benefits to both page load times and accessibility benefits to visitors to the site that have javascript disabled

@ExperimentsInHonesty ExperimentsInHonesty added the Draft Issue is still in the process of being created label Mar 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Added to dev/pm agenda Complexity: Medium Complexity: See issue making label See the Issue Making label to understand the issue writing difficulty level Draft Issue is still in the process of being created ER Emergent Request Feature: Refactor JS / Liquid Page is working fine - JS / Liquid needs changes to become consistent with other pages Issue Making: Level 2 Make issue(s) from an ER or Epic role: front end Tasks for front end developers size: 1pt Can be done in 4-6 hours
Projects
Status: New Issue Approval
Development

No branches or pull requests

5 participants