Skip to content
This repository has been archived by the owner on Dec 19, 2023. It is now read-only.

Fixed Cross-site Scripting #1

Merged
merged 1 commit into from Aug 20, 2020
Merged

Fixed Cross-site Scripting #1

merged 1 commit into from Aug 20, 2020

Conversation

mufeedvh
Copy link

馃搳 Metadata *

Bounty URL: https://www.huntr.dev/bounties/1-npm-x-editable

鈿欙笍 Description *

The project x-editable validated JSON string with poorly crafted Regex making it easy to bypass the validation and inject JavaScript code to achieve XSS (Cross-site Scripting).

馃捇 Technical Description *

The implemented Regex to validate JSON was so poor that it only checks whether if the string begins and ends with [ or { and their counterparts ] or }. This means you can give it a string such as []+alert(1)+[] and it will match.

Come on man why would you write a whole Regex to validate JSON semantics lol, and JavaScript's Regex match doesn't have certain expressions implemented making it even harder.

So how do we fix it? Just parse the JSON with the JavaScript function JSON.parse() and if it fails, it's not a valid JSON string.

馃悰 Proof of Concept (PoC) *

Refer: vitalets#1130

Payload used to bypass the current validation:

[]+alert(1)+[]

馃敟 Proof of Fix (PoF) *

Parse the input JSON string and if it fails, it wouldn't proceed dynamically adding it to the HTML code preventing the XSS (Cross-site Scripting) vulnerability.

if (typeof s === 'string' && s.length) {
    try {
        JSON.parse(s);
        if (safe) {
            try {
                /*jslint evil: true*/
                s = (new Function('return ' + s))();
                /*jslint evil: false*/
            } catch (e) {} finally {
                return s;
            }
        } else {
            /*jslint evil: true*/
            s = (new Function('return ' + s))();
            /*jslint evil: false*/
        }
        return s;
    } catch (e) {
        // pass
    }
}

馃憤 User Acceptance Testing (UAT)

Just added a try/catch block to check for JSON.parse() fails.

Copy link

@Mik317 Mik317 left a comment

Choose a reason for hiding this comment

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

LGTM 馃槃 馃帀

Just a note:
The author of the issue mentioned

For my site I opted to replace the new Function() call with a JSON.parse() call. This fix won't work for everybody though, as JSON.parse() is much stricter about what is and isn't allowed in a JSON string (e.g. all properties must be surrounded in double quotes and no trailing commas are allowed).

In case other will see this, I think it shouldn't anyway comport a breaking change since also the name of the function (tryParserJSON) makes clear the input should be a valid JSON, so there shouldn't be errors if people using this module had used it in the right way 馃槃

Cheers,
Mik

@mufeedvh
Copy link
Author

In case other will see this, I think it shouldn't anyway comport a breaking change since also the name of the function (tryParserJSON) makes clear the input should be a valid JSON, so there shouldn't be errors if people using this module had used it in the right way 馃槃

@Mik317 Yep exactly, the whole purpose of the function is to parse a valid JSON string, JSON.parse() / the fix does exactly what the function is intended to. It halts if the input is not a valid JSON, as it should. 馃憤

@JamieSlome JamieSlome removed the request for review from toufik-airane August 20, 2020 10:54
@JamieSlome JamieSlome merged commit 8700396 into 418sec:develop Aug 20, 2020
@huntr-helper
Copy link
Member

Congratulations mufeedvh - your fix has been selected! 馃帀

Thanks for being part of the community & helping secure the world's open source code.
If you have any questions, please respond in the comments section. Your bounty is on its way - keep hunting!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
4 participants