Skip to content

Commit

Permalink
Merge pull request from GHSA-cr84-xvw4-qx3c
Browse files Browse the repository at this point in the history
* Test polynomial backtracking ReDoS attack string on Bash

Create a unit test for a (new) ReDoS string on bash. This test should be
failing in this commit.

* Fix ReDoS (as seen in ReDoS test 1) for bash

Update bash escaping to pessimistically escape opening curly braces,
similar to Zsh escaping, to fix the ReDoS due to the complex regular
expression for opening curly braces.

Update tests accordingly.

* Test against old ReDoS values and all shells

Refactor the ReDoS test such that 1) it's tested against all (supported)
shells, and 2) extensible to test against multiple potential ReDoS
strings. Regarding the latter, the scope has been updated to include
known ReDoS strings related to CVE-2022-36064.

The `redos` value is intentionally a function as this avoids building
the string unnecessarily if the file is imported but the `redos` value
isn't used.

* Update SECURITY.md

Add latest advisory and credit its finder
  • Loading branch information
ericcornelissen authored Oct 25, 2022
1 parent ec0b41b commit 552e8ea
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 15 deletions.
19 changes: 11 additions & 8 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,21 @@ report this publicly. For example, as a regular issue in the public repository.

## Advisories

| ID | Date | Affected versions | Patched versions |
| :--------------- | :--------- | :---------------- | :--------------- |
| `CVE-2021-21384` | 2021-03-19 | `<1.1.3` | `1.1.3` |
| `CVE-2022-24725` | 2022-03-03 | `>=1.4.0 <1.5.1` | `1.5.1` |
| `CVE-2022-31179` | 2022-07-26 | `<1.5.8` | `1.5.8` |
| `CVE-2022-31180` | 2022-07-26 | `>=1.4.0 <1.5.8` | `1.5.8` |
| `CVE-2022-36064` | 2022-08-29 | `>=1.5.1 <1.5.10` | `1.5.10` |
| ID | Date | Affected versions | Patched versions |
| :-------------------- | :--------- | :---------------- | :--------------- |
| `CVE-2021-21384` | 2021-03-19 | `<1.1.3` | `1.1.3` |
| `CVE-2022-24725` | 2022-03-03 | `>=1.4.0 <1.5.1` | `1.5.1` |
| `CVE-2022-31179` | 2022-07-26 | `<1.5.8` | `1.5.8` |
| `CVE-2022-31180` | 2022-07-26 | `>=1.4.0 <1.5.8` | `1.5.8` |
| `CVE-2022-36064` | 2022-08-29 | `>=1.5.1 <1.5.10` | `1.5.10` |
| `GHSA-cr84-xvw4-qx3c` | 2022-10-25 | `>=1.5.10 <1.6.1` | `1.6.1` |

## Acknowledgments

We would like to publicly thank the following reporters:

- _None yet_
- Elliot Ward ([@mowzk]) from [Snyk]

[@mowzk]: https://github.com/mowzk
[security@ericcornelissen.dev]: mailto:security@ericcornelissen.dev?subject=SECURITY%20%28shescape%29
[snyk]: https://snyk.io/
5 changes: 1 addition & 4 deletions src/unix.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,7 @@ function escapeArgBash(arg, interpolation, quoted) {
.replace(/\\/gu, "\\\\")
.replace(/\n/gu, " ")
.replace(/(^|\s)([#~])/gu, "$1\\$2")
.replace(/(["$&'()*;<>?`|])/gu, "\\$1")
.replace(/(?<!\{)\{+(?=(?:[^{][^,.]*)?[,.][^}]*\})/gu, (curlyBraces) =>
curlyBraces.replace(/\{/gu, "\\{")
)
.replace(/(["$&'()*;<>?`{|])/gu, "\\$1")
.replace(/(?<=[:=])(~)(?=[\s+\-/0:=]|$)/gu, "\\$1");
} else if (quoted) {
result = result.replace(/'/gu, `'\\''`);
Expand Down
16 changes: 13 additions & 3 deletions test/fixtures/unix.js
Original file line number Diff line number Diff line change
Expand Up @@ -1116,23 +1116,23 @@ export const escape = {
"curly brackets ('{', '}')": [
{
input: "a{b",
expected: { interpolation: "a{b", noInterpolation: "a{b" },
expected: { interpolation: "a\\{b", noInterpolation: "a{b" },
},
{
input: "a}b",
expected: { interpolation: "a}b", noInterpolation: "a}b" },
},
{
input: "a{b{c",
expected: { interpolation: "a{b{c", noInterpolation: "a{b{c" },
expected: { interpolation: "a\\{b\\{c", noInterpolation: "a{b{c" },
},
{
input: "a}b}c",
expected: { interpolation: "a}b}c", noInterpolation: "a}b}c" },
},
{
input: "a{b}c",
expected: { interpolation: "a{b}c", noInterpolation: "a{b}c" },
expected: { interpolation: "a\\{b}c", noInterpolation: "a{b}c" },
},
{
input: "a{b,c}d",
Expand Down Expand Up @@ -3601,3 +3601,13 @@ export const quote = {
],
},
};

export const redos = () => [
// CVE-2022-36064
`foo${"{".repeat(150_000)}bar`,
`=${":".repeat(150_000)}foobar`,
`{${",".repeat(150_000)}`,

// No identifier (yet)
"{,".repeat(150_000),
];
20 changes: 20 additions & 0 deletions test/unit/unix/escape.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,24 @@ Object.entries(fixtures.escape).forEach(([shellName, scenarios]) => {
});
});

fixtures.redos().forEach((s, i) => {
test(`bash, ReDoS #${i}`, (t) => {
const escape = unix.getEscapeFunction("bash");
escape(s, true, false);
t.pass();
});

test(`dash, ReDoS #${i}`, (t) => {
const escape = unix.getEscapeFunction("dash");
escape(s, true, false);
t.pass();
});

test(`zsh, ReDoS #${i}`, (t) => {
const escape = unix.getEscapeFunction("zsh");
escape(s, true, false);
t.pass();
});
});

test(macros.unsupportedShell, { fn: unix.getEscapeFunction });

1 comment on commit 552e8ea

@Tharolzakariya

This comment was marked as off-topic.

Please sign in to comment.