bootbox icon indicating copy to clipboard operation
bootbox copied to clipboard

Document or fix possible XSS vulnerability (via jquery)

Open JesseDahl opened this issue 6 years ago • 45 comments

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

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.

JesseDahl avatar May 24 '18 01:05 JesseDahl

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.

tiesont avatar May 24 '18 02:05 tiesont

Yeah I get that.

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

JesseDahl avatar May 24 '18 16:05 JesseDahl

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.

tiesont avatar May 25 '18 03:05 tiesont

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

JesseDahl avatar May 25 '18 03:05 JesseDahl

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

yonjah avatar Aug 21 '18 05:08 yonjah

@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.

tiesont avatar Aug 21 '18 05:08 tiesont

@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 avatar Aug 21 '18 06:08 yonjah

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 - https://github.com/t4t5/sweetalert/issues/845 It's also have the extra benefit of allowing easier integration with UI frameworks

yonjah avatar Aug 22 '18 01:08 yonjah

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?

vedmant avatar Jun 24 '19 15:06 vedmant

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

JesseDahl avatar Jun 24 '19 20:06 JesseDahl

@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.

tiesont avatar Jun 24 '19 20:06 tiesont

@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.

vedmant avatar Jun 25 '19 05:06 vedmant

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

nullivex avatar Jul 17 '19 20:07 nullivex

@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.

tiesont avatar Jul 17 '19 20:07 tiesont

@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!

nullivex avatar Jul 17 '19 20:07 nullivex

@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 avatar Jul 17 '19 20:07 tiesont

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?

tiesont avatar Jul 17 '19 21:07 tiesont

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.

tarlepp avatar Aug 18 '19 11:08 tarlepp

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

tiesont avatar Aug 18 '19 19:08 tiesont

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.

tarlepp avatar Aug 18 '19 20:08 tarlepp

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 avatar Aug 19 '19 01:08 yonjah

@yonjah Minor API change, yes. Major change in functionality, also yes, and I'm not okay with that.

@tarlepp was just making a point that user input should never be trusted implicitly - Bootbox doesn't do anything that involves back-end code.

tiesont avatar Aug 19 '19 01:08 tiesont

@tiesont what is the major functionality change introduced in #699 ?

@tarlepp was just making a point that user input should never be trusted implicitly - Bootbox doesn't do anything that involves back-end code.

So if it only handles the DOM I would say this is the only kind of injections we should worry about.

yonjah avatar Aug 19 '19 01:08 yonjah

@yonjah Making HTML rendering (for the various options which currently allow it) require an extra step, rather than the default behavior, is a major difference, IMO, which is the majority of what your pull-request does. Anyone who's okay with adding something like

$('<b>Hello World!</b>')

as their message option should be capable of using

$('<b>Hello World!</b>').sanitize() // assuming some external sanitizing library or function

tiesont avatar Aug 19 '19 02:08 tiesont

@tiesont so from functionality perspective there is no issue the only change is API change -

bootbox.alert('<b>Hello World!</b>'); //Old API
bootbox.alert($('<b>Hello World!</b>')); //new API

Functionality is identical in both cases.

I agree that from API change adding some sanitize call when you need the HTML functionality might not be an issue but it probably wont solve the security issue. It will introduce the exact functionality change you are trying to prevent and when you don't need it it can be a major pain -

bootbox.alert(`Hello ${user.name}`);
bootbox.alert(request.error);

This examples are safe to use after the API change but are completely vulnerable with the current API. if the API expect a call to some sanitize function before passing the input in it will still be vulnerable.

yonjah avatar Aug 19 '19 02:08 yonjah

@yonjah I think we'll have to agree to disagree. I respect your input and value the time you've put into this, but I don't agree with the changes you want to make, so I won't be pulling them in.

tiesont avatar Aug 19 '19 03:08 tiesont

@tiesont fair enough

yonjah avatar Aug 19 '19 03:08 yonjah

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

NAMSGithub avatar Feb 25 '21 20:02 NAMSGithub

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.

JesseDahl avatar Feb 25 '21 23:02 JesseDahl

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?

GitRon avatar Sep 01 '21 11:09 GitRon