Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: ReDoS in cookie pair regexp #94

Closed
wants to merge 1 commit into from
Closed

Conversation

grnd
Copy link

@grnd grnd commented Sep 21, 2017

Limiting whitespaces to 512. While the RFC does not specify a limit on number of whitespace in key, it's unreasonable to have thousands of them.

Limiting whitespaces to 512. While the RFC does not specify a limit on number of whitespace in key, it's unreasonable to have thousands of them.
@salesforce-cla
Copy link

Thanks for the contribution! Before we can merge this, we need @grnd to sign the Salesforce Contributor License Agreement.

@grnd
Copy link
Author

grnd commented Sep 21, 2017

That test was failing before the change. will look into that, and add one for the ReDoS as well

@inikulin
Copy link
Contributor

inikulin commented Sep 21, 2017

@grnd test fails due to abarth/http-state#18. We just need to update it.

@YevhenLukomskyi YevhenLukomskyi mentioned this pull request Sep 21, 2017
@inikulin
Copy link
Contributor

@grnd Have you signed CLA?

@@ -58,7 +58,7 @@ var CONTROL_CHARS = /[\x00-\x1F]/;
// (see: https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/parsed_cookie.cc#L60)
// '=' and ';' are attribute/values separators
// (see: https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/parsed_cookie.cc#L64)
var COOKIE_PAIR = /^(([^=;]+))\s*=\s*([^\n\r\0]*)/;
var COOKIE_PAIR = /^(([^=;]+))\s{0,512}=\s*([^\n\r\0]*)/;
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be nice to leave a comment for future generations about why we need this limitation.

Copy link
Contributor

Choose a reason for hiding this comment

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

And we need a regression test for this.

Copy link

Choose a reason for hiding this comment

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

It looks like trim() is called on the captured key/val anyways, so why bother with the \s* altogether? It's already in the capture group [^=;].

Copy link

Choose a reason for hiding this comment

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

Also, note that LOOSE_COOKIE_PAIR seems to have the same problematic pattern.

@@ -58,7 +58,7 @@ var CONTROL_CHARS = /[\x00-\x1F]/;
// (see: https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/parsed_cookie.cc#L60)
// '=' and ';' are attribute/values separators
// (see: https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/parsed_cookie.cc#L64)
var COOKIE_PAIR = /^(([^=;]+))\s*=\s*([^\n\r\0]*)/;
var COOKIE_PAIR = /^(([^=;]+))\s{0,512}=\s*([^\n\r\0]*)/;
Copy link
Contributor

Choose a reason for hiding this comment

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

And we need a regression test for this.

@stewartjarod
Copy link

fixes #92

@stash-sfdc
Copy link
Contributor

For the other ReDoS, we were able to write a test that demonstrated the bug. Would be great to see that as well here. Would be good to also do a systematic review for other ReDoS sites :(

I'll spend some time on this today. @grnd if you don't want to sign the CLA I can reject this PR and develop an alternative fix. Up to you.

@alexanderbird
Copy link

alexanderbird commented Sep 21, 2017

I can't sign the CLA, but here are regression tests (adapted from the example given in issue 92 to reproduce the vulnerability) for the COOKIE_PAIR and LOOSE_COOKIE_PAIR. They fail without @grnd's fix, and pass if you apply the fix to both regexes.

@grnd, you may have already written the regression tests, but in case you didn't, feel free to use this.

.addBatch({
  "ReDoS vulnerabilities": {
    topic: function() {
      function genstr(len, chr) {
        var result = "";
        for (var i=0; i<=len; i++) {
          result = result + chr;
        }
        return result;
      }

      var NS_PER_SEC = 1e9;
      var maliciousString = "x"  + genstr(50000, ' ') + "x";

      return {
        maliciousString,
        NS_PER_SEC
      };
      this.callback();
    },
    "cookie pair regex is not vulnerable to ReDoS attacks": function(t) {
      var start = process.hrtime();
      var cookie = Cookie.parse(t.maliciousString);
      var end = process.hrtime(start);

      var elapsedSeconds = end[0] + (end[1] / t.NS_PER_SEC);
      assert.ok(elapsedSeconds < 0.25, "elapsedSeconds must be less than 0.25");
    },
    "loose cookie pair regex is not vulnerable to ReDoS attacks": function(t) {
      var start = process.hrtime();
      var cookie = Cookie.parse(t.maliciousString, { loose: true });
      var end = process.hrtime(start);

      var elapsedSeconds = end[0] + (end[1] / t.NS_PER_SEC);
      assert.ok(elapsedSeconds < 0.25, "elapsedSeconds must be less than 0.25");
    }
  }
})

@westy92
Copy link

westy92 commented Sep 21, 2017

@alexanderbird Prefer chr.repeat(len) over the custom genstr(len, chr). One string allocation vs. N.

@stash-sfdc
Copy link
Contributor

Going to close this in favor of #97. Thank you @alexanderbird @grnd @westy92

@stash-sfdc stash-sfdc closed this Sep 21, 2017
wjhsf pushed a commit that referenced this pull request Feb 8, 2024
* Winter '20 (API 47.0) prep

* 0.6.0

* use node LTS in CI

* Prerelease 0.6.1 (#98)

* 0.6.1-alpha1

* wip: synthetic shadow dep

* wip: add testEnvironment to preset

* update yargs for security alert (#90)

* update yargs for security alert

* fix test

* Bump eslint-utils from 1.3.1 to 1.4.2 (#89)

Bumps [eslint-utils](https://github.com/mysticatea/eslint-utils) from 1.3.1 to 1.4.2.
- [Release notes](https://github.com/mysticatea/eslint-utils/releases)
- [Commits](mysticatea/eslint-utils@v1.3.1...v1.4.2)

Signed-off-by: dependabot[bot] <support@github.com>

* Update input stub to support "autocomplete" property (#92)

* Update to include date-style and time-style attributes (#94)

* 0.6.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants