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

Document or fix possible XSS vulnerability (via jquery) #661

Open
JesseDahl opened this issue May 24, 2018 · 43 comments
Open

Document or fix possible XSS vulnerability (via jquery) #661

JesseDahl opened this issue May 24, 2018 · 43 comments
Labels

Comments

@JesseDahl
Copy link

bootbox.confirm and alert use jquery's .html() (and other functions) that add content to html elements. These are a potential XSS security issue since jquery evaluates the content.

Here's a working example (scroll down to the bottom of the JS window for the example code, I just borrowed somebody's fiddle and modified)
https://jsfiddle.net/93sk1zeh/2/

Pass in the following string to the text input field

<script>alert('HELLO WORLD')</script>

it should show 3 separate alert boxes (which verifies it can potentially be used for XSS attacks).

I think there's two options:

  1. Sanitize input before adding it to a DOM element using jquery, or build up the element in a safe manner (i'm not 100% sure the right way to do that just yet tbh)
  2. Mention in the documentation the potential danger of passing in user-submitted data as the first parameter to bootbox.confirm() and bootbox.alert(), or, if using an object instead of a string message, as the title property. This way it's clear the library user is responsible for sanitizing any input that might be used with bootbox.
@tiesont
Copy link
Member

tiesont commented May 24, 2018

I suppose I can see your point, although taking input from a user and then (safely) using it in a call to Bootbox as dialog content seems like something that's the responsibility of the developer, not this library.

I'll look into whether it's relatively easy to add something to sanitize message and title content, but I a) really don't want to write that myself, and b) really dislike adding another dependency to Bootbox.

@JesseDahl
Copy link
Author

Yeah I get that.

Maybe just a quick note in the docs about sanitizing your inputs before passing it in to bootbox?

@tiesont
Copy link
Member

tiesont commented May 25, 2018

The bootboxjs website is generated from the gh-pages branch, so if you would like to take a crack at that, I'd be happy to review a pull-request. Otherwise, it may be a little while before I get to something like that - what little free-time I have to work on projects like this has been spent trying to get the v5x branch ready for becoming the master branch.

@JesseDahl
Copy link
Author

oh yeah, didn't know the docs were on github too. i'll take a crack at it.

@yonjah
Copy link

yonjah commented Aug 21, 2018

I'm not sure if this is very hard to fix but I think the current implementation is useful in many cases.
So from a user perspective I want to still be able to show a dialog with HTML elements inside.

From implementation perspective all that needs to be done is to use .text method instead of .html
And I think you can add a constructor called like Bootbox.Unsafe that if provided for message or title will be entered into the DOM using the html method. So unless user wraps the strings in this object explicitly the data will be parsed as text only.

If it sounds reasonable I can probably try to submit a pull request

@tiesont
Copy link
Member

tiesont commented Aug 21, 2018

@yonjah I'm not entirely sure I understand what you're suggesting.

I won't be changing the internals to use text() instead of html() - that would break most of the existing functionality, since the message and title options have always allowed HTML.

I'd have to reiterate my previous statement: sanitizing content seems out of scope for this plugin. If I can get 5.0 squared away and pushed to master, maybe I could think about adding an option to allow a sanitizer to be passed in - that would allow devs to sanitize content, without having another large chunk of code for me to maintain.

@yonjah
Copy link

yonjah commented Aug 21, 2018

@tiesont Using text() method by default seem like the best fix to this problem.
But it is indeed a breaking change.

I wouldn't bother with implementing any solution that can't be activated by default since users will need to know to activate it. So it's not much better than changing the documentation and let users decide how they want to handle this issue.

@yonjah
Copy link

yonjah commented Aug 22, 2018

BTW it seem like SweetAlert decided to solve this issue by offering a content property
Which will contain an actual element to be injected into the dialog -
t4t5/sweetalert#845
It's also have the extra benefit of allowing easier integration with UI frameworks

@vedmant
Copy link

vedmant commented Jun 24, 2019

This makes problem as this package is reported as not secure by https://snyk.io/vuln/SNYK-JS-BOOTBOX-174704 . So there is no way to fix it without breaking existing projects? Then maybe major version bump?

@JesseDahl
Copy link
Author

@vedmant
you just need to make sure you pass your input through a sanitizer before passing it into this library.

@tiesont
Copy link
Member

tiesont commented Jun 24, 2019

@vedmant "fix it" implies that something is broken. I think I've made it clear that I don't consider this a "bug" or problem with Bootbox, in spite of whatever external sites want to claim. If not, well, here it is:

I don't consider sanitizing the content that gets passed to the message option as in-scope for Bootbox, and it's been a feature for quite some time to allow HTML to be be passed in, allowing messages shown by bootbox.alert(), bootbox.confirm(), and bootbox.prompt() to have formatted text. It's not up to bootbox to decide if a programmer has a valid use or not to inject a <script> tag, which in and of itself is not malicious - it's whatever code it contains and what the intent was that matters.

@vedmant
Copy link

vedmant commented Jun 25, 2019

@JesseDahl @tiesont I don't have security concerns here, the issue is that Snyk is reporting this package as not safe. Which required to manually add it to Snyk ignore list on every project, which is also a bad idea as if there any real security issue then it also will be ignored and not reported.

@nullivex
Copy link

This gridlock needs to be resolved in some way, I enjoy using this package safely but cannot get a clean build without getting dirty :(

@tiesont
Copy link
Member

tiesont commented Jul 17, 2019

@nullivex I hope this doesn't come across poorly, as there's no malicious intent behind it, but I'm not terribly concerned about what external sites report about this library. Bootbox works the way it does by intent, allowing users to have formatted text in their messages (which is no different than normal Bootstrap modals). I'm not going to change the default behavior and force users to enable HTML via an option, which is probably what I would have to do to make HackerOne et al happy.

It's always an option to fork this library, make that change, and create a new npm package, if someone really wanted to use Bootbox without warnings, but I'm not interested in doing so at the moment. Granted, I'm not the owner of this package, but since @makeusabrew hasn't been seen in a while, the most active collaborator (which seems to be me) pretty much becomes the de facto decision maker.

As a note, there is a recent fork that possibly has fixed some of these issues, found here: https://github.com/lddubeau/bootprompt - you may want to investigate if that works better. At the least, no one has filed a vulnerability report on that package yet, so you wouldn't get the warnings you're seeing here.

@nullivex
Copy link

nullivex commented Jul 17, 2019

@tiesont Thanks for getting back to me. I appreciate the time you took and sorry to bother you in the first place. I understand that life was all good until a security researcher decided something arbitrarily bad could happen when this library is used improperly. (Typically my thumb hurts after hitting it with a hammer so I think you are completely in the right!) Rather than continue to prod you over this and try to push you a direction you would rather not go. I would like to ask what you would see as a fitting solution to this issue? It could be important for other projects. I think you have ran into a reasonable disagreement with the security research done. I agree with your stance and wish the advisory could be adjusted personally. That being said. I would not mind hearing your opinion.

I hope this finds you well!

@tiesont
Copy link
Member

tiesont commented Jul 17, 2019

@nullivex I wouldn't call it "bothering" me. I understand that having that warning on the package is a problem for some users, but there's not a whole lot I can do about it. Someone decided that this small(ish) library needs to act the same way as a large framework like React, so now it's seen an issue.

As I noted, using bootprompt might a option - it's Bootbox ported to TypeScript, plus whatever changes that author has made since then. I did a quick scan, and it doesn't seem to use the html() function, which seems to be what all the fuss is about.

There are also other packages that have ported Bootbox to be jQuery-free, so that it can used in frameworks like Angular (I think one was called ng-bootbox, but it's been a bit since I last looked), so if you're using something like React or Angular, you might want to investigate those options.

I have thought about looking into what Bootstrap uses internally, since I think they have some form of HTML sanitizing built into their JavaScript components, if I recall correctly. I know that I don't have the requisite knowledge to build my own sanitizer, and there isn't much of a point of introducing an external dependency (developers can do that themselves, after all) if I were to rely on some other library (other than Bootstrap) to sanitize content.

@tiesont
Copy link
Member

tiesont commented Jul 17, 2019

Bootstrap's sanitizer functions (https://github.com/twbs/bootstrap/blob/master/js/src/util/sanitizer.js) seem fairly straight-forward, but none of these functions are part of it's public API. I suppose I could pull the code from that file into this project, but that would require manually updating the functions whenever Bootstrap fixes something. I'll consider it, but not promising anything.

@tarlepp Thoughts?

@tarlepp
Copy link
Collaborator

tarlepp commented Aug 18, 2019

Using that bootstrap sanitizer would be nice addition, although using it won't solve all possible attacks with inputs (eg. SQL injections, etc.) - We cannot know how those input data are used in backend side and that isn't something that bootstrap/bootbox itself should do.

@tiesont
Copy link
Member

tiesont commented Aug 18, 2019

I've pinned this issue, to make it easier to find (and hopefully reduce duplicate issues being raised).

@tarlepp
Copy link
Collaborator

tarlepp commented Aug 18, 2019

And imho this issue is not solved yet, so it should not be closed one - there is some improvements that could be done to bootbox side for this.

@tiesont tiesont reopened this Aug 18, 2019
@yonjah
Copy link

yonjah commented Aug 19, 2019

it won't solve all possible attacks with inputs (eg. SQL injections, etc.)

@tarlepp could you elaborate on this point
As far as I know bootbox only injects input into the DOM so it make sense to handle input in a safe manner preventing XSS and DOM related injections.
Does bootbox send SQL queries with inputs? if not how can it cause SQL injections ?

BTW as implemented in #699 the fix desn't require any sanitation and allows to keep the exact same functionality with a minor API change

@yonjah
Copy link

yonjah commented Aug 19, 2019

@tiesont fair enough

@NAMSGithub
Copy link

NAMSGithub commented Feb 25, 2021

Hi all,

Forgive me if this is a noob question, but doesn't dev tools give the ability to execute arbitrary javascript code on a page in the same way that this bootbox "vulnerability" gives? Sure, maybe a malicious user can inject code into the bootbox callback, but then it's still running frontend code which we already know is manipulable by the user.

If this ability to execute code gives malicious users a route to cause arbitrary code to be executed for anyone other than themselves, then I definitely want to fill in the gaps in my understanding.

Ryan

@JesseDahl
Copy link
Author

JesseDahl commented Feb 25, 2021

It could be a "stored XSS" type of attack. Some malicious user enters some value that gets stored in the backend. Then later some other user accesses some record or piece of information, and that stored bit of xss payload gets loaded into the app and into bootbox somehow.

In this case the user input is indirect and stored on the backend first before becoming a problem.

@GitRon
Copy link

GitRon commented Sep 1, 2021

Is there any update on the topic? My pipeline warns about this XSS issue and it's not fixable for me. If it's not an issue, maybe this can be sorted out with the security repo to remove the warning there?

@tiesont
Copy link
Member

tiesont commented Sep 5, 2021

@GitRon It's still an issue in that the notice isn't going to go away unless we change the internals of Bootbox to not use jQuery's .html() function or introduce an internal sanitizer. I'm not doing either anytime soon, as mentioned above and in related issues.

If you're never going to use HTML in your messages or titles, you can fork this repo and replace any uses of .html() with respect to the message and title options, which would probably let your fork pass whatever tool was used to determine Bootbox is vulnerable to injection.

@gberaudo
Copy link

gberaudo commented Nov 26, 2021

@tiesont, what about having bootbox accept a user provider sanitizer function, like prototyped in https://github.com/makeusabrew/bootbox/compare/master...gberaudo:accept_global_sanitizer?expand=1.
This would:

  • be opt-in (so no breaking change);
  • guarantee all usages of bootbox go through the sanitizer (no developer mistake).

Let me know if it is an acceptable approach and I will create a proper PR.

@tiesont
Copy link
Member

tiesont commented Nov 28, 2021

@tiesont, what about having bootbox accept a user provider sanitizer function, like prototyped in https://github.com/makeusabrew/bootbox/compare/master...gberaudo:accept_global_sanitizer?expand=1. This would:

@gberaudo That's been suggested before, but doesn't really solve the problem, at least as far as these "scan this project for issues" sites are concerned. There's nothing stopping anyone from running user input from an external sanitizer already (which seems like a completely rational solution). I suppose it would be a little less work from a developer's standpoint - supply an sanitizer, then all future values are cleaned automatically. But then again, that's solvable with a global helper function, so...

The core of the issue is that there seems to be an expectation that our small library, which has been around a while and was never built to be used in the context of things like React, should provide the same sort of "protect me from myself" functionality that much larger libraries do. I don't have the time or inclination to support an embedded sanitizing function, nor does @tarlepp. Since we're pretty much it as far as active collaborators, well, you get what we're okay with supporting.

If we ever decide to do a Bootbox 6, sure, I'll make sure that there's a way to define a sanitizer (and provide some sort of basic cleaning), but that's a project for next year, maybe...

@gberaudo
Copy link

Thanks for your reply @tiesont. I have double checked the discussion in this thread and I did not see where a similar proposition has been made before. Maybe it was proposed in another place? If you have a pointer to it, I would appreciate it because I really like to understand the situation here.

So far, I get that you want:

  • no breaking changes (which is fair);
  • no undue maintenance burden (writing an internal sanitizer function is a no-go).
    Also you don't care about bootbox being flagged as "unsafe" by companies like Snyk.

I am completly aligned with what you wrote, it is fair and reasonable to me. That is why I proposed a solution that has the merits of:

  • closing this issue;
  • being easy to implement and maintain;
  • being opt-in, no breaking change;
  • being flexible (use or not a sanitizer function, choose the one you like, implement your own, ...);
  • addressing the problem of unsafe usage of the lib: as soon as a sanitizer is defined, all subsequent usages of bootbox will be secure which is a great step forwards for me and my team, making us confident to press the "I know what I am doing button and whitelist this library".

That is as far as I can go to try to explain and convince you that the current issue is addressable upstream in a sane way.
Thanks for the great discussions and have a good day.

@MGeurts
Copy link

MGeurts commented Mar 4, 2024

More than 2 years later, still a warning during npm update

`# npm audit report

bootbox *
Severity: moderate
Bootbox.js Cross Site Scripting vulnerability - GHSA-m4ch-4m5f-2gp6
No fix available
node_modules/bootbox

1 moderate severity vulnerability

Some issues need review, and may require choosing
a different dependency.`

john-aws added a commit to awslabs/aws-js-s3-explorer that referenced this issue Mar 6, 2024
Escape the text input from bootbox prompt.

Related: [bootbox/issues/661](bootboxjs/bootbox#661)
@MakarMS
Copy link

MakarMS commented Mar 12, 2024

Hey, everybody. The problem there is that the library uses jQuery's append() to add a modal window to the container. Jquery in turn, analyzes the beginning <script> tags to decide how exactly to add the element, as a new <script> or as a string of html.

at eval (<anonymous>)
at Function.globalEval (jquery-2.1.1.min.js:2:2536)
at n.fn.init.domManip (jquery-2.1.1.min.js:3:17163)
at n.fn.init.append (jquery-2.1.1.min.js:3:14846)
at p.dialog (bootbox.min.js:6:7084)
at HTMLAnchorElement.<anonymous> (webmaster.js?rev=1710247087:341:17)
at HTMLDocument.dispatch (jquery-2.1.1.min.js:3:6404)
at r.handle (jquery-2.1.1.min.js:3:3179)`

@tiesont
Copy link
Member

tiesont commented Mar 12, 2024

Hey, everybody. The problem there is that the library uses jQuery's append() to add a modal window to the container. Jquery in turn, analyzes the beginning <script> tags to decide how exactly to add the element, as a new <script> or as a string of html.

at eval (<anonymous>)
at Function.globalEval (jquery-2.1.1.min.js:2:2536)
at n.fn.init.domManip (jquery-2.1.1.min.js:3:17163)
at n.fn.init.append (jquery-2.1.1.min.js:3:14846)
at p.dialog (bootbox.min.js:6:7084)
at HTMLAnchorElement.<anonymous> (webmaster.js?rev=1710247087:341:17)
at HTMLDocument.dispatch (jquery-2.1.1.min.js:3:6404)
at r.handle (jquery-2.1.1.min.js:3:3179)`

Yeah... no. That's not really the issue. This is: https://security.snyk.io/vuln/SNYK-JS-BOOTBOX-174704

@MakarMS
Copy link

MakarMS commented Mar 12, 2024

Hey, everybody. The problem there is that the library uses jQuery's append() to add a modal window to the container. Jquery in turn, analyzes the beginning <script> tags to decide how exactly to add the element, as a new <script> or as a string of html.

at eval (<anonymous>)
at Function.globalEval (jquery-2.1.1.min.js:2:2536)
at n.fn.init.domManip (jquery-2.1.1.min.js:3:17163)
at n.fn.init.append (jquery-2.1.1.min.js:3:14846)
at p.dialog (bootbox.min.js:6:7084)
at HTMLAnchorElement.<anonymous> (webmaster.js?rev=1710247087:341:17)
at HTMLDocument.dispatch (jquery-2.1.1.min.js:3:6404)
at r.handle (jquery-2.1.1.min.js:3:3179)`

Yeah... no. That's not really the issue. This is: https://security.snyk.io/vuln/SNYK-JS-BOOTBOX-174704

There are two issues here. One with user input, which was described at the beginning of the issue, and the second XSS one, which I described above, it is related to the use of unsafe jQuery functions. In particular, append() with its internal implementation. And as far as I understand, if we replace append() with something else, the problem in general will go away, because it is through it that the modal is added to the container. For example: $(options.container).append(dialog);

@tiesont
Copy link
Member

tiesont commented Mar 12, 2024

Hey, everybody. The problem there is that the library uses jQuery's append() to add a modal window to the container. Jquery in turn, analyzes the beginning <script> tags to decide how exactly to add the element, as a new <script> or as a string of html.

at eval (<anonymous>)
at Function.globalEval (jquery-2.1.1.min.js:2:2536)
at n.fn.init.domManip (jquery-2.1.1.min.js:3:17163)
at n.fn.init.append (jquery-2.1.1.min.js:3:14846)
at p.dialog (bootbox.min.js:6:7084)
at HTMLAnchorElement.<anonymous> (webmaster.js?rev=1710247087:341:17)
at HTMLDocument.dispatch (jquery-2.1.1.min.js:3:6404)
at r.handle (jquery-2.1.1.min.js:3:3179)`

Yeah... no. That's not really the issue. This is: https://security.snyk.io/vuln/SNYK-JS-BOOTBOX-174704

There are two issues here. One with user input, which was described at the beginning of the issue, and the second XSS one, which I described above, it is related to the use of unsafe jQuery functions. In particular, append() with its internal implementation. And as far as I understand, if we replace append() with something else, the problem in general will go away, because it is through it that the modal is added to the container. For example: $(options.container).append(dialog);

The issue I linked to above is what generates the "unsafe" warning on the npm package, and it specifically calls out not sanitizing user input as the issue. What you're describing is something that Bootstrap does when we call it's modal() function.

Ignoring all that... what happens is not really relevant. A PR that closes the exploit without changing the behavior of Bootbox is relevant. Anything else is noise and not really helping.

@MakarMS
Copy link

MakarMS commented Mar 12, 2024

Hey, everybody. The problem there is that the library uses jQuery's append() to add a modal window to the container. Jquery in turn, analyzes the beginning <script> tags to decide how exactly to add the element, as a new <script> or as a string of html.

at eval (<anonymous>)
at Function.globalEval (jquery-2.1.1.min.js:2:2536)
at n.fn.init.domManip (jquery-2.1.1.min.js:3:17163)
at n.fn.init.append (jquery-2.1.1.min.js:3:14846)
at p.dialog (bootbox.min.js:6:7084)
at HTMLAnchorElement.<anonymous> (webmaster.js?rev=1710247087:341:17)
at HTMLDocument.dispatch (jquery-2.1.1.min.js:3:6404)
at r.handle (jquery-2.1.1.min.js:3:3179)`

Yeah... no. That's not really the issue. This is: https://security.snyk.io/vuln/SNYK-JS-BOOTBOX-174704

There are two issues here. One with user input, which was described at the beginning of the issue, and the second XSS one, which I described above, it is related to the use of unsafe jQuery functions. In particular, append() with its internal implementation. And as far as I understand, if we replace append() with something else, the problem in general will go away, because it is through it that the modal is added to the container. For example: $(options.container).append(dialog);

The issue I linked to above is what generates the "unsafe" warning on the npm package, and it specifically calls out not sanitizing user input as the issue. What you're describing is something that Bootstrap does when we call it's modal() function.

Ignoring all that... what happens is not really relevant. A PR that closes the exploit without changing the behavior of Bootbox is relevant. Anything else is noise and not really helping.

Apparently a new warning needs to be added to make you pay attention to this 😄 I can't understand what bootstrap has to do with it, if it's not the bootstrap that handles content insecurely, but the bootbox, passing data directly to append() from jQuery, which knows how to handle <script> tags and execute code in them. In older versions via eval, in newer ones via adding a new <script> element, with attributes cloned in the DOM, and including ajax resolves the url inside scr itself. If you don't want to change the bootbox logic, then do the same, but after .replace(/</g, '&lt;').replace(/>/g, '&gt;') for content and the problem will be solved. 6 years have passed since the issue was opened)

@tiesont
Copy link
Member

tiesont commented Mar 12, 2024

Apparently a new warning needs to be added to make you pay attention to this

I am fully aware of the warning. Neither I nor @tarlepp has deemed it necessary to completely rewrite Bootbox just to fix something that users of the library can easily mitigate themselves.

after .replace(/</g, '<').replace(/>/g, '>') for content and the problem will be solved.

There's a lot more that goes into correctly sanitizing HTML than just encoding some brackets. There are plenty of OWASP articles discussing this.

@davidvandertuijn
Copy link

CVE-2023-46998

@Miras4207
Copy link

Solution in our case was to use audit-ci to ignore this specific warning. There should be other alternatives available if this doesn't suite you.

It seems to me that people care about this issue only because of the warning in CI. Therefore ignoring it may be the way to go as far as you sanitise the content.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.