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

fix: XSS vulnerability in the click event of a button #14

Closed
wants to merge 3 commits into from

Conversation

dgdev1024
Copy link

@dgdev1024 dgdev1024 commented May 26, 2022

Checklist:

A cross-site-scripting vulnerability was caught in the process of posting a comment on a saved book. Upon the comment being posted to the backend, the un-sanitized comment is 'unshifted' into the comments array, which is subsequently shown in the HTML. This pull request addresses the vulnerability by using the 'replace' method to replace any portion of the new comment matching the following regular expression, /(?\<\/?.+\>)/gi, with a blank string, removing much, if not all, of the vulnerability. See lines 74 and 75 of public/client.js for the fix.

Update: There is another XSS that pops up when there are books to fetch from the database, as their titles may also be unsanitized and also contain cross-site scripting. See line 13 for that fix.

dgdev1024 added 3 commits May 26, 2022 11:36
Tidied up the HTML-sanitizing code.
- The regular expression to pick up HTML tags is now at the top of the file. (Line 2)
- When book titles are read from the database, they are first sanitized of any tags. (Line 16)
- When a book is selected and its title appears in the comment section, the title is again sanitized. (Line 36)
- When a book's comments are fetched from the database, the comments are sanitized as well. (Line 78)
@Solarc117
Copy link

I just caught this vulnerability, and was about to mention it. Nice job!

@jdwilkin4 jdwilkin4 requested a review from a team September 1, 2023 22:01
@raisedadead raisedadead changed the title Fixed XSS vulnerability in the click event of 'button.addComment', in public/client.js. fix: XSS vulnerability in the click event of a button Sep 2, 2023
@raisedadead
Copy link
Member

Hi, @freeCodeCamp/moderators

Can you help us verify the existing user stories and functionality is unchanged? If not we should be able to merge this in.

Thanks.

Copy link
Member

@ShaunSHamilton ShaunSHamilton left a comment

Choose a reason for hiding this comment

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

This does not address any XSS, as these are only client-side changes.

Also, this is a boilerplate repo - it is not in production anywhere (that this change will affect).

So, it is up to the Camper to implement XSS safety when building the API.

As for something we can do, our production example app could get an XSS patch. However, this again would need to be a server (api) solution, and should not rely on Regex. @dgdev1024 Would you be interested in opening a PR with such a change on our demo-projects repo?

Hope this is clear.

@raisedadead raisedadead closed this Sep 4, 2023
@SethFalco
Copy link
Member

SethFalco commented Sep 4, 2023

This does not address any XSS, as these are only client-side changes.

In my opinion, it's not accurate to say that being client-side means that it doesn't address an XSS vulnerability. In fact, there are libraries dedicated to this which work in the browser, like DOMPurify.

Most frontend frameworks sanitize on client-side before inserting variables too. This was also a common practice historically afaik, it's just less visible now. A benefit I can see to this is that if a malicious engineer, browser, or browser extension, were to redirect the request to fetch data from somewhere untrusted, the client will still sanitize the input.

React always sanitizes HTML unless you use the dangerouslySetInnerHTML attribute.

So, you can set HTML directly from React, but you have to type out dangerouslySetInnerHTML and pass an object with a __html key, to remind yourself that it’s dangerous.

https://legacy.reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml

Angular always sanitized HTML unless you call bypassSecurityTrustHtml.

To systematically block XSS bugs, Angular treats all values as untrusted by default. When a value is inserted into the DOM from a template binding, or interpolation, Angular sanitizes and escapes untrusted values.

https://angular.io/guide/security#angulars-cross-site-scripting-security-model

But indeed, it's a good idea to sanitize the content as early as possible on a trusted environment (i.e. the server), and using a reputable library for it.

The intricacies of HTML sanitization aren't always apparent. I just had to deal with a similar problem lately, and dealing with content that looks like HTML but isn't HTML can be a headache. For example, there is a movie called 1968 < 2018 > 2068.

Even on IMDB, it's written as 1968 2068 (< 2018 > missing) in the synopsis, likely due to poor sanitization.

"I love the movie 1968 < 2018 > 2068!".match(/(?:\<\/?.+\>)/) 
// False Positive: [ "< 2018 >" ]

Reference:

@ShaunSHamilton
Copy link
Member

@SethFalco Quite right. Thank you for pointing that out. I was not thinking along those lines and missed the potential.

I think the main issue is still:

A benefit I can see to this is that if a malicious engineer, browser, or browser extension, were to redirect the request to fetch data from somewhere untrusted, the client will still sanitize the input.

If we are at this point, then the engineer/extension could/would just remove the client-side sanitization anyway. So, having client-side sanitation helps prevent simple attacks, but the minute something malicious has access to the DOM, there is nothing a web developer can do for the victim.

Server-side sanitation just ensures one man's vulnerability doesn't become everyone's vulnerability.

@SethFalco
Copy link
Member

If we are at this point, then the engineer/extension could/would just remove the client-side sanitization anyway.

Valid, I'll concede. ^-^'

The objective was just to pick at the wording. I was wary a learner's takeaway from the comment might be that XSS can never be resolved with a client-side fix, while a lot of effort is actually put into doing just that.

Just to clarify, I entirely agree with your proposed changes.

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.

5 participants