diff --git a/.gitignore b/.gitignore index a4204f449..9b15d9da2 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ tests/output .vscode/ deploy/smithy/chart/charts .idea/ +components/consumers/pdf/report.html diff --git a/components/producers/checkov/main.go b/components/producers/checkov/main.go index 7138901f2..621944de9 100644 --- a/components/producers/checkov/main.go +++ b/components/producers/checkov/main.go @@ -51,7 +51,7 @@ func run(inFile []byte, target string) error { func handleSarif(inFile []byte) ([]*smithyv1.Issue, error) { var sarifResults []*sarif.SmithyIssueCollection var smithyResults []*smithyv1.Issue - sarifResults, err := sarif.ToSmithy(string(inFile)) + sarifResults, err := sarif.ToSmithy(string(inFile), sarif.ExtraContextLanguageUnspecified) if err != nil { return smithyResults, err } diff --git a/components/producers/checkov/main_test.go b/components/producers/checkov/main_test.go index f9b40e178..709093770 100644 --- a/components/producers/checkov/main_test.go +++ b/components/producers/checkov/main_test.go @@ -43,19 +43,19 @@ func TestRunSarif(t *testing.T) { require.NoError(t, err) expectedIssues := []*smithyv1.Issue{ { - Target: "code/cfngoat/cfngoat.yaml:891-892", + Target: "file://code/cfngoat/cfngoat.yaml:891-892", Type: "CKV_SECRET_6", Title: "Base64 High Entropy String", Severity: smithyv1.Severity_SEVERITY_HIGH, Description: "MatchedRule: {\"id\":\"CKV_SECRET_6\",\"name\":\"Base64 High Entropy String\",\"shortDescription\":{\"text\":\"Base64 High Entropy String\"},\"fullDescription\":{\"text\":\"Base64 High Entropy String\"},\"defaultConfiguration\":{\"level\":\"error\"},\"help\":{\"text\":\"Base64 High Entropy String\\nResource: c00f1a6e4b20aa64691d50781b810756d6254b8e\"}} \n Message: Base64 High Entropy String", }, { - Target: "code/cfngoat/.github/workflows/checkov.yaml:1-1", + Target: "file://code/cfngoat/.github/workflows/checkov.yaml:1-1", Type: "CKV2_GHA_1", Title: "Ensure top-level permissions are not set to write-all", Severity: smithyv1.Severity_SEVERITY_HIGH, Description: "MatchedRule: {\"id\":\"CKV2_GHA_1\",\"name\":\"Ensure top-level permissions are not set to write-all\",\"shortDescription\":{\"text\":\"Ensure top-level permissions are not set to write-all\"},\"fullDescription\":{\"text\":\"Ensure top-level permissions are not set to write-all\"},\"defaultConfiguration\":{\"level\":\"error\"},\"help\":{\"text\":\"Ensure top-level permissions are not set to write-all\\nResource: on(build)\"}} \n Message: Ensure top-level permissions are not set to write-all", }, { - Target: "code/cfngoat/.github/workflows/main.yaml:1-1", + Target: "file://code/cfngoat/.github/workflows/main.yaml:1-1", Type: "CKV2_GHA_1", Title: "Ensure top-level permissions are not set to write-all", Severity: smithyv1.Severity_SEVERITY_HIGH, diff --git a/components/producers/docker-trivy/main.go b/components/producers/docker-trivy/main.go index 8c21c0a77..740b7573f 100644 --- a/components/producers/docker-trivy/main.go +++ b/components/producers/docker-trivy/main.go @@ -78,7 +78,7 @@ func handleJSON(inFile []byte) ([]*v1.Issue, error) { func handleSarif(inFile []byte) ([]*v1.Issue, error) { var sarifResults []*sarif.SmithyIssueCollection var smithyResults []*v1.Issue - sarifResults, err := sarif.ToSmithy(string(inFile)) + sarifResults, err := sarif.ToSmithy(string(inFile), sarif.ExtraContextLanguageUnspecified) if err != nil { return smithyResults, err } diff --git a/components/producers/java-findsecbugs/main.go b/components/producers/java-findsecbugs/main.go index 1b1e0c259..f05aa780d 100644 --- a/components/producers/java-findsecbugs/main.go +++ b/components/producers/java-findsecbugs/main.go @@ -182,7 +182,7 @@ func main() { if err != nil { log.Fatal(err) } - sarifResults, err = sarif.ToSmithy(string(inFile)) + sarifResults, err = sarif.ToSmithy(string(inFile), sarif.ExtraContextLanguageUnspecified) if err != nil { log.Fatal(err) } diff --git a/components/producers/kics/main.go b/components/producers/kics/main.go index 38c0cb9dc..6cc2eefaa 100644 --- a/components/producers/kics/main.go +++ b/components/producers/kics/main.go @@ -32,7 +32,7 @@ func main() { if Sarif { var sarifResults []*sarif.SmithyIssueCollection var smithyResults []*v1.Issue - sarifResults, err := sarif.ToSmithy(string(inFile)) + sarifResults, err := sarif.ToSmithy(string(inFile), sarif.ExtraContextLanguageUnspecified) if err != nil { log.Fatal(err) } diff --git a/components/producers/snyk-docker/main.go b/components/producers/snyk-docker/main.go index 5414dac6b..04f01d901 100644 --- a/components/producers/snyk-docker/main.go +++ b/components/producers/snyk-docker/main.go @@ -1,6 +1,7 @@ package main import ( + "flag" "log" "log/slog" @@ -10,6 +11,8 @@ import ( ) func main() { + var producerLang string + flag.StringVar(&producerLang, "language", "", "") if err := producers.ParseFlags(); err != nil { log.Fatal(err) @@ -20,7 +23,7 @@ func main() { if err != nil { log.Fatal(err) } - results, err := processInput(string(inFile)) + results, err := processInput(string(inFile), producerLang) if err != nil { log.Fatal(err) } @@ -46,11 +49,22 @@ func writeOutput(results map[string][]*v1.Issue) error { return nil } -func processInput(input string) (map[string][]*v1.Issue, error) { - issues, err := sarif.ToSmithy(string(input)) +func processInput(input string, language string) (map[string][]*v1.Issue, error) { + var ( + issues []*sarif.SmithyIssueCollection + extraCtxLang = sarif.ExtraContextLanguageUnspecified + err error + ) + + if language != "" { + extraCtxLang = sarif.ExtraContextLanguage(language) + } + + issues, err = sarif.ToSmithy(input, extraCtxLang) if err != nil { return nil, err } + results := map[string][]*v1.Issue{} for _, output := range issues { results[output.ToolName] = append(results[output.ToolName], output.Issues...) diff --git a/components/producers/snyk-docker/main_test.go b/components/producers/snyk-docker/main_test.go index 212149227..2fa43d359 100644 --- a/components/producers/snyk-docker/main_test.go +++ b/components/producers/snyk-docker/main_test.go @@ -18,12 +18,12 @@ const inputPath = "exampleData/snyk-example.sarif" func TestProcessInput(t *testing.T) { input, err := os.ReadFile(inputPath) require.NoError(t, err) - results, err := processInput(string(input)) + results, err := processInput(string(input), "") require.NoError(t, err) expected := map[string][]*v1.Issue{ "Snyk Open Source": { { - Target: "package.json:1-1", + Target: "file://package.json:1-1", Type: "SNYK-JS-ANSIREGEX-1583908", Title: "This file introduces a vulnerable ansi-regex package with a high severity vulnerability.", Severity: v1.Severity_SEVERITY_HIGH, @@ -32,28 +32,28 @@ func TestProcessInput(t *testing.T) { Description: "MatchedRule: {\"id\":\"SNYK-JS-ANSIREGEX-1583908\",\"shortDescription\":{\"text\":\"High severity - Regular Expression Denial of Service (ReDoS) vulnerability in ansi-regex\"},\"fullDescription\":{\"text\":\"(CVE-2021-3807) ansi-regex@2.1.1\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: yarn\\n* Vulnerable module: ansi-regex\\n* Introduced through: spyros-frontend@1.0.0, react-d3-library@1.1.8 and others\\n### Detailed paths\\n* _Introduced through_: spyros-frontend@1.0.0 › react-d3-library@1.1.8 › babel-core@6.26.3 › babel-code-frame@6.26.0 › chalk@1.1.3 › strip-ansi@3.0.1 › ansi-regex@2.1.1\\n* _Introduced through_: spyros-frontend@1.0.0 › react-d3-library@1.1.8 › babel-core@6.26.3 › babel-code-frame@6.26.0 › chalk@1.1.3 › has-ansi@2.0.0 › ansi-regex@2.1.1\\n* _Introduced through_: spyros-frontend@1.0.0 › npm@7.16.0 › @npmcli/arborist@2.6.2 › @npmcli/metavuln-calculator@1.1.1 › pacote@11.3.4 › @npmcli/run-script@1.8.5 › node-gyp@7.1.2 › npmlog@4.1.2 › gauge@2.7.4 › string-width@1.0.2 › strip-ansi@3.0.1 › ansi-regex@2.1.1\\n* _Introduced through_: spyros-frontend@1.0.0 › npm@7.16.0 › @npmcli/arborist@2.6.2 › @npmcli/metavuln-calculator@1.1.1 › pacote@11.3.4 › @npmcli/run-script@1.8.5 › node-gyp@7.1.2 › npmlog@4.1.2 › gauge@2.7.4 › wide-align@1.1.3 › string-width@2.1.1 › strip-ansi@4.0.0 › ansi-regex@3.0.0\\n* _Introduced through_: spyros-frontend@1.0.0 › npm@7.16.0 › cli-table3@0.6.0 › string-width@4.2.2 › strip-ansi@6.0.0 › ansi-regex@5.0.0\\n* _Introduced through_: spyros-frontend@1.0.0 › react-scripts@5.0.0 › jest@27.4.7 › @jest/core@27.4.7 › @jest/reporters@27.4.6 › string-length@4.0.2 › strip-ansi@6.0.0 › ansi-regex@5.0.0\\n# Overview\\n\\nAffected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) due to the sub-patterns` [[\\\\\\\\]()#;?]*` and `(?:;[-a-zA-Z\\\\\\\\d\\\\\\\\/#\\u0026.:=?%@~_]*)*`.\\r\\n\\r\\n\\r\\n## PoC\\r\\n```js\\r\\nimport ansiRegex from 'ansi-regex';\\r\\n\\r\\nfor(var i = 1; i \\u003c= 50000; i++) {\\r\\n var time = Date.now();\\r\\n var attack_str = \\\"\\\\u001B[\\\"+\\\";\\\".repeat(i*10000);\\r\\n ansiRegex().test(attack_str)\\r\\n var time_cost = Date.now() - time;\\r\\n console.log(\\\"attack_str.length: \\\" + attack_str.length + \\\": \\\" + time_cost+\\\" ms\\\")\\r\\n}\\r\\n```\\n\\n# Details\\n\\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.\\n\\nThe Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.\\n\\nLet’s take the following regular expression as an example:\\n```js\\nregex = /A(B|C+)+D/\\n```\\n\\nThis regular expression accomplishes the following:\\n- `A` The string must start with the letter 'A'\\n- `(B|C+)+` The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the `+` matches one or more times). The `+` at the end of this section states that we can look for one or more matches of this section.\\n- `D` Finally, we ensure this section of the string ends with a 'D'\\n\\nThe expression would match inputs such as `ABBD`, `ABCCCCD`, `ABCBCCCD` and `ACCCCCD`\\n\\nIt most cases, it doesn't take very long for a regex engine to find a match:\\n\\n```bash\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD\\\")'\\n0.04s user 0.01s system 95% cpu 0.052 total\\n\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX\\\")'\\n1.79s user 0.02s system 99% cpu 1.812 total\\n```\\n\\nThe entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.\\n\\nMost Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as _catastrophic backtracking_.\\n\\nLet's look at how our expression runs into this problem, using a shorter string: \\\"ACCCX\\\". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:\\n1. CCC\\n2. CC+C\\n3. C+CC\\n4. C+C+C.\\n\\nThe engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use [RegEx 101 debugger](https://regex101.com/debugger) to see the engine has to take a total of 38 steps before it can determine the string doesn't match.\\n\\nFrom there, the number of steps the engine must use to validate a string just continues to grow.\\n\\n| String | Number of C's | Number of steps |\\n| -------|-------------:| -----:|\\n| ACCCX | 3 | 38\\n| ACCCCX | 4 | 71\\n| ACCCCCX | 5 | 136\\n| ACCCCCCCCCCCCCCX | 14 | 65,553\\n\\n\\nBy the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.\\n\\n# Remediation\\nUpgrade `ansi-regex` to version 3.0.1, 4.1.1, 5.0.1, 6.0.1 or higher.\\n# References\\n- [GitHub Commit](https://github.com/chalk/ansi-regex/commit/419250fa510bf31b4cc672e76537a64f9332e1f1)\\n- [GitHub Commit](https://github.com/chalk/ansi-regex/commit/75a657da7af875b2e2724fd6331bf0a4b23d3c9a)\\n- [GitHub Commit](https://github.com/chalk/ansi-regex/commit/8d1d7cdb586269882c4bdc1b7325d0c58c8f76f9)\\n- [GitHub PR](https://github.com/chalk/ansi-regex/pull/37)\\n\"},\"properties\":{\"tags\":[\"security\",\"CWE-400\",\"yarn\"]}} \n Message: This file introduces a vulnerable ansi-regex package with a high severity vulnerability.", }, { - Target: "package.json:1-1", + Target: "file://package.json:1-1", Type: "SNYK-JS-ASYNC-2441827", Title: "This file introduces a vulnerable async package with a high severity vulnerability.", Severity: v1.Severity_SEVERITY_HIGH, Description: "MatchedRule: {\"id\":\"SNYK-JS-ASYNC-2441827\",\"shortDescription\":{\"text\":\"High severity - Prototype Pollution vulnerability in async\"},\"fullDescription\":{\"text\":\"(CVE-2021-43138) async@2.6.3\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: yarn\\n* Vulnerable module: async\\n* Introduced through: spyros-frontend@1.0.0, react-scripts@5.0.0 and others\\n### Detailed paths\\n* _Introduced through_: spyros-frontend@1.0.0 › react-scripts@5.0.0 › webpack-dev-server@4.7.3 › portfinder@1.0.28 › async@2.6.3\\n# Overview\\n\\nAffected versions of this package are vulnerable to Prototype Pollution via the `mapValues()` method, due to improper check in `createObjectIterator` function.\\r\\n\\r\\n# PoC\\r\\n\\r\\n```js\\r\\n//when objects are parsed, all properties are created as own (the objects can come from outside sources (http requests/ file))\\r\\nconst hasOwn = JSON.parse('{\\\"__proto__\\\": {\\\"isAdmin\\\": true}}');\\r\\n\\r\\n//does not have the property, because it's inside object's own \\\"__proto__\\\"\\r\\nconsole.log(hasOwn.isAdmin);\\r\\n\\r\\nasync.mapValues(hasOwn, (val, key, cb) =\\u003e cb(null, val), (error, result) =\\u003e {\\r\\n // after the method executes, hasOwn.__proto__ value (isAdmin: true) replaces the prototype of the newly created object, leading to potential exploits.\\r\\n console.log(result.isAdmin);\\r\\n});\\r\\n```\\n\\n# Details\\n\\nPrototype Pollution is a vulnerability affecting JavaScript. Prototype Pollution refers to the ability to inject properties into existing JavaScript language construct prototypes, such as objects. JavaScript allows all Object attributes to be altered, including their magical attributes such as `_proto_`, `constructor` and `prototype`. An attacker manipulates these attributes to overwrite, or pollute, a JavaScript application object prototype of the base object by injecting other values. Properties on the `Object.prototype` are then inherited by all the JavaScript objects through the prototype chain. When that happens, this leads to either denial of service by triggering JavaScript exceptions, or it tampers with the application source code to force the code path that the attacker injects, thereby leading to remote code execution.\\n\\nThere are two main ways in which the pollution of prototypes occurs:\\n\\n- Unsafe `Object` recursive merge\\n \\n- Property definition by path\\n \\n\\n## Unsafe Object recursive merge\\n\\nThe logic of a vulnerable recursive merge function follows the following high-level model:\\n```\\nmerge (target, source)\\n\\n foreach property of source\\n\\n if property exists and is an object on both the target and the source\\n\\n merge(target[property], source[property])\\n\\n else\\n\\n target[property] = source[property]\\n```\\n\\u003cbr\\u003e \\n\\nWhen the source object contains a property named `_proto_` defined with `Object.defineProperty()` , the condition that checks if the property exists and is an object on both the target and the source passes and the merge recurses with the target, being the prototype of `Object` and the source of `Object` as defined by the attacker. Properties are then copied on the `Object` prototype.\\n\\nClone operations are a special sub-class of unsafe recursive merges, which occur when a recursive merge is conducted on an empty object: `merge({},source)`.\\n\\n`lodash` and `Hoek` are examples of libraries susceptible to recursive merge attacks.\\n\\n## Property definition by path\\n\\nThere are a few JavaScript libraries that use an API to define property values on an object based on a given path. The function that is generally affected contains this signature: `theFunction(object, path, value)`\\n\\nIf the attacker can control the value of “path”, they can set this value to `_proto_.myValue`. `myValue` is then assigned to the prototype of the class of the object.\\n\\n# Types of attacks\\n\\nThere are a few methods by which Prototype Pollution can be manipulated:\\n\\n| Type |Origin |Short description |\\n|--|--|--|\\n| **Denial of service (DoS)**|Client |This is the most likely attack. \\u003cbr\\u003eDoS occurs when `Object` holds generic functions that are implicitly called for various operations (for example, `toString` and `valueOf`). \\u003cbr\\u003e The attacker pollutes `Object.prototype.someattr` and alters its state to an unexpected value such as `Int` or `Object`. In this case, the code fails and is likely to cause a denial of service. \\u003cbr\\u003e**For example:** if an attacker pollutes `Object.prototype.toString` by defining it as an integer, if the codebase at any point was reliant on `someobject.toString()` it would fail. |\\n |**Remote Code Execution**|Client|Remote code execution is generally only possible in cases where the codebase evaluates a specific attribute of an object, and then executes that evaluation.\\u003cbr\\u003e**For example:** `eval(someobject.someattr)`. In this case, if the attacker pollutes `Object.prototype.someattr` they are likely to be able to leverage this in order to execute code.|\\n|**Property Injection**|Client|The attacker pollutes properties that the codebase relies on for their informative value, including security properties such as cookies or tokens.\\u003cbr\\u003e **For example:** if a codebase checks privileges for `someuser.isAdmin`, then when the attacker pollutes `Object.prototype.isAdmin` and sets it to equal `true`, they can then achieve admin privileges.|\\n\\n# Affected environments\\n\\nThe following environments are susceptible to a Prototype Pollution attack:\\n\\n- Application server\\n \\n- Web server\\n \\n\\n# How to prevent\\n\\n1. Freeze the prototype— use `Object.freeze (Object.prototype)`.\\n \\n2. Require schema validation of JSON input.\\n \\n3. Avoid using unsafe recursive merge functions.\\n \\n4. Consider using objects without prototypes (for example, `Object.create(null)`), breaking the prototype chain and preventing pollution.\\n \\n5. As a best practice use `Map` instead of `Object`.\\n\\n## For more information on this vulnerability type:\\n\\n[Arteau, Oliver. “JavaScript prototype pollution attack in NodeJS application.” GitHub, 26 May 2018](https://github.com/HoLyVieR/prototype-pollution-nsec18/blob/master/paper/JavaScript_prototype_pollution_attack_in_NodeJS.pdf)\\n\\n# Remediation\\nUpgrade `async` to version 2.6.4, 3.2.2 or higher.\\n# References\\n- [GitHub Backport PR](https://github.com/caolan/async/pull/1828)\\n- [GitHub Commit](https://github.com/caolan/async/commit/8f7f90342a6571ba1c197d747ebed30c368096d2)\\n- [GitHub Commit](https://github.com/caolan/async/commit/e1ecdbf79264f9ab488c7799f4c76996d5dca66d)\\n- [PoC](https://jsfiddle.net/oz5twjd9/)\\n\"},\"properties\":{\"tags\":[\"security\",\"CWE-1321\",\"yarn\"]}} \n Message: This file introduces a vulnerable async package with a high severity vulnerability.", }, { - Target: "package.json:1-1", + Target: "file://package.json:1-1", Type: "SNYK-JS-CSSWHAT-1298035", Title: "This file introduces a vulnerable css-what package with a medium severity vulnerability.", Severity: v1.Severity_SEVERITY_MEDIUM, Description: "MatchedRule: {\"id\":\"SNYK-JS-CSSWHAT-1298035\",\"shortDescription\":{\"text\":\"Medium severity - Regular Expression Denial of Service (ReDoS) vulnerability in css-what\"},\"fullDescription\":{\"text\":\"(CVE-2021-33587) css-what@3.4.2\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: yarn\\n* Vulnerable module: css-what\\n* Introduced through: spyros-frontend@1.0.0, react-scripts@5.0.0 and others\\n### Detailed paths\\n* _Introduced through_: spyros-frontend@1.0.0 › react-scripts@5.0.0 › @svgr/webpack@5.5.0 › @svgr/plugin-svgo@5.5.0 › svgo@1.3.2 › css-select@2.1.0 › css-what@3.4.2\\n# Overview\\n[css-what](https://www.npmjs.org/package/css-what) is an a CSS selector parser\\n\\nAffected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) via attribute parsing.\\n\\n# Details\\n\\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.\\n\\nThe Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.\\n\\nLet’s take the following regular expression as an example:\\n```js\\nregex = /A(B|C+)+D/\\n```\\n\\nThis regular expression accomplishes the following:\\n- `A` The string must start with the letter 'A'\\n- `(B|C+)+` The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the `+` matches one or more times). The `+` at the end of this section states that we can look for one or more matches of this section.\\n- `D` Finally, we ensure this section of the string ends with a 'D'\\n\\nThe expression would match inputs such as `ABBD`, `ABCCCCD`, `ABCBCCCD` and `ACCCCCD`\\n\\nIt most cases, it doesn't take very long for a regex engine to find a match:\\n\\n```bash\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD\\\")'\\n0.04s user 0.01s system 95% cpu 0.052 total\\n\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX\\\")'\\n1.79s user 0.02s system 99% cpu 1.812 total\\n```\\n\\nThe entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.\\n\\nMost Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as _catastrophic backtracking_.\\n\\nLet's look at how our expression runs into this problem, using a shorter string: \\\"ACCCX\\\". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:\\n1. CCC\\n2. CC+C\\n3. C+CC\\n4. C+C+C.\\n\\nThe engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use [RegEx 101 debugger](https://regex101.com/debugger) to see the engine has to take a total of 38 steps before it can determine the string doesn't match.\\n\\nFrom there, the number of steps the engine must use to validate a string just continues to grow.\\n\\n| String | Number of C's | Number of steps |\\n| -------|-------------:| -----:|\\n| ACCCX | 3 | 38\\n| ACCCCX | 4 | 71\\n| ACCCCCX | 5 | 136\\n| ACCCCCCCCCCCCCCX | 14 | 65,553\\n\\n\\nBy the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.\\n\\n# Remediation\\nUpgrade `css-what` to version 5.0.1 or higher.\\n# References\\n- [GitHub Commit](https://github.com/fb55/css-what/commit/4cdaacfd0d4b6fd00614be030da0dea6c2994655)\\n- [GitHub PR](https://github.com/fb55/css-what/pull/503)\\n- [GitHub Release](https://github.com/fb55/css-what/releases/tag/v5.0.1)\\n\"},\"properties\":{\"tags\":[\"security\",\"CWE-400\",\"yarn\"]}} \n Message: This file introduces a vulnerable css-what package with a medium severity vulnerability.", }, { - Target: "package.json:1-1", + Target: "file://package.json:1-1", Type: "SNYK-JS-D3COLOR-1076592", Title: "This file introduces a vulnerable d3-color package with a medium severity vulnerability.", Severity: v1.Severity_SEVERITY_MEDIUM, Description: "MatchedRule: {\"id\":\"SNYK-JS-D3COLOR-1076592\",\"shortDescription\":{\"text\":\"Medium severity - Regular Expression Denial of Service (ReDoS) vulnerability in d3-color\"},\"fullDescription\":{\"text\":\"d3-color@3.0.1\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: yarn\\n* Vulnerable module: d3-color\\n* Introduced through: spyros-frontend@1.0.0, react-flow-renderer@9.7.4 and others\\n### Detailed paths\\n* _Introduced through_: spyros-frontend@1.0.0 › react-flow-renderer@9.7.4 › d3-zoom@3.0.0 › d3-interpolate@3.0.1 › d3-color@3.0.1\\n* _Introduced through_: spyros-frontend@1.0.0 › react-flow-renderer@9.7.4 › d3-zoom@3.0.0 › d3-transition@3.0.1 › d3-color@3.0.1\\n* _Introduced through_: spyros-frontend@1.0.0 › react-force-graph-2d@1.23.6 › force-graph@1.41.1 › d3-scale-chromatic@2.0.0 › d3-color@2.0.0\\n* _Introduced through_: spyros-frontend@1.0.0 › react-force-graph-2d@1.23.6 › force-graph@1.41.1 › d3-scale@3.3.0 › d3-interpolate@2.0.1 › d3-color@2.0.0\\n* _Introduced through_: spyros-frontend@1.0.0 › react-force-graph-2d@1.23.6 › force-graph@1.41.1 › d3-zoom@2.0.0 › d3-transition@2.0.0 › d3-color@2.0.0\\n# Overview\\n[d3-color](https://www.npmjs.org/package/d3-color) is a Color spaces! RGB, HSL, Cubehelix, Lab and HCL (Lch).\\n\\nAffected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) via the `rgb()` and `hrc()` functions. \\r\\n\\r\\nPoC by Yeting Li: \\r\\n```\\r\\nvar d3Color = require(\\\"d3-color\\\")\\r\\n// d3Color.rgb(\\\"rgb(255,255,255)\\\")\\r\\n\\r\\nfunction build_blank(n) {\\r\\n var ret = \\\"rgb(\\\"\\r\\n for (var i = 0; i \\u003c n; i++) {\\r\\n ret += \\\"1\\\"\\r\\n }\\r\\n return ret + \\\"!\\\";\\r\\n}\\r\\n\\r\\nfor(var i = 1; i \\u003c= 5000000; i++) {\\r\\n if (i % 1000 == 0) {\\r\\n var time = Date.now();\\r\\n var attack_str = build_blank(i)\\r\\n d3Color.rgb(attack_str)\\r\\n var time_cost = Date.now() - time;\\r\\n console.log(\\\"attack_str.length: \\\" + attack_str.length + \\\": \\\" + time_cost+\\\" ms\\\")\\r\\n }\\r\\n}\\r\\n```\\n\\n# Details\\n\\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.\\n\\nThe Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.\\n\\nLet’s take the following regular expression as an example:\\n```js\\nregex = /A(B|C+)+D/\\n```\\n\\nThis regular expression accomplishes the following:\\n- `A` The string must start with the letter 'A'\\n- `(B|C+)+` The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the `+` matches one or more times). The `+` at the end of this section states that we can look for one or more matches of this section.\\n- `D` Finally, we ensure this section of the string ends with a 'D'\\n\\nThe expression would match inputs such as `ABBD`, `ABCCCCD`, `ABCBCCCD` and `ACCCCCD`\\n\\nIt most cases, it doesn't take very long for a regex engine to find a match:\\n\\n```bash\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD\\\")'\\n0.04s user 0.01s system 95% cpu 0.052 total\\n\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX\\\")'\\n1.79s user 0.02s system 99% cpu 1.812 total\\n```\\n\\nThe entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.\\n\\nMost Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as _catastrophic backtracking_.\\n\\nLet's look at how our expression runs into this problem, using a shorter string: \\\"ACCCX\\\". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:\\n1. CCC\\n2. CC+C\\n3. C+CC\\n4. C+C+C.\\n\\nThe engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use [RegEx 101 debugger](https://regex101.com/debugger) to see the engine has to take a total of 38 steps before it can determine the string doesn't match.\\n\\nFrom there, the number of steps the engine must use to validate a string just continues to grow.\\n\\n| String | Number of C's | Number of steps |\\n| -------|-------------:| -----:|\\n| ACCCX | 3 | 38\\n| ACCCCX | 4 | 71\\n| ACCCCCX | 5 | 136\\n| ACCCCCCCCCCCCCCX | 14 | 65,553\\n\\n\\nBy the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.\\n\\n# Remediation\\nUpgrade `d3-color` to version 3.1.0 or higher.\\n# References\\n- [Github PR](https://github.com/d3/d3-color/pull/100)\\n- [Github PR](https://github.com/d3/d3-color/pull/99)\\n- [GitHub PR](https://github.com/d3/d3-color/pull/89)\\n- [Github Releases](https://github.com/d3/d3-color/releases/tag/v3.1.0)\\n\"},\"properties\":{\"tags\":[\"security\",\"CWE-400\",\"yarn\"]}} \n Message: This file introduces a vulnerable d3-color package with a medium severity vulnerability.", }, { - Target: "package.json:1-1", + Target: "file://package.json:1-1", Type: "SNYK-JS-EJS-2803307", Title: "This file introduces a vulnerable ejs package with a high severity vulnerability.", Severity: v1.Severity_SEVERITY_HIGH, diff --git a/components/producers/snyk-node/task.yaml b/components/producers/snyk-node/task.yaml index 8caa9214d..7127bb150 100644 --- a/components/producers/snyk-node/task.yaml +++ b/components/producers/snyk-node/task.yaml @@ -67,6 +67,7 @@ spec: args: - "-in=/scratch/snyk.out" - "-out=$(workspaces.output.path)/.smithy/producers/snyk.pb" + - "-language=javascript" volumeMounts: - mountPath: /scratch name: scratch diff --git a/components/producers/snyk-python/task.yaml b/components/producers/snyk-python/task.yaml index f928c9793..80983726f 100644 --- a/components/producers/snyk-python/task.yaml +++ b/components/producers/snyk-python/task.yaml @@ -61,6 +61,7 @@ spec: args: - "-in=/scratch/snyk.out" - "-out=$(workspaces.output.path)/.smithy/producers/snyk.pb" + - "-language=python" volumeMounts: - mountPath: /scratch name: scratch diff --git a/components/producers/terraform-tfsec/main.go b/components/producers/terraform-tfsec/main.go index 326373962..134631023 100644 --- a/components/producers/terraform-tfsec/main.go +++ b/components/producers/terraform-tfsec/main.go @@ -32,7 +32,7 @@ func main() { if Sarif { var sarifResults []*sarif.SmithyIssueCollection var smithyResults []*v1.Issue - sarifResults, err := sarif.ToSmithy(string(inFile)) + sarifResults, err := sarif.ToSmithy(string(inFile), sarif.ExtraContextLanguageUnspecified) if err != nil { log.Fatal(err) } diff --git a/pkg/sarif/sarif.go b/pkg/sarif/sarif.go index a3a5b4932..ab27359c4 100644 --- a/pkg/sarif/sarif.go +++ b/pkg/sarif/sarif.go @@ -8,16 +8,33 @@ import ( "strings" "time" + "github.com/go-errors/errors" "github.com/owenrumney/go-sarif/v2/sarif" + "github.com/package-url/packageurl-go" v1 "github.com/smithy-security/smithy/api/proto/v1" "github.com/smithy-security/smithy/components/producers" ) -// SmithyIssueCollection represents all the findings in a single Sarif file converted to smithy format. -type SmithyIssueCollection struct { - ToolName string - Issues []*v1.Issue +const ( + ExtraContextLanguageUnspecified ExtraContextLanguage = "unspecified" + ExtraContextLanguagePython ExtraContextLanguage = "python" + ExtraContextLanguageJS ExtraContextLanguage = "javascript" +) + +type ( + // SmithyIssueCollection represents all the findings in a single Sarif file converted to smithy format. + SmithyIssueCollection struct { + ToolName string + Issues []*v1.Issue + } + + ExtraContextLanguage string +) + +var extraCtxLangToPURLNS = map[ExtraContextLanguage]string{ + ExtraContextLanguagePython: "pypi", + ExtraContextLanguageJS: "npm", } // FromSmithyEnrichedIssuesRun transforms a set of LaunchToolResponse to ONE sarif document with @@ -159,7 +176,7 @@ func smithyIssueToSarif(issue *v1.Issue, rule *sarif.ReportingDescriptor) (*sari } // ToSmithy accepts a sarif file and transforms each run to SmithyIssueCollection ready to be written to a results file. -func ToSmithy(inFile string) ([]*SmithyIssueCollection, error) { +func ToSmithy(inFile string, language ExtraContextLanguage) ([]*SmithyIssueCollection, error) { issueCollection := []*SmithyIssueCollection{} inSarif, err := sarif.FromString(inFile) if err != nil { @@ -171,53 +188,59 @@ func ToSmithy(inFile string) ([]*SmithyIssueCollection, error) { for _, rule := range run.Tool.Driver.Rules { rules[rule.ID] = rule } + + issues, err := parseOut(*run, rules, tool, language) + if err != nil { + return nil, errors.Errorf("unexpected parse errors: %w", err) + } + + if len(issues) == 0 { + continue + } + issueCollection = append(issueCollection, &SmithyIssueCollection{ ToolName: tool, - Issues: parseOut(*run, rules, tool), + Issues: issues, }) } return issueCollection, err } -func parseOut(run sarif.Run, rules map[string]*sarif.ReportingDescriptor, toolName string) []*v1.Issue { - issues := []*v1.Issue{} +// parseOut parses a sarif report by extracting physical and logical targets from it +// and generating issues. +func parseOut( + run sarif.Run, + rules map[string]*sarif.ReportingDescriptor, + toolName string, + lang ExtraContextLanguage, +) ([]*v1.Issue, error) { + var ( + issues = make([]*v1.Issue, 0) + parseErr error + ) + for _, res := range run.Results { for _, loc := range res.Locations { - target, uri, sl, el := "", "", "", "" - if loc.PhysicalLocation == nil { - for _, ll := range loc.LogicalLocations { - // do the same for logical locs - target = *ll.FullyQualifiedName - issues = addIssue(rules, issues, target, toolName, res) - } - } else { - if loc.PhysicalLocation.ArtifactLocation.URI != nil { - uri = *loc.PhysicalLocation.ArtifactLocation.URI - } - if loc.PhysicalLocation.Region != nil { - if loc.PhysicalLocation.Region.StartLine != nil { - sl = fmt.Sprintf("%d", *loc.PhysicalLocation.Region.StartLine) - } - if loc.PhysicalLocation.Region.EndLine != nil { - el = fmt.Sprintf("%d", *loc.PhysicalLocation.Region.EndLine) - } else { - el = sl - } - target = fmt.Sprintf("%s:%s-%s", uri, sl, el) - } else { - target = uri - } + + targets, err := parseTargets(loc, lang) + if err != nil { + parseErr = errors.Join(parseErr, err) + } + + for _, target := range targets { issues = addIssue(rules, issues, target, toolName, res) } } } - return issues + + return issues, parseErr } func addIssue(rules map[string]*sarif.ReportingDescriptor, issues []*v1.Issue, target, toolName string, res *sarif.Result) []*v1.Issue { - rule, ok := rules[*res.RuleID] var description string + + rule, ok := rules[*res.RuleID] if !ok { log.Printf("could not find rule with id %s, double check tool %s output contains a tool.driver.rules section ", *res.RuleID, toolName) description = fmt.Sprintf("Message: %s", *res.Message.Text) @@ -230,15 +253,15 @@ func addIssue(rules map[string]*sarif.ReportingDescriptor, issues []*v1.Issue, t Title: *res.Message.Text, Description: description, Type: *res.RuleID, - Severity: levelToseverity(*res.Level), + Severity: levelToSeverity(*res.Level), Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, }) return issues } -// levelToseverity transforms error, warning and note levels to high, medium and low respectively. -func levelToseverity(level string) v1.Severity { +// levelToSeverity transforms error, warning and note levels to high, medium and low respectively. +func levelToSeverity(level string) v1.Severity { if level == LevelError { return v1.Severity_SEVERITY_HIGH } else if level == LevelWarning { @@ -261,6 +284,180 @@ func severityToLevel(severity v1.Severity) string { return LevelNote default: return LevelNone + } +} +// parseTargets parses the passes sarif location and returns all the valid physical and logical targets in it. +func parseTargets(loc *sarif.Location, lang ExtraContextLanguage) ([]string, error) { + var ( + targets = make([]string, 0) + parseErrs error + ) + + // We can have cases were both locations are defined but, in these cases, + // the physical location doesn't make much sense, so we just should leverage the logical one. + if isLogicalLocation(loc) { + tts, err := parseLogicalTargets(loc, lang) + if err != nil { + parseErrs = errors.Join(parseErrs, err) + } + targets = append(targets, tts...) + } else if isPhysicalLocation(loc) { + tt, err := parsePhysicalTarget(loc) + if err != nil { + parseErrs = errors.Join(parseErrs, err) + } + targets = append(targets, tt) } + + return targets, parseErrs +} + +func isPhysicalLocation(loc *sarif.Location) bool { + return loc.PhysicalLocation != nil +} + +// parsePhysicalTarget parses a sarif physical location target. +// We prefix the target with 'file://' so that we know that it's a physical target. +// We add start and end lines information if provided. +// In the case of missing start or end line, we default the undefined one to the same value of the defined one +// because it usually means that the finding affects one line only. +// It can be possible for a target URI to contain a pURL. In that case we simply return that. +func parsePhysicalTarget(loc *sarif.Location) (string, error) { + if loc.PhysicalLocation == nil { + return "", nil + } + + var ( + target string + phyLoc = loc.PhysicalLocation + targetURI = phyLoc.ArtifactLocation.URI + ) + + if targetURI == nil || *targetURI == "" { + return "", errors.New("target URI is empty") + } + + // This means that it's a purl in a physical path. + if _, err := packageurl.FromString(*targetURI); err == nil { + return *targetURI, nil + } + + // Safety check to make sure that we don't end up with malformed targets if + // the upstream tool is already doing this. + if !strings.Contains(*targetURI, "file://") { + target = fmt.Sprintf("file://%s", *targetURI) + } + + if phyLoc.Region != nil { + var ( + isStartLineDefined = phyLoc.Region.StartLine != nil + isEndLineDefined = phyLoc.Region.EndLine != nil + ) + + switch { + case isStartLineDefined && isEndLineDefined: + target = fmt.Sprintf( + "%s:%d-%d", + target, + *phyLoc.Region.StartLine, + *phyLoc.Region.EndLine, + ) + case isStartLineDefined && !isEndLineDefined: + target = fmt.Sprintf( + "%s:%d-%d", + target, + *phyLoc.Region.StartLine, + *phyLoc.Region.StartLine, + ) + case !isStartLineDefined && isEndLineDefined: + target = fmt.Sprintf( + "%s:%d-%d", + target, + *phyLoc.Region.EndLine, + *phyLoc.Region.EndLine, + ) + } + } + + return target, nil +} + +func isLogicalLocation(loc *sarif.Location) bool { + return len(loc.LogicalLocations) > 0 +} + +// parseLogicalTargets parses all the targets found in the logical locations. +// A logical target must be a valid pURL. +func parseLogicalTargets(loc *sarif.Location, lang ExtraContextLanguage) ([]string, error) { + var ( + targets = make([]string, 0) + parseErr error + ) + + if len(loc.LogicalLocations) == 0 { + return targets, nil + } + + for idx, logicLoc := range loc.LogicalLocations { + if logicLoc == nil { + parseErr = errors.Join(parseErr, errors.Errorf("logic location is nil at index %d", idx)) + continue + } + + qualifiedName := *logicLoc.FullyQualifiedName + // If we have a valid pURL, we are done. + // Otherwise, we can see if we can leverage the supplied extra context language to see if we can get a valid one. + if _, err := packageurl.FromString(qualifiedName); err != nil { + // If we don't have the language, just report an error. + if lang == "" || lang == ExtraContextLanguageUnspecified { + parseErr = errors.Join( + parseErr, + errors.Errorf( + "invalid pURL '%s' at index %d: %w", + qualifiedName, + idx, + err, + ), + ) + continue + } + + // Otherwise, let's check if we support the language. + purlNS, ok := extraCtxLangToPURLNS[lang] + if !ok { + parseErr = errors.Join( + parseErr, + errors.Errorf( + "invalid pURL '%s' at index %d. The supplied language '%s' is not supported.", + qualifiedName, + idx, + lang, + ), + ) + continue + } + + // Now let's put together a potentially valid pURL. + qualifiedName = fmt.Sprintf("pkg:%s/%s", purlNS, qualifiedName) + // And check again for its validity. + if _, err := packageurl.FromString(qualifiedName); err != nil { + // If invalid, report as an error. + parseErr = errors.Join( + parseErr, + errors.Errorf( + "invalid pURL '%s' at index %d. Enhanced qualified name '%s' is still not a valid pURL.", + qualifiedName, + idx, + qualifiedName, + ), + ) + continue + } + } + + targets = append(targets, qualifiedName) + } + + return targets, parseErr } diff --git a/pkg/sarif/sarif_test.go b/pkg/sarif/sarif_test.go index 891eba3b5..22abc7c09 100644 --- a/pkg/sarif/sarif_test.go +++ b/pkg/sarif/sarif_test.go @@ -10,57 +10,222 @@ import ( "github.com/owenrumney/go-sarif/v2/sarif" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/types/known/timestamppb" v1 "github.com/smithy-security/smithy/api/proto/v1" - - "google.golang.org/protobuf/types/known/timestamppb" ) func Test_ParseOut(t *testing.T) { - exampleOutput, err := os.ReadFile("./testdata/example_output.json") - require.NoError(t, err) + t.Run("gosec testcases", func(t *testing.T) { + exampleOutput, err := os.ReadFile("./testdata/gosec_output.json") + require.NoError(t, err) - results, err := sarif.FromString(string(exampleOutput)) - if err != nil { - t.Logf(err.Error()) - t.Fail() - } + results, err := sarif.FromString(string(exampleOutput)) + require.NoError(t, err) + require.NotNil(t, results) - expectedIssues := []*v1.Issue{ - { - Target: "main.go:83-83", - Type: "G404", - Title: "[test for missing endLine, common in some tools]", - Severity: v1.Severity_SEVERITY_HIGH, - Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, - Description: "Message: [test for missing endLine, common in some tools]", - }, - { - Target: "main.go:83-83", - Type: "G404", - Title: "Use of weak random number generator (math/rand instead of crypto/rand)", - Severity: v1.Severity_SEVERITY_HIGH, - Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, - Description: "Message: Use of weak random number generator (math/rand instead of crypto/rand)", - }, - { - Target: "main.go:347-347", - Type: "G104", - Title: "Errors unhandled.", - Severity: v1.Severity_SEVERITY_MEDIUM, - Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, - Description: "Message: Errors unhandled.", - }, - } - for _, run := range results.Runs { - rules := make(map[string]*sarif.ReportingDescriptor) - for _, rule := range run.Tool.Driver.Rules { - rules[rule.ID] = rule + expectedIssues := []*v1.Issue{ + { + Target: "file://main.go:83-83", + Type: "G404", + Title: "[test for missing endLine, common in some tools]", + Severity: v1.Severity_SEVERITY_HIGH, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "Message: [test for missing endLine, common in some tools]", + }, + { + Target: "file://main.go:83-83", + Type: "G404", + Title: "Use of weak random number generator (math/rand instead of crypto/rand)", + Severity: v1.Severity_SEVERITY_HIGH, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "Message: Use of weak random number generator (math/rand instead of crypto/rand)", + }, + { + Target: "file://main.go:83-83", + Type: "G404", + Title: "Use of weak random number generator (math/rand instead of crypto/rand) - nil endline", + Severity: v1.Severity_SEVERITY_HIGH, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "Message: Use of weak random number generator (math/rand instead of crypto/rand) - nil endline", + }, + { + Target: "file://main.go:83-83", + Type: "G404", + Title: "Use of weak random number generator (math/rand instead of crypto/rand) - nil startline", + Severity: v1.Severity_SEVERITY_HIGH, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "Message: Use of weak random number generator (math/rand instead of crypto/rand) - nil startline", + }, + { + Target: "file://main.go:347-347", + Type: "G104", + Title: "Errors unhandled.", + Severity: v1.Severity_SEVERITY_MEDIUM, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "Message: Errors unhandled.", + }, + { + Target: "pkg:npm/%40angular/animation@12.3.1", + Type: "G104", + Title: "Vulnerable SQL injection code.", + Severity: v1.Severity_SEVERITY_HIGH, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "Message: Vulnerable SQL injection code.", + }, + } + for _, run := range results.Runs { + rules := make(map[string]*sarif.ReportingDescriptor) + for _, rule := range run.Tool.Driver.Rules { + rules[rule.ID] = rule + } + issues, err := parseOut(*run, rules, "gosec", ExtraContextLanguageUnspecified) + require.NoError(t, err) + assert.EqualValues(t, expectedIssues, issues) } - issues := parseOut(*run, rules, "trivy") + }) + t.Run("snyk-node testcases", func(t *testing.T) { + exampleOutput, err := os.ReadFile("./testdata/snyk-node_output.json") + require.NoError(t, err) - assert.EqualValues(t, expectedIssues, issues) - } + results, err := sarif.FromString(string(exampleOutput)) + require.NoError(t, err) + require.NotNil(t, results) + + expectedIssues := []*v1.Issue{ + { + Target: "pkg:npm/cookie@0.3.1", + Type: "SNYK-JS-COOKIE-8163060", + Title: "This file introduces a vulnerable cookie package with a medium severity vulnerability.", + Severity: v1.Severity_SEVERITY_MEDIUM, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "MatchedRule: {\"id\":\"SNYK-JS-COOKIE-8163060\",\"shortDescription\":{\"text\":\"Medium severity - Cross-site Scripting (XSS) vulnerability in cookie\"},\"fullDescription\":{\"text\":\"(CVE-2024-47764) cookie@0.3.1\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: npm\\n* Vulnerable module: cookie\\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, socket.io@1.7.4 and others\\n### Detailed paths\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › engine.io@1.8.5 › cookie@0.3.1\\n# Overview\\n\\nAffected versions of this package are vulnerable to Cross-site Scripting (XSS) via the cookie `name`, `path`, or `domain`, which can be used to set unexpected values to other cookie fields.\\r\\n\\r\\n# Workaround\\r\\nUsers who are not able to upgrade to the fixed version should avoid passing untrusted or arbitrary values for the cookie fields and ensure they are set by the application instead of user input.\\n# Details\\n\\nA cross-site scripting attack occurs when the attacker tricks a legitimate web-based application or site to accept a request as originating from a trusted source.\\n\\nThis is done by escaping the context of the web application; the web application then delivers that data to its users along with other trusted dynamic content, without validating it. The browser unknowingly executes malicious script on the client side (through client-side languages; usually JavaScript or HTML) in order to perform actions that are otherwise typically blocked by the browser’s Same Origin Policy.\\n\\nInjecting malicious code is the most prevalent manner by which XSS is exploited; for this reason, escaping characters in order to prevent this manipulation is the top method for securing code against this vulnerability.\\n\\nEscaping means that the application is coded to mark key characters, and particularly key characters included in user input, to prevent those characters from being interpreted in a dangerous context. For example, in HTML, `\\u003c` can be coded as `\\u0026lt`; and `\\u003e` can be coded as `\\u0026gt`; in order to be interpreted and displayed as themselves in text, while within the code itself, they are used for HTML tags. If malicious content is injected into an application that escapes special characters and that malicious content uses `\\u003c` and `\\u003e` as HTML tags, those characters are nonetheless not interpreted as HTML tags by the browser if they’ve been correctly escaped in the application code and in this way the attempted attack is diverted.\\n \\nThe most prominent use of XSS is to steal cookies (source: OWASP HttpOnly) and hijack user sessions, but XSS exploits have been used to expose sensitive information, enable access to privileged services and functionality and deliver malware. \\n\\n## Types of attacks\\nThere are a few methods by which XSS can be manipulated:\\n\\n|Type|Origin|Description|\\n|--|--|--|\\n|**Stored**|Server|The malicious code is inserted in the application (usually as a link) by the attacker. The code is activated every time a user clicks the link.|\\n|**Reflected**|Server|The attacker delivers a malicious link externally from the vulnerable web site application to a user. When clicked, malicious code is sent to the vulnerable web site, which reflects the attack back to the user’s browser.| \\n|**DOM-based**|Client|The attacker forces the user’s browser to render a malicious page. The data in the page itself delivers the cross-site scripting data.|\\n|**Mutated**| |The attacker injects code that appears safe, but is then rewritten and modified by the browser, while parsing the markup. An example is rebalancing unclosed quotation marks or even adding quotation marks to unquoted parameters.|\\n\\n## Affected environments\\nThe following environments are susceptible to an XSS attack:\\n\\n* Web servers\\n* Application servers\\n* Web application environments\\n\\n## How to prevent\\nThis section describes the top best practices designed to specifically protect your code: \\n\\n* Sanitize data input in an HTTP request before reflecting it back, ensuring all data is validated, filtered or escaped before echoing anything back to the user, such as the values of query parameters during searches. \\n* Convert special characters such as `?`, `\\u0026`, `/`, `\\u003c`, `\\u003e` and spaces to their respective HTML or URL encoded equivalents. \\n* Give users the option to disable client-side scripts.\\n* Redirect invalid requests.\\n* Detect simultaneous logins, including those from two separate IP addresses, and invalidate those sessions.\\n* Use and enforce a Content Security Policy (source: Wikipedia) to disable any features that might be manipulated for an XSS attack.\\n* Read the documentation for any of the libraries referenced in your code to understand which elements allow for embedded HTML.\\n\\n# Remediation\\nUpgrade `cookie` to version 0.7.0 or higher.\\n# References\\n- [GitHub Commit](https://github.com/jshttp/cookie/commit/e10042845354fea83bd8f34af72475eed1dadf5c)\\n- [GitHub PR](https://github.com/jshttp/cookie/pull/167)\\n- [Red Hat Bugzilla Bug](https://bugzilla.redhat.com/show_bug.cgi?id=2316549)\\n\"},\"properties\":{\"cvssv3_baseScore\":6.3,\"security-severity\":\"6.3\",\"tags\":[\"security\",\"CWE-79\",\"npm\"]}} \n Message: This file introduces a vulnerable cookie package with a medium severity vulnerability.", + }, + { + Target: "pkg:npm/engine.io@1.8.5", + Type: "SNYK-JS-ENGINEIO-1056749", + Title: "This file introduces a vulnerable engine.io package with a high severity vulnerability.", + Severity: v1.Severity_SEVERITY_HIGH, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "MatchedRule: {\"id\":\"SNYK-JS-ENGINEIO-1056749\",\"shortDescription\":{\"text\":\"High severity - Denial of Service (DoS) vulnerability in engine.io\"},\"fullDescription\":{\"text\":\"(CVE-2020-36048) engine.io@1.8.5\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: npm\\n* Vulnerable module: engine.io\\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, socket.io@1.7.4 and others\\n### Detailed paths\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › engine.io@1.8.5\\n# Overview\\n[engine.io](https://github.com/socketio/engine.io) is a realtime engine behind Socket.IO. It provides the foundation of a bidirectional connection between client and server\\n\\nAffected versions of this package are vulnerable to Denial of Service (DoS) via a POST request to the long polling transport.\\n\\n# Details\\n\\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.\\n\\nUnlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.\\n\\nOne popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.\\n\\nWhen it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.\\n\\nTwo common types of DoS vulnerabilities:\\n\\n* High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, [commons-fileupload:commons-fileupload](https://security.snyk.io/vuln/SNYK-JAVA-COMMONSFILEUPLOAD-30082).\\n\\n* Crash - An attacker sending crafted requests that could cause the system to crash. For Example, [npm `ws` package](https://snyk.io/vuln/npm:ws:20171108)\\n\\n# Remediation\\nUpgrade `engine.io` to version 3.6.0 or higher.\\n# References\\n- [GitHub Commit](https://github.com/socketio/engine.io/commit/58e274c437e9cbcf69fd913c813aad8fbd253703)\\n- [GitHub Commit](https://github.com/socketio/engine.io/commit/734f9d1268840722c41219e69eb58318e0b2ac6b)\\n- [GitHub Tags](https://github.com/socketio/engine.io/releases/tag/3.6.0)\\n- [PoC](https://github.com/bcaller/kill-engine-io)\\n- [Research Blogpost](https://blog.caller.xyz/socketio-engineio-dos/)\\n\"},\"properties\":{\"cvssv3_baseScore\":7.5,\"security-severity\":\"7.5\",\"tags\":[\"security\",\"CWE-400\",\"npm\"]}} \n Message: This file introduces a vulnerable engine.io package with a high severity vulnerability.", + }, + { + Target: "pkg:npm/engine.io@1.8.5", + Type: "SNYK-JS-ENGINEIO-3136336", + Title: "This file introduces a vulnerable engine.io package with a high severity vulnerability.", + Severity: v1.Severity_SEVERITY_HIGH, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "MatchedRule: {\"id\":\"SNYK-JS-ENGINEIO-3136336\",\"shortDescription\":{\"text\":\"High severity - Denial of Service (DoS) vulnerability in engine.io\"},\"fullDescription\":{\"text\":\"(CVE-2022-41940) engine.io@1.8.5\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: npm\\n* Vulnerable module: engine.io\\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, socket.io@1.7.4 and others\\n### Detailed paths\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › engine.io@1.8.5\\n# Overview\\n[engine.io](https://github.com/socketio/engine.io) is a realtime engine behind Socket.IO. It provides the foundation of a bidirectional connection between client and server\\n\\nAffected versions of this package are vulnerable to Denial of Service (DoS). A malicious client could send a specially crafted HTTP request, triggering an uncaught exception and killing the `Node.js` process.\\n\\n# Details\\n\\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.\\n\\nUnlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.\\n\\nOne popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.\\n\\nWhen it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.\\n\\nTwo common types of DoS vulnerabilities:\\n\\n* High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, [commons-fileupload:commons-fileupload](https://security.snyk.io/vuln/SNYK-JAVA-COMMONSFILEUPLOAD-30082).\\n\\n* Crash - An attacker sending crafted requests that could cause the system to crash. For Example, [npm `ws` package](https://snyk.io/vuln/npm:ws:20171108)\\n\\n# Remediation\\nUpgrade `engine.io` to version 3.6.1, 6.2.1 or higher.\\n# References\\n- [GitHub Commit](https://github.com/socketio/engine.io/commit/425e833ab13373edf1dd5a0706f07100db14e3c6)\\n- [GitHub Commit](https://github.com/socketio/engine.io/commit/83c4071af871fc188298d7d591e95670bf9f9085)\\n- [GitHub PR](https://github.com/socketio/engine.io/pull/658)\\n\"},\"properties\":{\"cvssv3_baseScore\":7.5,\"security-severity\":\"7.5\",\"tags\":[\"security\",\"CWE-400\",\"npm\"]}} \n Message: This file introduces a vulnerable engine.io package with a high severity vulnerability.", + }, + { + Target: "pkg:npm/socket.io@1.7.4", + Type: "SNYK-JS-SOCKETIO-1024859", + Title: "This file introduces a vulnerable socket.io package with a medium severity vulnerability.", + Severity: v1.Severity_SEVERITY_MEDIUM, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "MatchedRule: {\"id\":\"SNYK-JS-SOCKETIO-1024859\",\"shortDescription\":{\"text\":\"Medium severity - Insecure Defaults vulnerability in socket.io\"},\"fullDescription\":{\"text\":\"(CVE-2020-28481) socket.io@1.7.4\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: npm\\n* Vulnerable module: socket.io\\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 and socket.io@1.7.4\\n### Detailed paths\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4\\n# Overview\\n[socket.io](https://github.com/socketio/socket.io) is a node.js realtime framework server.\\n\\nAffected versions of this package are vulnerable to Insecure Defaults due to CORS Misconfiguration. All domains are whitelisted by default.\\n# Remediation\\nUpgrade `socket.io` to version 2.4.0 or higher.\\n# References\\n- [GitHub Issue](https://github.com/socketio/socket.io/issues/3671)\\n- [HackerOne Report](https://hackerone.com/reports/931197)\\n\"},\"properties\":{\"cvssv3_baseScore\":5.3,\"security-severity\":\"5.3\",\"tags\":[\"security\",\"CWE-453\",\"npm\"]}} \n Message: This file introduces a vulnerable socket.io package with a medium severity vulnerability.", + }, + { + Target: "pkg:npm/socket.io-parser@2.3.1", + Type: "SNYK-JS-SOCKETIOPARSER-1056752", + Title: "This file introduces a vulnerable socket.io-parser package with a high severity vulnerability.", + Severity: v1.Severity_SEVERITY_HIGH, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "MatchedRule: {\"id\":\"SNYK-JS-SOCKETIOPARSER-1056752\",\"shortDescription\":{\"text\":\"High severity - Denial of Service (DoS) vulnerability in socket.io-parser\"},\"fullDescription\":{\"text\":\"(CVE-2020-36049) socket.io-parser@2.3.1\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: npm\\n* Vulnerable module: socket.io-parser\\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, socket.io@1.7.4 and others\\n### Detailed paths\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-parser@2.3.1\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-adapter@0.5.0 › socket.io-parser@2.3.1\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › socket.io-parser@2.3.1\\n# Overview\\n[socket.io-parser](https://www.npmjs.org/package/socket.io-parser) is a socket.io protocol parser\\n\\nAffected versions of this package are vulnerable to Denial of Service (DoS) via a large packet because a concatenation approach is used.\\n\\n# Details\\n\\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.\\n\\nUnlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.\\n\\nOne popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.\\n\\nWhen it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.\\n\\nTwo common types of DoS vulnerabilities:\\n\\n* High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, [commons-fileupload:commons-fileupload](https://security.snyk.io/vuln/SNYK-JAVA-COMMONSFILEUPLOAD-30082).\\n\\n* Crash - An attacker sending crafted requests that could cause the system to crash. For Example, [npm `ws` package](https://snyk.io/vuln/npm:ws:20171108)\\n\\n# Remediation\\nUpgrade `socket.io-parser` to version 3.3.2, 3.4.1 or higher.\\n# References\\n- [GitHub Commit](https://github.com/socketio/socket.io-parser/commit/dcb942d24db97162ad16a67c2a0cf30875342d55)\\n- [PoC](https://github.com/bcaller/kill-engine-io)\\n- [Research Blogpost](https://blog.caller.xyz/socketio-engineio-dos/)\\n\"},\"properties\":{\"cvssv3_baseScore\":7.5,\"security-severity\":\"7.5\",\"tags\":[\"security\",\"CWE-400\",\"npm\"]}} \n Message: This file introduces a vulnerable socket.io-parser package with a high severity vulnerability.", + }, + { + Target: "pkg:npm/socket.io-parser@2.3.1", + Type: "SNYK-JS-SOCKETIOPARSER-3091012", + Title: "This file introduces a vulnerable socket.io-parser package with a critical severity vulnerability.", + Severity: v1.Severity_SEVERITY_HIGH, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "MatchedRule: {\"id\":\"SNYK-JS-SOCKETIOPARSER-3091012\",\"shortDescription\":{\"text\":\"Critical severity - Improper Input Validation vulnerability in socket.io-parser\"},\"fullDescription\":{\"text\":\"(CVE-2022-2421) socket.io-parser@2.3.1\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: npm\\n* Vulnerable module: socket.io-parser\\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, socket.io@1.7.4 and others\\n### Detailed paths\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-parser@2.3.1\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-adapter@0.5.0 › socket.io-parser@2.3.1\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › socket.io-parser@2.3.1\\n# Overview\\n\\n[socket.io-parser](https://www.npmjs.org/package/socket.io-parser) is a socket.io protocol parser\\n\\n\\nAffected versions of this package are vulnerable to Improper Input Validation.\\nwhen parsing attachments containing untrusted user input. Attackers can overwrite the `_placeholder` object to place references to functions in query objects.\\r\\n\\r\\n# PoC\\r\\n\\r\\n```js\\r\\nconst decoder = new Decoder();\\r\\n\\r\\ndecoder.on(\\\"decoded\\\", (packet) =\\u003e {\\r\\n console.log(packet.data); // prints [ 'hello', [Function: splice] ]\\r\\n})\\r\\n\\r\\ndecoder.add('51-[\\\"hello\\\",{\\\"_placeholder\\\":true,\\\"num\\\":\\\"splice\\\"}]');\\r\\ndecoder.add(Buffer.from(\\\"world\\\"));\\r\\n```\\n\\n# Remediation\\n\\nUpgrade `socket.io-parser` to version 3.3.3, 3.4.2, 4.0.5, 4.2.1 or higher.\\n\\n\\n# References\\n\\n- [GitHub Commit](https://github.com/socketio/socket.io-parser/commit/b559f050ee02bd90bd853b9823f8de7fa94a80d4)\\n\\n- [GitHub Commit](https://github.com/socketio/socket.io-parser/commit/b5d0cb7dc56a0601a09b056beaeeb0e43b160050)\\n\\n- [Vulnerability Report](https://csirt.divd.nl/cases/DIVD-2022-00045)\\n\\n- [Vulnerability Report](https://csirt.divd.nl/cves/CVE-2022-2421)\\n\"},\"properties\":{\"cvssv3_baseScore\":9.8,\"security-severity\":\"9.8\",\"tags\":[\"security\",\"CWE-89\",\"npm\"]}} \n Message: This file introduces a vulnerable socket.io-parser package with a critical severity vulnerability.", + }, + { + Target: "pkg:npm/uglify-js@2.2.5", + Type: "SNYK-JS-UGLIFYJS-1727251", + Title: "This file introduces a vulnerable uglify-js package with a medium severity vulnerability.", + Severity: v1.Severity_SEVERITY_MEDIUM, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "MatchedRule: {\"id\":\"SNYK-JS-UGLIFYJS-1727251\",\"shortDescription\":{\"text\":\"Medium severity - Regular Expression Denial of Service (ReDoS) vulnerability in uglify-js\"},\"fullDescription\":{\"text\":\"uglify-js@2.2.5\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: npm\\n* Vulnerable module: uglify-js\\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, jade@1.11.0 and others\\n### Detailed paths\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › jade@1.11.0 › transformers@2.1.0 › uglify-js@2.2.5\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › jade@1.11.0 › uglify-js@2.8.29\\n# Overview\\n[uglify-js](http://npmjs.com/package/uglify-js) is a JavaScript parser, minifier, compressor and beautifier toolkit.\\n\\nAffected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) via the `string_template` and the `decode_template` functions.\\n\\n# Details\\n\\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.\\n\\nThe Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.\\n\\nLet’s take the following regular expression as an example:\\n```js\\nregex = /A(B|C+)+D/\\n```\\n\\nThis regular expression accomplishes the following:\\n- `A` The string must start with the letter 'A'\\n- `(B|C+)+` The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the `+` matches one or more times). The `+` at the end of this section states that we can look for one or more matches of this section.\\n- `D` Finally, we ensure this section of the string ends with a 'D'\\n\\nThe expression would match inputs such as `ABBD`, `ABCCCCD`, `ABCBCCCD` and `ACCCCCD`\\n\\nIt most cases, it doesn't take very long for a regex engine to find a match:\\n\\n```bash\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD\\\")'\\n0.04s user 0.01s system 95% cpu 0.052 total\\n\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX\\\")'\\n1.79s user 0.02s system 99% cpu 1.812 total\\n```\\n\\nThe entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.\\n\\nMost Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as _catastrophic backtracking_.\\n\\nLet's look at how our expression runs into this problem, using a shorter string: \\\"ACCCX\\\". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:\\n1. CCC\\n2. CC+C\\n3. C+CC\\n4. C+C+C.\\n\\nThe engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use [RegEx 101 debugger](https://regex101.com/debugger) to see the engine has to take a total of 38 steps before it can determine the string doesn't match.\\n\\nFrom there, the number of steps the engine must use to validate a string just continues to grow.\\n\\n| String | Number of C's | Number of steps |\\n| -------|-------------:| -----:|\\n| ACCCX | 3 | 38\\n| ACCCCX | 4 | 71\\n| ACCCCCX | 5 | 136\\n| ACCCCCCCCCCCCCCX | 14 | 65,553\\n\\n\\nBy the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.\\n\\n# Remediation\\nUpgrade `uglify-js` to version 3.14.3 or higher.\\n# References\\n- [GitHub Commit](https://github.com/mishoo/UglifyJS/commit/157521066fc43cff2feab7ffc1ecea603617606b)\\n- [GitHub Issue](https://github.com/mishoo/UglifyJS/issues/5133)\\n- [GitHub PR](https://github.com/mishoo/UglifyJS/pull/5134)\\n- [GitHub PR](https://github.com/mishoo/UglifyJS/pull/5135)\\n\"},\"properties\":{\"cvssv3_baseScore\":5.3,\"security-severity\":\"5.3\",\"tags\":[\"security\",\"CWE-1333\",\"npm\"]}} \n Message: This file introduces a vulnerable uglify-js package with a medium severity vulnerability.", + }, + { + Target: "pkg:npm/ws@1.1.5", + Type: "SNYK-JS-WS-1296835", + Title: "This file introduces a vulnerable ws package with a medium severity vulnerability.", + Severity: v1.Severity_SEVERITY_MEDIUM, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "MatchedRule: {\"id\":\"SNYK-JS-WS-1296835\",\"shortDescription\":{\"text\":\"Medium severity - Regular Expression Denial of Service (ReDoS) vulnerability in ws\"},\"fullDescription\":{\"text\":\"(CVE-2021-32640) ws@1.1.5\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: npm\\n* Vulnerable module: ws\\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, socket.io@1.7.4 and others\\n### Detailed paths\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › engine.io@1.8.5 › ws@1.1.5\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › engine.io-client@1.8.6 › ws@1.1.5\\n# Overview\\n[ws](https://www.npmjs.com/package/ws) is a simple to use websocket client, server and console for node.js.\\n\\nAffected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS). A specially crafted value of the `Sec-Websocket-Protocol` header can be used to significantly slow down a `ws` server.\\r\\n\\r\\n##PoC\\r\\n```\\r\\nfor (const length of [1000, 2000, 4000, 8000, 16000, 32000]) {\\r\\n const value = 'b' + ' '.repeat(length) + 'x';\\r\\n const start = process.hrtime.bigint();\\r\\n\\r\\n value.trim().split(/ *, */);\\r\\n\\r\\n const end = process.hrtime.bigint();\\r\\n\\r\\n console.log('length = %d, time = %f ns', length, end - start);\\r\\n}\\r\\n```\\n\\n# Details\\n\\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.\\n\\nThe Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.\\n\\nLet’s take the following regular expression as an example:\\n```js\\nregex = /A(B|C+)+D/\\n```\\n\\nThis regular expression accomplishes the following:\\n- `A` The string must start with the letter 'A'\\n- `(B|C+)+` The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the `+` matches one or more times). The `+` at the end of this section states that we can look for one or more matches of this section.\\n- `D` Finally, we ensure this section of the string ends with a 'D'\\n\\nThe expression would match inputs such as `ABBD`, `ABCCCCD`, `ABCBCCCD` and `ACCCCCD`\\n\\nIt most cases, it doesn't take very long for a regex engine to find a match:\\n\\n```bash\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD\\\")'\\n0.04s user 0.01s system 95% cpu 0.052 total\\n\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX\\\")'\\n1.79s user 0.02s system 99% cpu 1.812 total\\n```\\n\\nThe entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.\\n\\nMost Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as _catastrophic backtracking_.\\n\\nLet's look at how our expression runs into this problem, using a shorter string: \\\"ACCCX\\\". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:\\n1. CCC\\n2. CC+C\\n3. C+CC\\n4. C+C+C.\\n\\nThe engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use [RegEx 101 debugger](https://regex101.com/debugger) to see the engine has to take a total of 38 steps before it can determine the string doesn't match.\\n\\nFrom there, the number of steps the engine must use to validate a string just continues to grow.\\n\\n| String | Number of C's | Number of steps |\\n| -------|-------------:| -----:|\\n| ACCCX | 3 | 38\\n| ACCCCX | 4 | 71\\n| ACCCCCX | 5 | 136\\n| ACCCCCCCCCCCCCCX | 14 | 65,553\\n\\n\\nBy the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.\\n\\n# Remediation\\nUpgrade `ws` to version 7.4.6, 6.2.2, 5.2.3 or higher.\\n# References\\n- [GitHub Commit](https://github.com/websockets/ws/commit/00c425ec77993773d823f018f64a5c44e17023ff)\\n\"},\"properties\":{\"cvssv3_baseScore\":5.3,\"security-severity\":\"5.3\",\"tags\":[\"security\",\"CWE-400\",\"npm\"]}} \n Message: This file introduces a vulnerable ws package with a medium severity vulnerability.", + }, + { + Target: "pkg:npm/clean-css@3.4.28", + Type: "npm:clean-css:20180306", + Title: "This file introduces a vulnerable clean-css package with a low severity vulnerability.", + Severity: v1.Severity_SEVERITY_INFO, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "MatchedRule: {\"id\":\"npm:clean-css:20180306\",\"shortDescription\":{\"text\":\"Low severity - Regular Expression Denial of Service (ReDoS) vulnerability in clean-css\"},\"fullDescription\":{\"text\":\"clean-css@3.4.28\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: npm\\n* Vulnerable module: clean-css\\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, jade@1.11.0 and others\\n### Detailed paths\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › jade@1.11.0 › clean-css@3.4.28\\n# Overview\\n\\n[clean-css](https://www.npmjs.com/package/clean-css) is a fast and efficient CSS optimizer for Node.js platform and any modern browser.\\n\\n\\nAffected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS).\\nattacks. This can cause an impact of about 10 seconds matching time for data 70k characters long.\\n\\n# Disclosure Timeline\\n* Feb 15th, 2018 - Initial Disclosure to package owner\\n* Feb 20th, 2018 - Initial Response from package owner\\n* Mar 6th, 2018 - Fix issued\\n* Mar 7th, 2018 - Vulnerability published\\n\\n# Details\\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.\\r\\n\\r\\nThe Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.\\r\\n\\r\\nLet’s take the following regular expression as an example:\\r\\n```js\\r\\nregex = /A(B|C+)+D/\\r\\n```\\r\\n\\r\\nThis regular expression accomplishes the following:\\r\\n- `A` The string must start with the letter 'A'\\r\\n- `(B|C+)+` The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the `+` matches one or more times). The `+` at the end of this section states that we can look for one or more matches of this section.\\r\\n- `D` Finally, we ensure this section of the string ends with a 'D'\\r\\n\\r\\nThe expression would match inputs such as `ABBD`, `ABCCCCD`, `ABCBCCCD` and `ACCCCCD`\\r\\n\\r\\nIt most cases, it doesn't take very long for a regex engine to find a match:\\r\\n\\r\\n```bash\\r\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD\\\")'\\r\\n0.04s user 0.01s system 95% cpu 0.052 total\\r\\n\\r\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX\\\")'\\r\\n1.79s user 0.02s system 99% cpu 1.812 total\\r\\n```\\r\\n\\r\\nThe entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.\\r\\n\\r\\nMost Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as _catastrophic backtracking_.\\r\\n\\r\\nLet's look at how our expression runs into this problem, using a shorter string: \\\"ACCCX\\\". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:\\r\\n1. CCC\\r\\n2. CC+C\\r\\n3. C+CC\\r\\n4. C+C+C.\\r\\n\\r\\nThe engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use [RegEx 101 debugger](https://regex101.com/debugger) to see the engine has to take a total of 38 steps before it can determine the string doesn't match.\\r\\n\\r\\nFrom there, the number of steps the engine must use to validate a string just continues to grow.\\r\\n\\r\\n| String | Number of C's | Number of steps |\\r\\n| -------|-------------:| -----:|\\r\\n| ACCCX | 3 | 38\\r\\n| ACCCCX | 4 | 71\\r\\n| ACCCCCX | 5 | 136\\r\\n| ACCCCCCCCCCCCCCX | 14 | 65,553\\r\\n\\r\\n\\r\\nBy the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.\\n\\n# Remediation\\n\\nUpgrade `clean-css` to version 4.1.11 or higher.\\n\\n\\n# References\\n\\n- [GitHub Advisory](https://github.com/advisories/GHSA-wxhq-pm8v-cw75)\\n\\n- [GitHub Commit](https://github.com/jakubpawlowicz/clean-css/commit/2929bafbf8cdf7dccb24e0949c70833764fa87e3)\\n\"},\"properties\":{\"cvssv3_baseScore\":3.7,\"security-severity\":\"3.7\",\"tags\":[\"security\",\"CWE-185\",\"CWE-400\",\"npm\"]}} \n Message: This file introduces a vulnerable clean-css package with a low severity vulnerability.", + }, + { + Target: "pkg:npm/constantinople@3.0.2", + Type: "npm:constantinople:20180421", + Title: "This file introduces a vulnerable constantinople package with a critical severity vulnerability.", + Severity: v1.Severity_SEVERITY_HIGH, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "MatchedRule: {\"id\":\"npm:constantinople:20180421\",\"shortDescription\":{\"text\":\"Critical severity - Sandbox Bypass vulnerability in constantinople\"},\"fullDescription\":{\"text\":\"constantinople@3.0.2\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: npm\\n* Vulnerable module: constantinople\\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, jade@1.11.0 and others\\n### Detailed paths\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › jade@1.11.0 › constantinople@3.0.2\\n# Overview\\n[constantinople](https://github.com/ForbesLindesay/constantinople) is a Determine whether a JavaScript expression evaluates to a constant (using acorn)\\n\\nAffected versions of this package are vulnerable to Sandbox Bypass which can lead to arbitrary code execution.\\n# Remediation\\nUpgrade `constantinople` to version 3.1.1 or higher.\\n# References\\n- [GitHub Commit](https://github.com/pugjs/constantinople/commit/01d409c0d081dfd65223e6b7767c244156d35f7f)\\n\"},\"properties\":{\"cvssv3_baseScore\":10,\"security-severity\":\"10\",\"tags\":[\"security\",\"CWE-264\",\"npm\"]}} \n Message: This file introduces a vulnerable constantinople package with a critical severity vulnerability.", + }, + { + Target: "pkg:npm/debug@2.3.3", + Type: "npm:debug:20170905", + Title: "This file introduces a vulnerable debug package with a low severity vulnerability.", + Severity: v1.Severity_SEVERITY_INFO, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "MatchedRule: {\"id\":\"npm:debug:20170905\",\"shortDescription\":{\"text\":\"Low severity - Regular Expression Denial of Service (ReDoS) vulnerability in debug\"},\"fullDescription\":{\"text\":\"(CVE-2017-16137) debug@2.3.3\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: npm\\n* Vulnerable module: debug\\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, socket.io@1.7.4 and others\\n### Detailed paths\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › debug@2.3.3\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › engine.io@1.8.5 › debug@2.3.3\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-adapter@0.5.0 › debug@2.3.3\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › debug@2.3.3\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › engine.io-client@1.8.6 › debug@2.3.3\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-parser@2.3.1 › debug@2.2.0\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-adapter@0.5.0 › socket.io-parser@2.3.1 › debug@2.2.0\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › socket.io-parser@2.3.1 › debug@2.2.0\\n# Overview\\n[debug](https://github.com/visionmedia/debug) is a small debugging utility.\\n\\nAffected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) in the function `useColors` via manipulation of the `str` argument. \\r\\nThe vulnerability can cause a very low impact of about 2 seconds of matching time for data 50k characters long.\\r\\n\\r\\n**Note:**\\r\\nCVE-2017-20165 is a duplicate of this vulnerability.\\r\\n\\r\\n# PoC\\r\\n\\r\\nUse the following regex in the `%o` formatter.\\r\\n```js\\r\\n/\\\\s*\\\\n\\\\s*/\\r\\n```\\n\\n# Details\\n\\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.\\n\\nThe Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.\\n\\nLet’s take the following regular expression as an example:\\n```js\\nregex = /A(B|C+)+D/\\n```\\n\\nThis regular expression accomplishes the following:\\n- `A` The string must start with the letter 'A'\\n- `(B|C+)+` The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the `+` matches one or more times). The `+` at the end of this section states that we can look for one or more matches of this section.\\n- `D` Finally, we ensure this section of the string ends with a 'D'\\n\\nThe expression would match inputs such as `ABBD`, `ABCCCCD`, `ABCBCCCD` and `ACCCCCD`\\n\\nIt most cases, it doesn't take very long for a regex engine to find a match:\\n\\n```bash\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD\\\")'\\n0.04s user 0.01s system 95% cpu 0.052 total\\n\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX\\\")'\\n1.79s user 0.02s system 99% cpu 1.812 total\\n```\\n\\nThe entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.\\n\\nMost Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as _catastrophic backtracking_.\\n\\nLet's look at how our expression runs into this problem, using a shorter string: \\\"ACCCX\\\". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:\\n1. CCC\\n2. CC+C\\n3. C+CC\\n4. C+C+C.\\n\\nThe engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use [RegEx 101 debugger](https://regex101.com/debugger) to see the engine has to take a total of 38 steps before it can determine the string doesn't match.\\n\\nFrom there, the number of steps the engine must use to validate a string just continues to grow.\\n\\n| String | Number of C's | Number of steps |\\n| -------|-------------:| -----:|\\n| ACCCX | 3 | 38\\n| ACCCCX | 4 | 71\\n| ACCCCCX | 5 | 136\\n| ACCCCCCCCCCCCCCX | 14 | 65,553\\n\\n\\nBy the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.\\n\\n# Remediation\\nUpgrade `debug` to version 2.6.9, 3.1.0, 3.2.7, 4.3.1 or higher.\\n# References\\n- [GitHub Commit](https://github.com/debug-js/debug/commit/b6d12fdbc63b483e5c969da33ea6adc09946b5ac)\\n- [GitHub Commit](https://github.com/visionmedia/debug/pull/504/commits/42a6ae0737f9243c80b6d3dbb08a69a7ae2a1061)\\n- [GitHub Issue](https://github.com/visionmedia/debug/issues/501)\\n- [GitHub PR](https://github.com/visionmedia/debug/pull/504)\\n- [GitHub Release Notes 2.6.9](https://github.com/debug-js/debug/releases/tag/2.6.9)\\n- [GitHub Release Notes 3.1.0](https://github.com/debug-js/debug/releases/tag/3.1.0)\\n\"},\"properties\":{\"cvssv3_baseScore\":3.7,\"security-severity\":\"3.7\",\"tags\":[\"security\",\"CWE-400\",\"npm\"]}} \n Message: This file introduces a vulnerable debug package with a low severity vulnerability.", + }, + { + Target: "pkg:npm/ms@0.7.2", + Type: "npm:ms:20170412", + Title: "This file introduces a vulnerable ms package with a low severity vulnerability.", + Severity: v1.Severity_SEVERITY_INFO, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "MatchedRule: {\"id\":\"npm:ms:20170412\",\"shortDescription\":{\"text\":\"Low severity - Regular Expression Denial of Service (ReDoS) vulnerability in ms\"},\"fullDescription\":{\"text\":\"(CVE-2017-20162) ms@0.7.2\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: npm\\n* Vulnerable module: ms\\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, socket.io@1.7.4 and others\\n### Detailed paths\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › debug@2.3.3 › ms@0.7.2\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › engine.io@1.8.5 › debug@2.3.3 › ms@0.7.2\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-adapter@0.5.0 › debug@2.3.3 › ms@0.7.2\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › debug@2.3.3 › ms@0.7.2\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › engine.io-client@1.8.6 › debug@2.3.3 › ms@0.7.2\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-parser@2.3.1 › debug@2.2.0 › ms@0.7.1\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-adapter@0.5.0 › socket.io-parser@2.3.1 › debug@2.2.0 › ms@0.7.1\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › socket.io-parser@2.3.1 › debug@2.2.0 › ms@0.7.1\\n# Overview\\r\\n[`ms`](https://www.npmjs.com/package/ms) is a tiny millisecond conversion utility.\\r\\n\\r\\nAffected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) due to an incomplete fix for previously reported vulnerability [npm:ms:20151024](https://snyk.io/vuln/npm:ms:20151024). The fix limited the length of accepted input string to 10,000 characters, and turned to be insufficient making it possible to block the event loop for 0.3 seconds (on a typical laptop) with a specially crafted string passed to `ms()` function.\\r\\n\\r\\n*Proof of concept*\\r\\n```js\\r\\nms = require('ms');\\r\\nms('1'.repeat(9998) + 'Q') // Takes about ~0.3s\\r\\n```\\r\\n\\r\\n**Note:** Snyk's patch for this vulnerability limits input length to 100 characters. This new limit was deemed to be a breaking change by the author.\\r\\nBased on user feedback, we believe the risk of breakage is _very_ low, while the value to your security is much greater, and therefore opted to still capture this change in a patch for earlier versions as well. Whenever patching security issues, we always suggest to run tests on your code to validate that nothing has been broken.\\r\\n\\r\\nFor more information on `Regular Expression Denial of Service (ReDoS)` attacks, go to our [blog](https://snyk.io/blog/redos-and-catastrophic-backtracking/).\\r\\n\\r\\n# Disclosure Timeline\\r\\n- Feb 9th, 2017 - Reported the issue to package owner.\\r\\n- Feb 11th, 2017 - Issue acknowledged by package owner.\\r\\n- April 12th, 2017 - Fix PR opened by Snyk Security Team.\\r\\n- May 15th, 2017 - Vulnerability published.\\r\\n- May 16th, 2017 - Issue fixed and version `2.0.0` released.\\r\\n- May 21th, 2017 - Patches released for versions `\\u003e=0.7.1, \\u003c=1.0.0`.\\r\\n\\r\\n# Details\\r\\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.\\r\\n\\r\\nThe Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.\\r\\n\\r\\nLet’s take the following regular expression as an example:\\r\\n```js\\r\\nregex = /A(B|C+)+D/\\r\\n```\\r\\n\\r\\nThis regular expression accomplishes the following:\\r\\n- `A` The string must start with the letter 'A'\\r\\n- `(B|C+)+` The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the `+` matches one or more times). The `+` at the end of this section states that we can look for one or more matches of this section.\\r\\n- `D` Finally, we ensure this section of the string ends with a 'D'\\r\\n\\r\\nThe expression would match inputs such as `ABBD`, `ABCCCCD`, `ABCBCCCD` and `ACCCCCD`\\r\\n\\r\\nIt most cases, it doesn't take very long for a regex engine to find a match:\\r\\n\\r\\n```bash\\r\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD\\\")'\\r\\n0.04s user 0.01s system 95% cpu 0.052 total\\r\\n\\r\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX\\\")'\\r\\n1.79s user 0.02s system 99% cpu 1.812 total\\r\\n```\\r\\n\\r\\nThe entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.\\r\\n\\r\\nMost Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as _catastrophic backtracking_.\\r\\n\\r\\nLet's look at how our expression runs into this problem, using a shorter string: \\\"ACCCX\\\". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:\\r\\n1. CCC\\r\\n2. CC+C\\r\\n3. C+CC\\r\\n4. C+C+C.\\r\\n\\r\\nThe engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use [RegEx 101 debugger](https://regex101.com/debugger) to see the engine has to take a total of 38 steps before it can determine the string doesn't match.\\r\\n\\r\\nFrom there, the number of steps the engine must use to validate a string just continues to grow.\\r\\n\\r\\n| String | Number of C's | Number of steps |\\r\\n| -------|-------------:| -----:|\\r\\n| ACCCX | 3 | 38\\r\\n| ACCCCX | 4 | 71\\r\\n| ACCCCCX | 5 | 136\\r\\n| ACCCCCCCCCCCCCCX | 14 | 65,553\\r\\n\\r\\n\\r\\nBy the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.\\r\\n\\r\\n\\r\\n# Remediation\\r\\nUpgrade `ms` to version 2.0.0 or higher.\\r\\n\\r\\n# References\\r\\n- [GitHub PR](https://github.com/zeit/ms/pull/89)\\r\\n- [GitHub Commit](https://github.com/zeit/ms/pull/89/commits/305f2ddcd4eff7cc7c518aca6bb2b2d2daad8fef)\"},\"properties\":{\"cvssv3_baseScore\":3.7,\"security-severity\":\"3.7\",\"tags\":[\"security\",\"CWE-400\",\"npm\"]}} \n Message: This file introduces a vulnerable ms package with a low severity vulnerability.", + }, + { + Target: "pkg:npm/parsejson@0.0.3", + Type: "npm:parsejson:20170908", + Title: "This file introduces a vulnerable parsejson package with a high severity vulnerability.", + Severity: v1.Severity_SEVERITY_HIGH, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "MatchedRule: {\"id\":\"npm:parsejson:20170908\",\"shortDescription\":{\"text\":\"High severity - Regular Expression Denial of Service (ReDoS) vulnerability in parsejson\"},\"fullDescription\":{\"text\":\"(CVE-2017-16113) parsejson@0.0.3\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: npm\\n* Vulnerable module: parsejson\\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, socket.io@1.7.4 and others\\n### Detailed paths\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › engine.io-client@1.8.6 › parsejson@0.0.3\\n# Overview\\n\\n[parsejson](https://www.npmjs.com/package/parsejson) is a method that parses a JSON string and returns a JSON object.\\n\\n\\nAffected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) attacks.\\nAn attacker may pass a specially crafted JSON data, causing the server to hang.\\n\\n# Details\\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.\\r\\n\\r\\nThe Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.\\r\\n\\r\\nLet’s take the following regular expression as an example:\\r\\n```js\\r\\nregex = /A(B|C+)+D/\\r\\n```\\r\\n\\r\\nThis regular expression accomplishes the following:\\r\\n- `A` The string must start with the letter 'A'\\r\\n- `(B|C+)+` The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the `+` matches one or more times). The `+` at the end of this section states that we can look for one or more matches of this section.\\r\\n- `D` Finally, we ensure this section of the string ends with a 'D'\\r\\n\\r\\nThe expression would match inputs such as `ABBD`, `ABCCCCD`, `ABCBCCCD` and `ACCCCCD`\\r\\n\\r\\nIt most cases, it doesn't take very long for a regex engine to find a match:\\r\\n\\r\\n```bash\\r\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD\\\")'\\r\\n0.04s user 0.01s system 95% cpu 0.052 total\\r\\n\\r\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX\\\")'\\r\\n1.79s user 0.02s system 99% cpu 1.812 total\\r\\n```\\r\\n\\r\\nThe entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.\\r\\n\\r\\nMost Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as _catastrophic backtracking_.\\r\\n\\r\\nLet's look at how our expression runs into this problem, using a shorter string: \\\"ACCCX\\\". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:\\r\\n1. CCC\\r\\n2. CC+C\\r\\n3. C+CC\\r\\n4. C+C+C.\\r\\n\\r\\nThe engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use [RegEx 101 debugger](https://regex101.com/debugger) to see the engine has to take a total of 38 steps before it can determine the string doesn't match.\\r\\n\\r\\nFrom there, the number of steps the engine must use to validate a string just continues to grow.\\r\\n\\r\\n| String | Number of C's | Number of steps |\\r\\n| -------|-------------:| -----:|\\r\\n| ACCCX | 3 | 38\\r\\n| ACCCCX | 4 | 71\\r\\n| ACCCCCX | 5 | 136\\r\\n| ACCCCCCCCCCCCCCX | 14 | 65,553\\r\\n\\r\\n\\r\\nBy the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.\\n\\n# Remediation\\n\\nThere is no fixed version for `parsejson`.\\n\\n\\n# References\\n\\n- [GitHub Issue](https://github.com/get/parsejson/issues/4)\\n\"},\"properties\":{\"cvssv3_baseScore\":7.5,\"security-severity\":\"7.5\",\"tags\":[\"security\",\"CWE-400\",\"npm\"]}} \n Message: This file introduces a vulnerable parsejson package with a high severity vulnerability.", + }, + { + Target: "pkg:npm/uglify-js@2.2.5", + Type: "npm:uglify-js:20150824", + Title: "This file introduces a vulnerable uglify-js package with a high severity vulnerability.", + Severity: v1.Severity_SEVERITY_HIGH, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "MatchedRule: {\"id\":\"npm:uglify-js:20150824\",\"shortDescription\":{\"text\":\"High severity - Improper minification of non-boolean comparisons vulnerability in uglify-js\"},\"fullDescription\":{\"text\":\"(CVE-2015-8857) uglify-js@2.2.5\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: npm\\n* Vulnerable module: uglify-js\\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, jade@1.11.0 and others\\n### Detailed paths\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › jade@1.11.0 › transformers@2.1.0 › uglify-js@2.2.5\\n# Overview\\r\\n[`uglify-js`](http://npmjs.com/package/uglify-js) is a JavaScript parser, minifier, compressor and beautifier toolkit.\\r\\n\\r\\n[Tom MacWright](https://github.com/mishoo/UglifyJS2/issues/751) discovered that UglifyJS versions 2.4.23 and earlier are affected by a vulnerability which allows a specially crafted Javascript file to have altered functionality after minification. This bug was [demonstrated](https://zyan.scripts.mit.edu/blog/backdooring-js/) by [Yan](https://twitter.com/bcrypt) to allow potentially malicious code to be hidden within secure code, activated by minification.\\r\\n\\r\\n## Details\\r\\nIn Boolean algebra, DeMorgan's laws describe the relationships between conjunctions (`\\u0026\\u0026`), disjunctions (`||`) and negations (`!`).\\r\\nIn Javascript form, they state that:\\r\\n```savascript\\r\\n !(a \\u0026\\u0026 b) === (!a) || (!b)\\r\\n !(a || b) === (!a) \\u0026\\u0026 (!b)\\r\\n```\\r\\n\\r\\nThe law does not hold true when one of the values is not a boolean however.\\r\\n\\r\\nVulnerable versions of UglifyJS do not account for this restriction, and erroneously apply the laws to a statement if it can be reduced in length by it.\\r\\n\\r\\nConsider this authentication function:\\r\\n\\r\\n```javascript\\r\\nfunction isTokenValid(user) {\\r\\n var timeLeft =\\r\\n !!config \\u0026\\u0026 // config object exists\\r\\n !!user.token \\u0026\\u0026 // user object has a token\\r\\n !user.token.invalidated \\u0026\\u0026 // token is not explicitly invalidated\\r\\n !config.uninitialized \\u0026\\u0026 // config is initialized\\r\\n !config.ignoreTimestamps \\u0026\\u0026 // don't ignore timestamps\\r\\n getTimeLeft(user.token.expiry); // \\u003e 0 if expiration is in the future\\r\\n\\r\\n // The token must not be expired\\r\\n return timeLeft \\u003e 0;\\r\\n}\\r\\n\\r\\nfunction getTimeLeft(expiry) {\\r\\n return expiry - getSystemTime();\\r\\n}\\r\\n```\\r\\nWhen minified with a vulnerable version of UglifyJS, it will produce the following insecure output, where a token will never expire:\\r\\n\\r\\n( Formatted for readability )\\r\\n\\r\\n```javascript\\r\\nfunction isTokenValid(user) {\\r\\n var timeLeft = !( // negation\\r\\n !config // config object does not exist\\r\\n || !user.token // user object does not have a token\\r\\n || user.token.invalidated // token is explicitly invalidated\\r\\n || config.uninitialized // config isn't initialized\\r\\n || config.ignoreTimestamps // ignore timestamps\\r\\n || !getTimeLeft(user.token.expiry) // \\u003e 0 if expiration is in the future\\r\\n );\\r\\n return timeLeft \\u003e 0\\r\\n}\\r\\n\\r\\nfunction getTimeLeft(expiry) {\\r\\n return expiry - getSystemTime()\\r\\n}\\r\\n```\\r\\n\\r\\n# Remediation\\r\\nUpgrade UglifyJS to version `2.4.24` or higher.\\r\\n\\r\\n# References\\r\\n- [Blog Post](https://zyan.scripts.mit.edu/blog/backdooring-js/)\\r\\n- [GitHub Issue](https://github.com/mishoo/UglifyJS2/issues/751)\"},\"properties\":{\"cvssv3_baseScore\":8.3,\"security-severity\":\"8.3\",\"tags\":[\"security\",\"CWE-95\",\"npm\"]}} \n Message: This file introduces a vulnerable uglify-js package with a high severity vulnerability.", + }, + { + Target: "pkg:npm/uglify-js@2.2.5", + Type: "npm:uglify-js:20151024", + Title: "This file introduces a vulnerable uglify-js package with a medium severity vulnerability.", + Severity: v1.Severity_SEVERITY_MEDIUM, + Confidence: v1.Confidence_CONFIDENCE_UNSPECIFIED, + Description: "MatchedRule: {\"id\":\"npm:uglify-js:20151024\",\"shortDescription\":{\"text\":\"Medium severity - Regular Expression Denial of Service (ReDoS) vulnerability in uglify-js\"},\"fullDescription\":{\"text\":\"(CVE-2015-8858) uglify-js@2.2.5\"},\"help\":{\"text\":\"\",\"markdown\":\"* Package Manager: npm\\n* Vulnerable module: uglify-js\\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, jade@1.11.0 and others\\n### Detailed paths\\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › jade@1.11.0 › transformers@2.1.0 › uglify-js@2.2.5\\n# Overview\\r\\nThe `parse()` function in the [`uglify-js`](https://www.npmjs.com/package/uglify-js) package prior to version 2.6.0 is vulnerable to regular expression denial of service (ReDoS) attacks when long inputs of certain patterns are processed.\\r\\n\\r\\n# Details\\r\\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.\\r\\n\\r\\nThe Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.\\r\\n\\r\\nLet’s take the following regular expression as an example:\\r\\n```js\\r\\nregex = /A(B|C+)+D/\\r\\n```\\r\\n\\r\\nThis regular expression accomplishes the following:\\r\\n- `A` The string must start with the letter 'A'\\r\\n- `(B|C+)+` The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the `+` matches one or more times). The `+` at the end of this section states that we can look for one or more matches of this section.\\r\\n- `D` Finally, we ensure this section of the string ends with a 'D'\\r\\n\\r\\nThe expression would match inputs such as `ABBD`, `ABCCCCD`, `ABCBCCCD` and `ACCCCCD`\\r\\n\\r\\nIt most cases, it doesn't take very long for a regex engine to find a match:\\r\\n\\r\\n```bash\\r\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD\\\")'\\r\\n0.04s user 0.01s system 95% cpu 0.052 total\\r\\n\\r\\n$ time node -e '/A(B|C+)+D/.test(\\\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX\\\")'\\r\\n1.79s user 0.02s system 99% cpu 1.812 total\\r\\n```\\r\\n\\r\\nThe entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.\\r\\n\\r\\nMost Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as _catastrophic backtracking_.\\r\\n\\r\\nLet's look at how our expression runs into this problem, using a shorter string: \\\"ACCCX\\\". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:\\r\\n1. CCC\\r\\n2. CC+C\\r\\n3. C+CC\\r\\n4. C+C+C.\\r\\n\\r\\nThe engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use [RegEx 101 debugger](https://regex101.com/debugger) to see the engine has to take a total of 38 steps before it can determine the string doesn't match.\\r\\n\\r\\nFrom there, the number of steps the engine must use to validate a string just continues to grow.\\r\\n\\r\\n| String | Number of C's | Number of steps |\\r\\n| -------|-------------:| -----:|\\r\\n| ACCCX | 3 | 38\\r\\n| ACCCCX | 4 | 71\\r\\n| ACCCCCX | 5 | 136\\r\\n| ACCCCCCCCCCCCCCX | 14 | 65,553\\r\\n\\r\\n\\r\\nBy the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.\\r\\n\\r\\n# Remediation\\r\\nUpgrade to version `2.6.0` or greater.\\r\\nIf a direct dependency update is not possible, use `snyk wizard` to patch this vulnerability.\\r\\n\\r\\n# References\\r\\n- [OWASP - ReDoS](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS)\"},\"properties\":{\"cvssv3_baseScore\":5.3,\"security-severity\":\"5.3\",\"tags\":[\"security\",\"CWE-400\",\"npm\"]}} \n Message: This file introduces a vulnerable uglify-js package with a medium severity vulnerability.", + }, + } + + for _, run := range results.Runs { + rules := make(map[string]*sarif.ReportingDescriptor) + for _, rule := range run.Tool.Driver.Rules { + rules[rule.ID] = rule + } + issues, err := parseOut(*run, rules, "snyk-node", ExtraContextLanguageJS) + require.NoError(t, err) + require.NotEmpty(t, issues) + assert.EqualValues(t, expectedIssues, issues) + } + }) } func Test_ToSmithy(t *testing.T) { @@ -68,12 +233,12 @@ func Test_ToSmithy(t *testing.T) { require.NoError(t, err) var issues []*SmithyIssueCollection - issues, err = ToSmithy(string(trivyOutput)) + issues, err = ToSmithy(string(trivyOutput), ExtraContextLanguageUnspecified) require.NoError(t, err) expectedIssues := []*v1.Issue{ { - Target: "library/ubuntu:1-1", + Target: "file://library/ubuntu:1-1", Type: "CVE-2016-20013", Title: "Package: libc6\nInstalled Version: 2.35-0ubuntu3\nVulnerability CVE-2016-20013\nSeverity: LOW\nFixed Version: \nLink: [CVE-2016-20013](https://avd.aquasec.com/nvd/cve-2016-20013)", Severity: v1.Severity_SEVERITY_INFO, diff --git a/pkg/sarif/testdata/example_output.json b/pkg/sarif/testdata/example_output.json deleted file mode 100644 index 5aca2f4e5..000000000 --- a/pkg/sarif/testdata/example_output.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "runs": [{ - "results": [ - { - "level": "error", - "locations": [{ - "physicalLocation": { - "artifactLocation": { - "uri": "main.go" - }, - "region": { - "snippet": { - "text": "r := rand.New(rand.NewSource(time.Now().UnixNano()))" - }, - "sourceLanguage": "go", - "startColumn": 7, - "startLine": 83 - } - } - }], - "message": { - "text": "[test for missing endLine, common in some tools]" - }, - "ruleId": "G404" - }, - { - "level": "error", - "locations": [{ - "physicalLocation": { - "artifactLocation": { - "uri": "main.go" - }, - "region": { - "endColumn": 7, - "endLine": 83, - "snippet": { - "text": "r := rand.New(rand.NewSource(time.Now().UnixNano()))" - }, - "sourceLanguage": "go", - "startColumn": 7, - "startLine": 83 - } - } - }], - "message": { - "text": "Use of weak random number generator (math/rand instead of crypto/rand)" - }, - "ruleId": "G404" - }, - { - "level": "warning", - "locations": [{ - "physicalLocation": { - "artifactLocation": { - "uri": "main.go" - }, - "region": { - "endColumn": 2, - "endLine": 347, - "snippet": { - "text": "zipWriter.Close()" - }, - "sourceLanguage": "go", - "startColumn": 2, - "startLine": 347 - } - } - }], - "message": { - "text": "Errors unhandled." - }, - "ruleId": "G104", - "ruleIndex": 3 - } - ], - "tool": { - "driver": { - "guid": "8b518d5f-906d-39f9-894b-d327b1a421c5", - "informationUri": "https://github.com/securego/gosec/", - "name": "gosec" - } - } - }], - "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json", - "version": "2.1.0" -} diff --git a/pkg/sarif/testdata/gosec_output.json b/pkg/sarif/testdata/gosec_output.json new file mode 100644 index 000000000..3d8dff9bb --- /dev/null +++ b/pkg/sarif/testdata/gosec_output.json @@ -0,0 +1,143 @@ +{ + "runs": [{ + "results": [ + { + "level": "error", + "locations": [{ + "physicalLocation": { + "artifactLocation": { + "uri": "main.go" + }, + "region": { + "snippet": { + "text": "r := rand.New(rand.NewSource(time.Now().UnixNano()))" + }, + "sourceLanguage": "go", + "startColumn": 7, + "startLine": 83 + } + } + }], + "message": { + "text": "[test for missing endLine, common in some tools]" + }, + "ruleId": "G404" + }, + { + "level": "error", + "locations": [{ + "physicalLocation": { + "artifactLocation": { + "uri": "main.go" + }, + "region": { + "endColumn": 7, + "endLine": 83, + "snippet": { + "text": "r := rand.New(rand.NewSource(time.Now().UnixNano()))" + }, + "sourceLanguage": "go", + "startColumn": 7, + "startLine": 83 + } + } + }], + "message": { + "text": "Use of weak random number generator (math/rand instead of crypto/rand)" + }, + "ruleId": "G404" + }, + { + "level": "error", + "locations": [{ + "physicalLocation": { + "artifactLocation": { + "uri": "main.go" + }, + "region": { + "snippet": { + "text": "r := rand.New(rand.NewSource(time.Now().UnixNano()))" + }, + "sourceLanguage": "go", + "startLine": 83 + } + } + }], + "message": { + "text": "Use of weak random number generator (math/rand instead of crypto/rand) - nil endline" + }, + "ruleId": "G404" + }, + { + "level": "error", + "locations": [{ + "physicalLocation": { + "artifactLocation": { + "uri": "main.go" + }, + "region": { + "snippet": { + "text": "r := rand.New(rand.NewSource(time.Now().UnixNano()))" + }, + "sourceLanguage": "go", + "endLine": 83 + } + } + }], + "message": { + "text": "Use of weak random number generator (math/rand instead of crypto/rand) - nil startline" + }, + "ruleId": "G404" + }, + { + "level": "warning", + "locations": [{ + "physicalLocation": { + "artifactLocation": { + "uri": "main.go" + }, + "region": { + "endColumn": 2, + "endLine": 347, + "snippet": { + "text": "zipWriter.Close()" + }, + "sourceLanguage": "go", + "startColumn": 2, + "startLine": 347 + } + } + }], + "message": { + "text": "Errors unhandled." + }, + "ruleId": "G104", + "ruleIndex": 3 + }, + { + "level": "error", + "locations": [{ + "physicalLocation": { + "artifactLocation": { + "uri": "pkg:npm/%40angular/animation@12.3.1" + } + } + }], + "message": { + "text": "Vulnerable SQL injection code." + }, + "ruleId": "G104", + "ruleIndex": 3 + } + ], + "tool": { + "driver": { + "guid": "8b518d5f-906d-39f9-894b-d327b1a421c5", + "informationUri": "https://github.com/securego/gosec/", + "name": "gosec" + } + } + }], + "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json", + "version": "2.1.0" +} diff --git a/pkg/sarif/testdata/snyk-node_output.json b/pkg/sarif/testdata/snyk-node_output.json new file mode 100644 index 000000000..047c3c3ba --- /dev/null +++ b/pkg/sarif/testdata/snyk-node_output.json @@ -0,0 +1,1048 @@ +{ + "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json", + "version": "2.1.0", + "runs": [ + { + "tool": { + "driver": { + "name": "Snyk Open Source", + "semanticVersion": "1.1294.0", + "version": "1.1294.0", + "informationUri": "https://docs.snyk.io/", + "properties": {}, + "rules": [ + { + "id": "SNYK-JS-COOKIE-8163060", + "shortDescription": { + "text": "Medium severity - Cross-site Scripting (XSS) vulnerability in cookie" + }, + "fullDescription": { + "text": "(CVE-2024-47764) cookie@0.3.1" + }, + "help": { + "text": "", + "markdown": "* Package Manager: npm\n* Vulnerable module: cookie\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, socket.io@1.7.4 and others\n### Detailed paths\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › engine.io@1.8.5 › cookie@0.3.1\n# Overview\n\nAffected versions of this package are vulnerable to Cross-site Scripting (XSS) via the cookie `name`, `path`, or `domain`, which can be used to set unexpected values to other cookie fields.\r\n\r\n# Workaround\r\nUsers who are not able to upgrade to the fixed version should avoid passing untrusted or arbitrary values for the cookie fields and ensure they are set by the application instead of user input.\n# Details\n\nA cross-site scripting attack occurs when the attacker tricks a legitimate web-based application or site to accept a request as originating from a trusted source.\n\nThis is done by escaping the context of the web application; the web application then delivers that data to its users along with other trusted dynamic content, without validating it. The browser unknowingly executes malicious script on the client side (through client-side languages; usually JavaScript or HTML) in order to perform actions that are otherwise typically blocked by the browser’s Same Origin Policy.\n\nInjecting malicious code is the most prevalent manner by which XSS is exploited; for this reason, escaping characters in order to prevent this manipulation is the top method for securing code against this vulnerability.\n\nEscaping means that the application is coded to mark key characters, and particularly key characters included in user input, to prevent those characters from being interpreted in a dangerous context. For example, in HTML, `<` can be coded as `<`; and `>` can be coded as `>`; in order to be interpreted and displayed as themselves in text, while within the code itself, they are used for HTML tags. If malicious content is injected into an application that escapes special characters and that malicious content uses `<` and `>` as HTML tags, those characters are nonetheless not interpreted as HTML tags by the browser if they’ve been correctly escaped in the application code and in this way the attempted attack is diverted.\n \nThe most prominent use of XSS is to steal cookies (source: OWASP HttpOnly) and hijack user sessions, but XSS exploits have been used to expose sensitive information, enable access to privileged services and functionality and deliver malware. \n\n## Types of attacks\nThere are a few methods by which XSS can be manipulated:\n\n|Type|Origin|Description|\n|--|--|--|\n|**Stored**|Server|The malicious code is inserted in the application (usually as a link) by the attacker. The code is activated every time a user clicks the link.|\n|**Reflected**|Server|The attacker delivers a malicious link externally from the vulnerable web site application to a user. When clicked, malicious code is sent to the vulnerable web site, which reflects the attack back to the user’s browser.| \n|**DOM-based**|Client|The attacker forces the user’s browser to render a malicious page. The data in the page itself delivers the cross-site scripting data.|\n|**Mutated**| |The attacker injects code that appears safe, but is then rewritten and modified by the browser, while parsing the markup. An example is rebalancing unclosed quotation marks or even adding quotation marks to unquoted parameters.|\n\n## Affected environments\nThe following environments are susceptible to an XSS attack:\n\n* Web servers\n* Application servers\n* Web application environments\n\n## How to prevent\nThis section describes the top best practices designed to specifically protect your code: \n\n* Sanitize data input in an HTTP request before reflecting it back, ensuring all data is validated, filtered or escaped before echoing anything back to the user, such as the values of query parameters during searches. \n* Convert special characters such as `?`, `&`, `/`, `<`, `>` and spaces to their respective HTML or URL encoded equivalents. \n* Give users the option to disable client-side scripts.\n* Redirect invalid requests.\n* Detect simultaneous logins, including those from two separate IP addresses, and invalidate those sessions.\n* Use and enforce a Content Security Policy (source: Wikipedia) to disable any features that might be manipulated for an XSS attack.\n* Read the documentation for any of the libraries referenced in your code to understand which elements allow for embedded HTML.\n\n# Remediation\nUpgrade `cookie` to version 0.7.0 or higher.\n# References\n- [GitHub Commit](https://github.com/jshttp/cookie/commit/e10042845354fea83bd8f34af72475eed1dadf5c)\n- [GitHub PR](https://github.com/jshttp/cookie/pull/167)\n- [Red Hat Bugzilla Bug](https://bugzilla.redhat.com/show_bug.cgi?id=2316549)\n" + }, + "properties": { + "tags": [ + "security", + "CWE-79", + "npm" + ], + "cvssv3_baseScore": 6.3, + "security-severity": "6.3" + } + }, + { + "id": "SNYK-JS-ENGINEIO-1056749", + "shortDescription": { + "text": "High severity - Denial of Service (DoS) vulnerability in engine.io" + }, + "fullDescription": { + "text": "(CVE-2020-36048) engine.io@1.8.5" + }, + "help": { + "text": "", + "markdown": "* Package Manager: npm\n* Vulnerable module: engine.io\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, socket.io@1.7.4 and others\n### Detailed paths\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › engine.io@1.8.5\n# Overview\n[engine.io](https://github.com/socketio/engine.io) is a realtime engine behind Socket.IO. It provides the foundation of a bidirectional connection between client and server\n\nAffected versions of this package are vulnerable to Denial of Service (DoS) via a POST request to the long polling transport.\n\n# Details\n\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.\n\nUnlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.\n\nOne popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.\n\nWhen it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.\n\nTwo common types of DoS vulnerabilities:\n\n* High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, [commons-fileupload:commons-fileupload](https://security.snyk.io/vuln/SNYK-JAVA-COMMONSFILEUPLOAD-30082).\n\n* Crash - An attacker sending crafted requests that could cause the system to crash. For Example, [npm `ws` package](https://snyk.io/vuln/npm:ws:20171108)\n\n# Remediation\nUpgrade `engine.io` to version 3.6.0 or higher.\n# References\n- [GitHub Commit](https://github.com/socketio/engine.io/commit/58e274c437e9cbcf69fd913c813aad8fbd253703)\n- [GitHub Commit](https://github.com/socketio/engine.io/commit/734f9d1268840722c41219e69eb58318e0b2ac6b)\n- [GitHub Tags](https://github.com/socketio/engine.io/releases/tag/3.6.0)\n- [PoC](https://github.com/bcaller/kill-engine-io)\n- [Research Blogpost](https://blog.caller.xyz/socketio-engineio-dos/)\n" + }, + "properties": { + "tags": [ + "security", + "CWE-400", + "npm" + ], + "cvssv3_baseScore": 7.5, + "security-severity": "7.5" + } + }, + { + "id": "SNYK-JS-ENGINEIO-3136336", + "shortDescription": { + "text": "High severity - Denial of Service (DoS) vulnerability in engine.io" + }, + "fullDescription": { + "text": "(CVE-2022-41940) engine.io@1.8.5" + }, + "help": { + "text": "", + "markdown": "* Package Manager: npm\n* Vulnerable module: engine.io\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, socket.io@1.7.4 and others\n### Detailed paths\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › engine.io@1.8.5\n# Overview\n[engine.io](https://github.com/socketio/engine.io) is a realtime engine behind Socket.IO. It provides the foundation of a bidirectional connection between client and server\n\nAffected versions of this package are vulnerable to Denial of Service (DoS). A malicious client could send a specially crafted HTTP request, triggering an uncaught exception and killing the `Node.js` process.\n\n# Details\n\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.\n\nUnlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.\n\nOne popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.\n\nWhen it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.\n\nTwo common types of DoS vulnerabilities:\n\n* High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, [commons-fileupload:commons-fileupload](https://security.snyk.io/vuln/SNYK-JAVA-COMMONSFILEUPLOAD-30082).\n\n* Crash - An attacker sending crafted requests that could cause the system to crash. For Example, [npm `ws` package](https://snyk.io/vuln/npm:ws:20171108)\n\n# Remediation\nUpgrade `engine.io` to version 3.6.1, 6.2.1 or higher.\n# References\n- [GitHub Commit](https://github.com/socketio/engine.io/commit/425e833ab13373edf1dd5a0706f07100db14e3c6)\n- [GitHub Commit](https://github.com/socketio/engine.io/commit/83c4071af871fc188298d7d591e95670bf9f9085)\n- [GitHub PR](https://github.com/socketio/engine.io/pull/658)\n" + }, + "properties": { + "tags": [ + "security", + "CWE-400", + "npm" + ], + "cvssv3_baseScore": 7.5, + "security-severity": "7.5" + } + }, + { + "id": "SNYK-JS-SOCKETIO-1024859", + "shortDescription": { + "text": "Medium severity - Insecure Defaults vulnerability in socket.io" + }, + "fullDescription": { + "text": "(CVE-2020-28481) socket.io@1.7.4" + }, + "help": { + "text": "", + "markdown": "* Package Manager: npm\n* Vulnerable module: socket.io\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 and socket.io@1.7.4\n### Detailed paths\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4\n# Overview\n[socket.io](https://github.com/socketio/socket.io) is a node.js realtime framework server.\n\nAffected versions of this package are vulnerable to Insecure Defaults due to CORS Misconfiguration. All domains are whitelisted by default.\n# Remediation\nUpgrade `socket.io` to version 2.4.0 or higher.\n# References\n- [GitHub Issue](https://github.com/socketio/socket.io/issues/3671)\n- [HackerOne Report](https://hackerone.com/reports/931197)\n" + }, + "properties": { + "tags": [ + "security", + "CWE-453", + "npm" + ], + "cvssv3_baseScore": 5.3, + "security-severity": "5.3" + } + }, + { + "id": "SNYK-JS-SOCKETIOPARSER-1056752", + "shortDescription": { + "text": "High severity - Denial of Service (DoS) vulnerability in socket.io-parser" + }, + "fullDescription": { + "text": "(CVE-2020-36049) socket.io-parser@2.3.1" + }, + "help": { + "text": "", + "markdown": "* Package Manager: npm\n* Vulnerable module: socket.io-parser\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, socket.io@1.7.4 and others\n### Detailed paths\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-parser@2.3.1\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-adapter@0.5.0 › socket.io-parser@2.3.1\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › socket.io-parser@2.3.1\n# Overview\n[socket.io-parser](https://www.npmjs.org/package/socket.io-parser) is a socket.io protocol parser\n\nAffected versions of this package are vulnerable to Denial of Service (DoS) via a large packet because a concatenation approach is used.\n\n# Details\n\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its intended and legitimate users.\n\nUnlike other vulnerabilities, DoS attacks usually do not aim at breaching security. Rather, they are focused on making websites and services unavailable to genuine users resulting in downtime.\n\nOne popular Denial of Service vulnerability is DDoS (a Distributed Denial of Service), an attack that attempts to clog network pipes to the system by generating a large volume of traffic from many machines.\n\nWhen it comes to open source libraries, DoS vulnerabilities allow attackers to trigger such a crash or crippling of the service by using a flaw either in the application code or from the use of open source libraries.\n\nTwo common types of DoS vulnerabilities:\n\n* High CPU/Memory Consumption- An attacker sending crafted requests that could cause the system to take a disproportionate amount of time to process. For example, [commons-fileupload:commons-fileupload](https://security.snyk.io/vuln/SNYK-JAVA-COMMONSFILEUPLOAD-30082).\n\n* Crash - An attacker sending crafted requests that could cause the system to crash. For Example, [npm `ws` package](https://snyk.io/vuln/npm:ws:20171108)\n\n# Remediation\nUpgrade `socket.io-parser` to version 3.3.2, 3.4.1 or higher.\n# References\n- [GitHub Commit](https://github.com/socketio/socket.io-parser/commit/dcb942d24db97162ad16a67c2a0cf30875342d55)\n- [PoC](https://github.com/bcaller/kill-engine-io)\n- [Research Blogpost](https://blog.caller.xyz/socketio-engineio-dos/)\n" + }, + "properties": { + "tags": [ + "security", + "CWE-400", + "npm" + ], + "cvssv3_baseScore": 7.5, + "security-severity": "7.5" + } + }, + { + "id": "SNYK-JS-SOCKETIOPARSER-3091012", + "shortDescription": { + "text": "Critical severity - Improper Input Validation vulnerability in socket.io-parser" + }, + "fullDescription": { + "text": "(CVE-2022-2421) socket.io-parser@2.3.1" + }, + "help": { + "text": "", + "markdown": "* Package Manager: npm\n* Vulnerable module: socket.io-parser\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, socket.io@1.7.4 and others\n### Detailed paths\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-parser@2.3.1\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-adapter@0.5.0 › socket.io-parser@2.3.1\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › socket.io-parser@2.3.1\n# Overview\n\n[socket.io-parser](https://www.npmjs.org/package/socket.io-parser) is a socket.io protocol parser\n\n\nAffected versions of this package are vulnerable to Improper Input Validation.\nwhen parsing attachments containing untrusted user input. Attackers can overwrite the `_placeholder` object to place references to functions in query objects.\r\n\r\n# PoC\r\n\r\n```js\r\nconst decoder = new Decoder();\r\n\r\ndecoder.on(\"decoded\", (packet) => {\r\n console.log(packet.data); // prints [ 'hello', [Function: splice] ]\r\n})\r\n\r\ndecoder.add('51-[\"hello\",{\"_placeholder\":true,\"num\":\"splice\"}]');\r\ndecoder.add(Buffer.from(\"world\"));\r\n```\n\n# Remediation\n\nUpgrade `socket.io-parser` to version 3.3.3, 3.4.2, 4.0.5, 4.2.1 or higher.\n\n\n# References\n\n- [GitHub Commit](https://github.com/socketio/socket.io-parser/commit/b559f050ee02bd90bd853b9823f8de7fa94a80d4)\n\n- [GitHub Commit](https://github.com/socketio/socket.io-parser/commit/b5d0cb7dc56a0601a09b056beaeeb0e43b160050)\n\n- [Vulnerability Report](https://csirt.divd.nl/cases/DIVD-2022-00045)\n\n- [Vulnerability Report](https://csirt.divd.nl/cves/CVE-2022-2421)\n" + }, + "properties": { + "tags": [ + "security", + "CWE-89", + "npm" + ], + "cvssv3_baseScore": 9.8, + "security-severity": "9.8" + } + }, + { + "id": "SNYK-JS-UGLIFYJS-1727251", + "shortDescription": { + "text": "Medium severity - Regular Expression Denial of Service (ReDoS) vulnerability in uglify-js" + }, + "fullDescription": { + "text": "uglify-js@2.2.5" + }, + "help": { + "text": "", + "markdown": "* Package Manager: npm\n* Vulnerable module: uglify-js\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, jade@1.11.0 and others\n### Detailed paths\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › jade@1.11.0 › transformers@2.1.0 › uglify-js@2.2.5\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › jade@1.11.0 › uglify-js@2.8.29\n# Overview\n[uglify-js](http://npmjs.com/package/uglify-js) is a JavaScript parser, minifier, compressor and beautifier toolkit.\n\nAffected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) via the `string_template` and the `decode_template` functions.\n\n# Details\n\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.\n\nThe Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.\n\nLet’s take the following regular expression as an example:\n```js\nregex = /A(B|C+)+D/\n```\n\nThis regular expression accomplishes the following:\n- `A` The string must start with the letter 'A'\n- `(B|C+)+` The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the `+` matches one or more times). The `+` at the end of this section states that we can look for one or more matches of this section.\n- `D` Finally, we ensure this section of the string ends with a 'D'\n\nThe expression would match inputs such as `ABBD`, `ABCCCCD`, `ABCBCCCD` and `ACCCCCD`\n\nIt most cases, it doesn't take very long for a regex engine to find a match:\n\n```bash\n$ time node -e '/A(B|C+)+D/.test(\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD\")'\n0.04s user 0.01s system 95% cpu 0.052 total\n\n$ time node -e '/A(B|C+)+D/.test(\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX\")'\n1.79s user 0.02s system 99% cpu 1.812 total\n```\n\nThe entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.\n\nMost Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as _catastrophic backtracking_.\n\nLet's look at how our expression runs into this problem, using a shorter string: \"ACCCX\". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:\n1. CCC\n2. CC+C\n3. C+CC\n4. C+C+C.\n\nThe engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use [RegEx 101 debugger](https://regex101.com/debugger) to see the engine has to take a total of 38 steps before it can determine the string doesn't match.\n\nFrom there, the number of steps the engine must use to validate a string just continues to grow.\n\n| String | Number of C's | Number of steps |\n| -------|-------------:| -----:|\n| ACCCX | 3 | 38\n| ACCCCX | 4 | 71\n| ACCCCCX | 5 | 136\n| ACCCCCCCCCCCCCCX | 14 | 65,553\n\n\nBy the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.\n\n# Remediation\nUpgrade `uglify-js` to version 3.14.3 or higher.\n# References\n- [GitHub Commit](https://github.com/mishoo/UglifyJS/commit/157521066fc43cff2feab7ffc1ecea603617606b)\n- [GitHub Issue](https://github.com/mishoo/UglifyJS/issues/5133)\n- [GitHub PR](https://github.com/mishoo/UglifyJS/pull/5134)\n- [GitHub PR](https://github.com/mishoo/UglifyJS/pull/5135)\n" + }, + "properties": { + "tags": [ + "security", + "CWE-1333", + "npm" + ], + "cvssv3_baseScore": 5.3, + "security-severity": "5.3" + } + }, + { + "id": "SNYK-JS-WS-1296835", + "shortDescription": { + "text": "Medium severity - Regular Expression Denial of Service (ReDoS) vulnerability in ws" + }, + "fullDescription": { + "text": "(CVE-2021-32640) ws@1.1.5" + }, + "help": { + "text": "", + "markdown": "* Package Manager: npm\n* Vulnerable module: ws\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, socket.io@1.7.4 and others\n### Detailed paths\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › engine.io@1.8.5 › ws@1.1.5\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › engine.io-client@1.8.6 › ws@1.1.5\n# Overview\n[ws](https://www.npmjs.com/package/ws) is a simple to use websocket client, server and console for node.js.\n\nAffected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS). A specially crafted value of the `Sec-Websocket-Protocol` header can be used to significantly slow down a `ws` server.\r\n\r\n##PoC\r\n```\r\nfor (const length of [1000, 2000, 4000, 8000, 16000, 32000]) {\r\n const value = 'b' + ' '.repeat(length) + 'x';\r\n const start = process.hrtime.bigint();\r\n\r\n value.trim().split(/ *, */);\r\n\r\n const end = process.hrtime.bigint();\r\n\r\n console.log('length = %d, time = %f ns', length, end - start);\r\n}\r\n```\n\n# Details\n\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.\n\nThe Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.\n\nLet’s take the following regular expression as an example:\n```js\nregex = /A(B|C+)+D/\n```\n\nThis regular expression accomplishes the following:\n- `A` The string must start with the letter 'A'\n- `(B|C+)+` The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the `+` matches one or more times). The `+` at the end of this section states that we can look for one or more matches of this section.\n- `D` Finally, we ensure this section of the string ends with a 'D'\n\nThe expression would match inputs such as `ABBD`, `ABCCCCD`, `ABCBCCCD` and `ACCCCCD`\n\nIt most cases, it doesn't take very long for a regex engine to find a match:\n\n```bash\n$ time node -e '/A(B|C+)+D/.test(\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD\")'\n0.04s user 0.01s system 95% cpu 0.052 total\n\n$ time node -e '/A(B|C+)+D/.test(\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX\")'\n1.79s user 0.02s system 99% cpu 1.812 total\n```\n\nThe entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.\n\nMost Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as _catastrophic backtracking_.\n\nLet's look at how our expression runs into this problem, using a shorter string: \"ACCCX\". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:\n1. CCC\n2. CC+C\n3. C+CC\n4. C+C+C.\n\nThe engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use [RegEx 101 debugger](https://regex101.com/debugger) to see the engine has to take a total of 38 steps before it can determine the string doesn't match.\n\nFrom there, the number of steps the engine must use to validate a string just continues to grow.\n\n| String | Number of C's | Number of steps |\n| -------|-------------:| -----:|\n| ACCCX | 3 | 38\n| ACCCCX | 4 | 71\n| ACCCCCX | 5 | 136\n| ACCCCCCCCCCCCCCX | 14 | 65,553\n\n\nBy the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.\n\n# Remediation\nUpgrade `ws` to version 7.4.6, 6.2.2, 5.2.3 or higher.\n# References\n- [GitHub Commit](https://github.com/websockets/ws/commit/00c425ec77993773d823f018f64a5c44e17023ff)\n" + }, + "properties": { + "tags": [ + "security", + "CWE-400", + "npm" + ], + "cvssv3_baseScore": 5.3, + "security-severity": "5.3" + } + }, + { + "id": "npm:clean-css:20180306", + "shortDescription": { + "text": "Low severity - Regular Expression Denial of Service (ReDoS) vulnerability in clean-css" + }, + "fullDescription": { + "text": "clean-css@3.4.28" + }, + "help": { + "text": "", + "markdown": "* Package Manager: npm\n* Vulnerable module: clean-css\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, jade@1.11.0 and others\n### Detailed paths\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › jade@1.11.0 › clean-css@3.4.28\n# Overview\n\n[clean-css](https://www.npmjs.com/package/clean-css) is a fast and efficient CSS optimizer for Node.js platform and any modern browser.\n\n\nAffected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS).\nattacks. This can cause an impact of about 10 seconds matching time for data 70k characters long.\n\n# Disclosure Timeline\n* Feb 15th, 2018 - Initial Disclosure to package owner\n* Feb 20th, 2018 - Initial Response from package owner\n* Mar 6th, 2018 - Fix issued\n* Mar 7th, 2018 - Vulnerability published\n\n# Details\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.\r\n\r\nThe Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.\r\n\r\nLet’s take the following regular expression as an example:\r\n```js\r\nregex = /A(B|C+)+D/\r\n```\r\n\r\nThis regular expression accomplishes the following:\r\n- `A` The string must start with the letter 'A'\r\n- `(B|C+)+` The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the `+` matches one or more times). The `+` at the end of this section states that we can look for one or more matches of this section.\r\n- `D` Finally, we ensure this section of the string ends with a 'D'\r\n\r\nThe expression would match inputs such as `ABBD`, `ABCCCCD`, `ABCBCCCD` and `ACCCCCD`\r\n\r\nIt most cases, it doesn't take very long for a regex engine to find a match:\r\n\r\n```bash\r\n$ time node -e '/A(B|C+)+D/.test(\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD\")'\r\n0.04s user 0.01s system 95% cpu 0.052 total\r\n\r\n$ time node -e '/A(B|C+)+D/.test(\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX\")'\r\n1.79s user 0.02s system 99% cpu 1.812 total\r\n```\r\n\r\nThe entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.\r\n\r\nMost Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as _catastrophic backtracking_.\r\n\r\nLet's look at how our expression runs into this problem, using a shorter string: \"ACCCX\". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:\r\n1. CCC\r\n2. CC+C\r\n3. C+CC\r\n4. C+C+C.\r\n\r\nThe engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use [RegEx 101 debugger](https://regex101.com/debugger) to see the engine has to take a total of 38 steps before it can determine the string doesn't match.\r\n\r\nFrom there, the number of steps the engine must use to validate a string just continues to grow.\r\n\r\n| String | Number of C's | Number of steps |\r\n| -------|-------------:| -----:|\r\n| ACCCX | 3 | 38\r\n| ACCCCX | 4 | 71\r\n| ACCCCCX | 5 | 136\r\n| ACCCCCCCCCCCCCCX | 14 | 65,553\r\n\r\n\r\nBy the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.\n\n# Remediation\n\nUpgrade `clean-css` to version 4.1.11 or higher.\n\n\n# References\n\n- [GitHub Advisory](https://github.com/advisories/GHSA-wxhq-pm8v-cw75)\n\n- [GitHub Commit](https://github.com/jakubpawlowicz/clean-css/commit/2929bafbf8cdf7dccb24e0949c70833764fa87e3)\n" + }, + "properties": { + "tags": [ + "security", + "CWE-185", + "CWE-400", + "npm" + ], + "cvssv3_baseScore": 3.7, + "security-severity": "3.7" + } + }, + { + "id": "npm:constantinople:20180421", + "shortDescription": { + "text": "Critical severity - Sandbox Bypass vulnerability in constantinople" + }, + "fullDescription": { + "text": "constantinople@3.0.2" + }, + "help": { + "text": "", + "markdown": "* Package Manager: npm\n* Vulnerable module: constantinople\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, jade@1.11.0 and others\n### Detailed paths\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › jade@1.11.0 › constantinople@3.0.2\n# Overview\n[constantinople](https://github.com/ForbesLindesay/constantinople) is a Determine whether a JavaScript expression evaluates to a constant (using acorn)\n\nAffected versions of this package are vulnerable to Sandbox Bypass which can lead to arbitrary code execution.\n# Remediation\nUpgrade `constantinople` to version 3.1.1 or higher.\n# References\n- [GitHub Commit](https://github.com/pugjs/constantinople/commit/01d409c0d081dfd65223e6b7767c244156d35f7f)\n" + }, + "properties": { + "tags": [ + "security", + "CWE-264", + "npm" + ], + "cvssv3_baseScore": 10, + "security-severity": "10" + } + }, + { + "id": "npm:debug:20170905", + "shortDescription": { + "text": "Low severity - Regular Expression Denial of Service (ReDoS) vulnerability in debug" + }, + "fullDescription": { + "text": "(CVE-2017-16137) debug@2.3.3" + }, + "help": { + "text": "", + "markdown": "* Package Manager: npm\n* Vulnerable module: debug\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, socket.io@1.7.4 and others\n### Detailed paths\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › debug@2.3.3\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › engine.io@1.8.5 › debug@2.3.3\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-adapter@0.5.0 › debug@2.3.3\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › debug@2.3.3\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › engine.io-client@1.8.6 › debug@2.3.3\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-parser@2.3.1 › debug@2.2.0\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-adapter@0.5.0 › socket.io-parser@2.3.1 › debug@2.2.0\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › socket.io-parser@2.3.1 › debug@2.2.0\n# Overview\n[debug](https://github.com/visionmedia/debug) is a small debugging utility.\n\nAffected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) in the function `useColors` via manipulation of the `str` argument. \r\nThe vulnerability can cause a very low impact of about 2 seconds of matching time for data 50k characters long.\r\n\r\n**Note:**\r\nCVE-2017-20165 is a duplicate of this vulnerability.\r\n\r\n# PoC\r\n\r\nUse the following regex in the `%o` formatter.\r\n```js\r\n/\\s*\\n\\s*/\r\n```\n\n# Details\n\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.\n\nThe Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.\n\nLet’s take the following regular expression as an example:\n```js\nregex = /A(B|C+)+D/\n```\n\nThis regular expression accomplishes the following:\n- `A` The string must start with the letter 'A'\n- `(B|C+)+` The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the `+` matches one or more times). The `+` at the end of this section states that we can look for one or more matches of this section.\n- `D` Finally, we ensure this section of the string ends with a 'D'\n\nThe expression would match inputs such as `ABBD`, `ABCCCCD`, `ABCBCCCD` and `ACCCCCD`\n\nIt most cases, it doesn't take very long for a regex engine to find a match:\n\n```bash\n$ time node -e '/A(B|C+)+D/.test(\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD\")'\n0.04s user 0.01s system 95% cpu 0.052 total\n\n$ time node -e '/A(B|C+)+D/.test(\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX\")'\n1.79s user 0.02s system 99% cpu 1.812 total\n```\n\nThe entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.\n\nMost Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as _catastrophic backtracking_.\n\nLet's look at how our expression runs into this problem, using a shorter string: \"ACCCX\". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:\n1. CCC\n2. CC+C\n3. C+CC\n4. C+C+C.\n\nThe engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use [RegEx 101 debugger](https://regex101.com/debugger) to see the engine has to take a total of 38 steps before it can determine the string doesn't match.\n\nFrom there, the number of steps the engine must use to validate a string just continues to grow.\n\n| String | Number of C's | Number of steps |\n| -------|-------------:| -----:|\n| ACCCX | 3 | 38\n| ACCCCX | 4 | 71\n| ACCCCCX | 5 | 136\n| ACCCCCCCCCCCCCCX | 14 | 65,553\n\n\nBy the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.\n\n# Remediation\nUpgrade `debug` to version 2.6.9, 3.1.0, 3.2.7, 4.3.1 or higher.\n# References\n- [GitHub Commit](https://github.com/debug-js/debug/commit/b6d12fdbc63b483e5c969da33ea6adc09946b5ac)\n- [GitHub Commit](https://github.com/visionmedia/debug/pull/504/commits/42a6ae0737f9243c80b6d3dbb08a69a7ae2a1061)\n- [GitHub Issue](https://github.com/visionmedia/debug/issues/501)\n- [GitHub PR](https://github.com/visionmedia/debug/pull/504)\n- [GitHub Release Notes 2.6.9](https://github.com/debug-js/debug/releases/tag/2.6.9)\n- [GitHub Release Notes 3.1.0](https://github.com/debug-js/debug/releases/tag/3.1.0)\n" + }, + "properties": { + "tags": [ + "security", + "CWE-400", + "npm" + ], + "cvssv3_baseScore": 3.7, + "security-severity": "3.7" + } + }, + { + "id": "npm:ms:20170412", + "shortDescription": { + "text": "Low severity - Regular Expression Denial of Service (ReDoS) vulnerability in ms" + }, + "fullDescription": { + "text": "(CVE-2017-20162) ms@0.7.2" + }, + "help": { + "text": "", + "markdown": "* Package Manager: npm\n* Vulnerable module: ms\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, socket.io@1.7.4 and others\n### Detailed paths\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › debug@2.3.3 › ms@0.7.2\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › engine.io@1.8.5 › debug@2.3.3 › ms@0.7.2\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-adapter@0.5.0 › debug@2.3.3 › ms@0.7.2\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › debug@2.3.3 › ms@0.7.2\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › engine.io-client@1.8.6 › debug@2.3.3 › ms@0.7.2\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-parser@2.3.1 › debug@2.2.0 › ms@0.7.1\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-adapter@0.5.0 › socket.io-parser@2.3.1 › debug@2.2.0 › ms@0.7.1\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › socket.io-parser@2.3.1 › debug@2.2.0 › ms@0.7.1\n# Overview\r\n[`ms`](https://www.npmjs.com/package/ms) is a tiny millisecond conversion utility.\r\n\r\nAffected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) due to an incomplete fix for previously reported vulnerability [npm:ms:20151024](https://snyk.io/vuln/npm:ms:20151024). The fix limited the length of accepted input string to 10,000 characters, and turned to be insufficient making it possible to block the event loop for 0.3 seconds (on a typical laptop) with a specially crafted string passed to `ms()` function.\r\n\r\n*Proof of concept*\r\n```js\r\nms = require('ms');\r\nms('1'.repeat(9998) + 'Q') // Takes about ~0.3s\r\n```\r\n\r\n**Note:** Snyk's patch for this vulnerability limits input length to 100 characters. This new limit was deemed to be a breaking change by the author.\r\nBased on user feedback, we believe the risk of breakage is _very_ low, while the value to your security is much greater, and therefore opted to still capture this change in a patch for earlier versions as well. Whenever patching security issues, we always suggest to run tests on your code to validate that nothing has been broken.\r\n\r\nFor more information on `Regular Expression Denial of Service (ReDoS)` attacks, go to our [blog](https://snyk.io/blog/redos-and-catastrophic-backtracking/).\r\n\r\n# Disclosure Timeline\r\n- Feb 9th, 2017 - Reported the issue to package owner.\r\n- Feb 11th, 2017 - Issue acknowledged by package owner.\r\n- April 12th, 2017 - Fix PR opened by Snyk Security Team.\r\n- May 15th, 2017 - Vulnerability published.\r\n- May 16th, 2017 - Issue fixed and version `2.0.0` released.\r\n- May 21th, 2017 - Patches released for versions `>=0.7.1, <=1.0.0`.\r\n\r\n# Details\r\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.\r\n\r\nThe Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.\r\n\r\nLet’s take the following regular expression as an example:\r\n```js\r\nregex = /A(B|C+)+D/\r\n```\r\n\r\nThis regular expression accomplishes the following:\r\n- `A` The string must start with the letter 'A'\r\n- `(B|C+)+` The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the `+` matches one or more times). The `+` at the end of this section states that we can look for one or more matches of this section.\r\n- `D` Finally, we ensure this section of the string ends with a 'D'\r\n\r\nThe expression would match inputs such as `ABBD`, `ABCCCCD`, `ABCBCCCD` and `ACCCCCD`\r\n\r\nIt most cases, it doesn't take very long for a regex engine to find a match:\r\n\r\n```bash\r\n$ time node -e '/A(B|C+)+D/.test(\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD\")'\r\n0.04s user 0.01s system 95% cpu 0.052 total\r\n\r\n$ time node -e '/A(B|C+)+D/.test(\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX\")'\r\n1.79s user 0.02s system 99% cpu 1.812 total\r\n```\r\n\r\nThe entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.\r\n\r\nMost Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as _catastrophic backtracking_.\r\n\r\nLet's look at how our expression runs into this problem, using a shorter string: \"ACCCX\". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:\r\n1. CCC\r\n2. CC+C\r\n3. C+CC\r\n4. C+C+C.\r\n\r\nThe engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use [RegEx 101 debugger](https://regex101.com/debugger) to see the engine has to take a total of 38 steps before it can determine the string doesn't match.\r\n\r\nFrom there, the number of steps the engine must use to validate a string just continues to grow.\r\n\r\n| String | Number of C's | Number of steps |\r\n| -------|-------------:| -----:|\r\n| ACCCX | 3 | 38\r\n| ACCCCX | 4 | 71\r\n| ACCCCCX | 5 | 136\r\n| ACCCCCCCCCCCCCCX | 14 | 65,553\r\n\r\n\r\nBy the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.\r\n\r\n\r\n# Remediation\r\nUpgrade `ms` to version 2.0.0 or higher.\r\n\r\n# References\r\n- [GitHub PR](https://github.com/zeit/ms/pull/89)\r\n- [GitHub Commit](https://github.com/zeit/ms/pull/89/commits/305f2ddcd4eff7cc7c518aca6bb2b2d2daad8fef)" + }, + "properties": { + "tags": [ + "security", + "CWE-400", + "npm" + ], + "cvssv3_baseScore": 3.7, + "security-severity": "3.7" + } + }, + { + "id": "npm:parsejson:20170908", + "shortDescription": { + "text": "High severity - Regular Expression Denial of Service (ReDoS) vulnerability in parsejson" + }, + "fullDescription": { + "text": "(CVE-2017-16113) parsejson@0.0.3" + }, + "help": { + "text": "", + "markdown": "* Package Manager: npm\n* Vulnerable module: parsejson\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, socket.io@1.7.4 and others\n### Detailed paths\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › socket.io@1.7.4 › socket.io-client@1.7.4 › engine.io-client@1.8.6 › parsejson@0.0.3\n# Overview\n\n[parsejson](https://www.npmjs.com/package/parsejson) is a method that parses a JSON string and returns a JSON object.\n\n\nAffected versions of this package are vulnerable to Regular Expression Denial of Service (ReDoS) attacks.\nAn attacker may pass a specially crafted JSON data, causing the server to hang.\n\n# Details\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.\r\n\r\nThe Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.\r\n\r\nLet’s take the following regular expression as an example:\r\n```js\r\nregex = /A(B|C+)+D/\r\n```\r\n\r\nThis regular expression accomplishes the following:\r\n- `A` The string must start with the letter 'A'\r\n- `(B|C+)+` The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the `+` matches one or more times). The `+` at the end of this section states that we can look for one or more matches of this section.\r\n- `D` Finally, we ensure this section of the string ends with a 'D'\r\n\r\nThe expression would match inputs such as `ABBD`, `ABCCCCD`, `ABCBCCCD` and `ACCCCCD`\r\n\r\nIt most cases, it doesn't take very long for a regex engine to find a match:\r\n\r\n```bash\r\n$ time node -e '/A(B|C+)+D/.test(\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD\")'\r\n0.04s user 0.01s system 95% cpu 0.052 total\r\n\r\n$ time node -e '/A(B|C+)+D/.test(\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX\")'\r\n1.79s user 0.02s system 99% cpu 1.812 total\r\n```\r\n\r\nThe entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.\r\n\r\nMost Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as _catastrophic backtracking_.\r\n\r\nLet's look at how our expression runs into this problem, using a shorter string: \"ACCCX\". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:\r\n1. CCC\r\n2. CC+C\r\n3. C+CC\r\n4. C+C+C.\r\n\r\nThe engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use [RegEx 101 debugger](https://regex101.com/debugger) to see the engine has to take a total of 38 steps before it can determine the string doesn't match.\r\n\r\nFrom there, the number of steps the engine must use to validate a string just continues to grow.\r\n\r\n| String | Number of C's | Number of steps |\r\n| -------|-------------:| -----:|\r\n| ACCCX | 3 | 38\r\n| ACCCCX | 4 | 71\r\n| ACCCCCX | 5 | 136\r\n| ACCCCCCCCCCCCCCX | 14 | 65,553\r\n\r\n\r\nBy the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.\n\n# Remediation\n\nThere is no fixed version for `parsejson`.\n\n\n# References\n\n- [GitHub Issue](https://github.com/get/parsejson/issues/4)\n" + }, + "properties": { + "tags": [ + "security", + "CWE-400", + "npm" + ], + "cvssv3_baseScore": 7.5, + "security-severity": "7.5" + } + }, + { + "id": "npm:uglify-js:20150824", + "shortDescription": { + "text": "High severity - Improper minification of non-boolean comparisons vulnerability in uglify-js" + }, + "fullDescription": { + "text": "(CVE-2015-8857) uglify-js@2.2.5" + }, + "help": { + "text": "", + "markdown": "* Package Manager: npm\n* Vulnerable module: uglify-js\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, jade@1.11.0 and others\n### Detailed paths\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › jade@1.11.0 › transformers@2.1.0 › uglify-js@2.2.5\n# Overview\r\n[`uglify-js`](http://npmjs.com/package/uglify-js) is a JavaScript parser, minifier, compressor and beautifier toolkit.\r\n\r\n[Tom MacWright](https://github.com/mishoo/UglifyJS2/issues/751) discovered that UglifyJS versions 2.4.23 and earlier are affected by a vulnerability which allows a specially crafted Javascript file to have altered functionality after minification. This bug was [demonstrated](https://zyan.scripts.mit.edu/blog/backdooring-js/) by [Yan](https://twitter.com/bcrypt) to allow potentially malicious code to be hidden within secure code, activated by minification.\r\n\r\n## Details\r\nIn Boolean algebra, DeMorgan's laws describe the relationships between conjunctions (`&&`), disjunctions (`||`) and negations (`!`).\r\nIn Javascript form, they state that:\r\n```savascript\r\n !(a && b) === (!a) || (!b)\r\n !(a || b) === (!a) && (!b)\r\n```\r\n\r\nThe law does not hold true when one of the values is not a boolean however.\r\n\r\nVulnerable versions of UglifyJS do not account for this restriction, and erroneously apply the laws to a statement if it can be reduced in length by it.\r\n\r\nConsider this authentication function:\r\n\r\n```javascript\r\nfunction isTokenValid(user) {\r\n var timeLeft =\r\n !!config && // config object exists\r\n !!user.token && // user object has a token\r\n !user.token.invalidated && // token is not explicitly invalidated\r\n !config.uninitialized && // config is initialized\r\n !config.ignoreTimestamps && // don't ignore timestamps\r\n getTimeLeft(user.token.expiry); // > 0 if expiration is in the future\r\n\r\n // The token must not be expired\r\n return timeLeft > 0;\r\n}\r\n\r\nfunction getTimeLeft(expiry) {\r\n return expiry - getSystemTime();\r\n}\r\n```\r\nWhen minified with a vulnerable version of UglifyJS, it will produce the following insecure output, where a token will never expire:\r\n\r\n( Formatted for readability )\r\n\r\n```javascript\r\nfunction isTokenValid(user) {\r\n var timeLeft = !( // negation\r\n !config // config object does not exist\r\n || !user.token // user object does not have a token\r\n || user.token.invalidated // token is explicitly invalidated\r\n || config.uninitialized // config isn't initialized\r\n || config.ignoreTimestamps // ignore timestamps\r\n || !getTimeLeft(user.token.expiry) // > 0 if expiration is in the future\r\n );\r\n return timeLeft > 0\r\n}\r\n\r\nfunction getTimeLeft(expiry) {\r\n return expiry - getSystemTime()\r\n}\r\n```\r\n\r\n# Remediation\r\nUpgrade UglifyJS to version `2.4.24` or higher.\r\n\r\n# References\r\n- [Blog Post](https://zyan.scripts.mit.edu/blog/backdooring-js/)\r\n- [GitHub Issue](https://github.com/mishoo/UglifyJS2/issues/751)" + }, + "properties": { + "tags": [ + "security", + "CWE-95", + "npm" + ], + "cvssv3_baseScore": 8.3, + "security-severity": "8.3" + } + }, + { + "id": "npm:uglify-js:20151024", + "shortDescription": { + "text": "Medium severity - Regular Expression Denial of Service (ReDoS) vulnerability in uglify-js" + }, + "fullDescription": { + "text": "(CVE-2015-8858) uglify-js@2.2.5" + }, + "help": { + "text": "", + "markdown": "* Package Manager: npm\n* Vulnerable module: uglify-js\n* Introduced through: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964, jade@1.11.0 and others\n### Detailed paths\n* _Introduced through_: realtimechat@extwiii/Nodejs-Real-time-Chat-App#c2ffccab1a6ad4ade9f33eacb647997b8c2ff964 › jade@1.11.0 › transformers@2.1.0 › uglify-js@2.2.5\n# Overview\r\nThe `parse()` function in the [`uglify-js`](https://www.npmjs.com/package/uglify-js) package prior to version 2.6.0 is vulnerable to regular expression denial of service (ReDoS) attacks when long inputs of certain patterns are processed.\r\n\r\n# Details\r\nDenial of Service (DoS) describes a family of attacks, all aimed at making a system inaccessible to its original and legitimate users. There are many types of DoS attacks, ranging from trying to clog the network pipes to the system by generating a large volume of traffic from many machines (a Distributed Denial of Service - DDoS - attack) to sending crafted requests that cause a system to crash or take a disproportional amount of time to process.\r\n\r\nThe Regular expression Denial of Service (ReDoS) is a type of Denial of Service attack. Regular expressions are incredibly powerful, but they aren't very intuitive and can ultimately end up making it easy for attackers to take your site down.\r\n\r\nLet’s take the following regular expression as an example:\r\n```js\r\nregex = /A(B|C+)+D/\r\n```\r\n\r\nThis regular expression accomplishes the following:\r\n- `A` The string must start with the letter 'A'\r\n- `(B|C+)+` The string must then follow the letter A with either the letter 'B' or some number of occurrences of the letter 'C' (the `+` matches one or more times). The `+` at the end of this section states that we can look for one or more matches of this section.\r\n- `D` Finally, we ensure this section of the string ends with a 'D'\r\n\r\nThe expression would match inputs such as `ABBD`, `ABCCCCD`, `ABCBCCCD` and `ACCCCCD`\r\n\r\nIt most cases, it doesn't take very long for a regex engine to find a match:\r\n\r\n```bash\r\n$ time node -e '/A(B|C+)+D/.test(\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCD\")'\r\n0.04s user 0.01s system 95% cpu 0.052 total\r\n\r\n$ time node -e '/A(B|C+)+D/.test(\"ACCCCCCCCCCCCCCCCCCCCCCCCCCCCX\")'\r\n1.79s user 0.02s system 99% cpu 1.812 total\r\n```\r\n\r\nThe entire process of testing it against a 30 characters long string takes around ~52ms. But when given an invalid string, it takes nearly two seconds to complete the test, over ten times as long as it took to test a valid string. The dramatic difference is due to the way regular expressions get evaluated.\r\n\r\nMost Regex engines will work very similarly (with minor differences). The engine will match the first possible way to accept the current character and proceed to the next one. If it then fails to match the next one, it will backtrack and see if there was another way to digest the previous character. If it goes too far down the rabbit hole only to find out the string doesn’t match in the end, and if many characters have multiple valid regex paths, the number of backtracking steps can become very large, resulting in what is known as _catastrophic backtracking_.\r\n\r\nLet's look at how our expression runs into this problem, using a shorter string: \"ACCCX\". While it seems fairly straightforward, there are still four different ways that the engine could match those three C's:\r\n1. CCC\r\n2. CC+C\r\n3. C+CC\r\n4. C+C+C.\r\n\r\nThe engine has to try each of those combinations to see if any of them potentially match against the expression. When you combine that with the other steps the engine must take, we can use [RegEx 101 debugger](https://regex101.com/debugger) to see the engine has to take a total of 38 steps before it can determine the string doesn't match.\r\n\r\nFrom there, the number of steps the engine must use to validate a string just continues to grow.\r\n\r\n| String | Number of C's | Number of steps |\r\n| -------|-------------:| -----:|\r\n| ACCCX | 3 | 38\r\n| ACCCCX | 4 | 71\r\n| ACCCCCX | 5 | 136\r\n| ACCCCCCCCCCCCCCX | 14 | 65,553\r\n\r\n\r\nBy the time the string includes 14 C's, the engine has to take over 65,000 steps just to see if the string is valid. These extreme situations can cause them to work very slowly (exponentially related to input size, as shown above), allowing an attacker to exploit this and can cause the service to excessively consume CPU, resulting in a Denial of Service.\r\n\r\n# Remediation\r\nUpgrade to version `2.6.0` or greater.\r\nIf a direct dependency update is not possible, use `snyk wizard` to patch this vulnerability.\r\n\r\n# References\r\n- [OWASP - ReDoS](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS)" + }, + "properties": { + "tags": [ + "security", + "CWE-400", + "npm" + ], + "cvssv3_baseScore": 5.3, + "security-severity": "5.3" + } + } + ] + } + }, + "results": [ + { + "ruleId": "SNYK-JS-COOKIE-8163060", + "level": "warning", + "message": { + "text": "This file introduces a vulnerable cookie package with a medium severity vulnerability." + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "region": { + "startLine": 1 + } + }, + "logicalLocations": [ + { + "fullyQualifiedName": "cookie@0.3.1" + } + ] + } + ], + "fixes": [ + { + "description": { + "text": "Upgrade to socket.io@4.8.0" + }, + "artifactChanges": [ + { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "replacements": [ + { + "deletedRegion": { + "startLine": 1 + }, + "insertedContent": { + "text": "socket.io@4.8.0" + } + } + ] + } + ] + } + ] + }, + { + "ruleId": "SNYK-JS-ENGINEIO-1056749", + "level": "error", + "message": { + "text": "This file introduces a vulnerable engine.io package with a high severity vulnerability." + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "region": { + "startLine": 1 + } + }, + "logicalLocations": [ + { + "fullyQualifiedName": "engine.io@1.8.5" + } + ] + } + ], + "fixes": [ + { + "description": { + "text": "Upgrade to socket.io@2.5.0" + }, + "artifactChanges": [ + { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "replacements": [ + { + "deletedRegion": { + "startLine": 1 + }, + "insertedContent": { + "text": "socket.io@2.5.0" + } + } + ] + } + ] + } + ] + }, + { + "ruleId": "SNYK-JS-ENGINEIO-3136336", + "level": "error", + "message": { + "text": "This file introduces a vulnerable engine.io package with a high severity vulnerability." + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "region": { + "startLine": 1 + } + }, + "logicalLocations": [ + { + "fullyQualifiedName": "engine.io@1.8.5" + } + ] + } + ], + "fixes": [ + { + "description": { + "text": "Upgrade to socket.io@2.5.0" + }, + "artifactChanges": [ + { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "replacements": [ + { + "deletedRegion": { + "startLine": 1 + }, + "insertedContent": { + "text": "socket.io@2.5.0" + } + } + ] + } + ] + } + ] + }, + { + "ruleId": "SNYK-JS-SOCKETIO-1024859", + "level": "warning", + "message": { + "text": "This file introduces a vulnerable socket.io package with a medium severity vulnerability." + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "region": { + "startLine": 1 + } + }, + "logicalLocations": [ + { + "fullyQualifiedName": "socket.io@1.7.4" + } + ] + } + ], + "fixes": [ + { + "description": { + "text": "Upgrade to socket.io@2.4.0" + }, + "artifactChanges": [ + { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "replacements": [ + { + "deletedRegion": { + "startLine": 1 + }, + "insertedContent": { + "text": "socket.io@2.4.0" + } + } + ] + } + ] + } + ] + }, + { + "ruleId": "SNYK-JS-SOCKETIOPARSER-1056752", + "level": "error", + "message": { + "text": "This file introduces a vulnerable socket.io-parser package with a high severity vulnerability." + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "region": { + "startLine": 1 + } + }, + "logicalLocations": [ + { + "fullyQualifiedName": "socket.io-parser@2.3.1" + } + ] + } + ], + "fixes": [ + { + "description": { + "text": "Upgrade to socket.io@2.2.0" + }, + "artifactChanges": [ + { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "replacements": [ + { + "deletedRegion": { + "startLine": 1 + }, + "insertedContent": { + "text": "socket.io@2.2.0" + } + } + ] + } + ] + } + ] + }, + { + "ruleId": "SNYK-JS-SOCKETIOPARSER-3091012", + "level": "error", + "message": { + "text": "This file introduces a vulnerable socket.io-parser package with a critical severity vulnerability." + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "region": { + "startLine": 1 + } + }, + "logicalLocations": [ + { + "fullyQualifiedName": "socket.io-parser@2.3.1" + } + ] + } + ], + "fixes": [ + { + "description": { + "text": "Upgrade to socket.io@2.2.0" + }, + "artifactChanges": [ + { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "replacements": [ + { + "deletedRegion": { + "startLine": 1 + }, + "insertedContent": { + "text": "socket.io@2.2.0" + } + } + ] + } + ] + } + ] + }, + { + "ruleId": "SNYK-JS-UGLIFYJS-1727251", + "level": "warning", + "message": { + "text": "This file introduces a vulnerable uglify-js package with a medium severity vulnerability." + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "region": { + "startLine": 1 + } + }, + "logicalLocations": [ + { + "fullyQualifiedName": "uglify-js@2.2.5" + } + ] + } + ], + "fixes": [ + { + "description": { + "text": "Upgrade to false" + }, + "artifactChanges": [ + { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "replacements": [ + { + "deletedRegion": { + "startLine": 1 + }, + "insertedContent": { + "text": "false" + } + } + ] + } + ] + } + ] + }, + { + "ruleId": "SNYK-JS-WS-1296835", + "level": "warning", + "message": { + "text": "This file introduces a vulnerable ws package with a medium severity vulnerability." + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "region": { + "startLine": 1 + } + }, + "logicalLocations": [ + { + "fullyQualifiedName": "ws@1.1.5" + } + ] + } + ], + "fixes": [ + { + "description": { + "text": "Upgrade to socket.io@2.3.0" + }, + "artifactChanges": [ + { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "replacements": [ + { + "deletedRegion": { + "startLine": 1 + }, + "insertedContent": { + "text": "socket.io@2.3.0" + } + } + ] + } + ] + } + ] + }, + { + "ruleId": "npm:clean-css:20180306", + "level": "note", + "message": { + "text": "This file introduces a vulnerable clean-css package with a low severity vulnerability." + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "region": { + "startLine": 1 + } + }, + "logicalLocations": [ + { + "fullyQualifiedName": "clean-css@3.4.28" + } + ] + } + ], + "fixes": [ + { + "description": { + "text": "Upgrade to false" + }, + "artifactChanges": [ + { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "replacements": [ + { + "deletedRegion": { + "startLine": 1 + }, + "insertedContent": { + "text": "false" + } + } + ] + } + ] + } + ] + }, + { + "ruleId": "npm:constantinople:20180421", + "level": "error", + "message": { + "text": "This file introduces a vulnerable constantinople package with a critical severity vulnerability." + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "region": { + "startLine": 1 + } + }, + "logicalLocations": [ + { + "fullyQualifiedName": "constantinople@3.0.2" + } + ] + } + ], + "fixes": [ + { + "description": { + "text": "Upgrade to false" + }, + "artifactChanges": [ + { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "replacements": [ + { + "deletedRegion": { + "startLine": 1 + }, + "insertedContent": { + "text": "false" + } + } + ] + } + ] + } + ] + }, + { + "ruleId": "npm:debug:20170905", + "level": "note", + "message": { + "text": "This file introduces a vulnerable debug package with a low severity vulnerability." + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "region": { + "startLine": 1 + } + }, + "logicalLocations": [ + { + "fullyQualifiedName": "debug@2.3.3" + } + ] + } + ], + "fixes": [ + { + "description": { + "text": "Upgrade to socket.io@2.0.0" + }, + "artifactChanges": [ + { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "replacements": [ + { + "deletedRegion": { + "startLine": 1 + }, + "insertedContent": { + "text": "socket.io@2.0.0" + } + } + ] + } + ] + } + ] + }, + { + "ruleId": "npm:ms:20170412", + "level": "note", + "message": { + "text": "This file introduces a vulnerable ms package with a low severity vulnerability." + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "region": { + "startLine": 1 + } + }, + "logicalLocations": [ + { + "fullyQualifiedName": "ms@0.7.2" + } + ] + } + ], + "fixes": [ + { + "description": { + "text": "Upgrade to socket.io@2.0.0" + }, + "artifactChanges": [ + { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "replacements": [ + { + "deletedRegion": { + "startLine": 1 + }, + "insertedContent": { + "text": "socket.io@2.0.0" + } + } + ] + } + ] + } + ] + }, + { + "ruleId": "npm:parsejson:20170908", + "level": "error", + "message": { + "text": "This file introduces a vulnerable parsejson package with a high severity vulnerability." + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "region": { + "startLine": 1 + } + }, + "logicalLocations": [ + { + "fullyQualifiedName": "parsejson@0.0.3" + } + ] + } + ] + }, + { + "ruleId": "npm:uglify-js:20150824", + "level": "error", + "message": { + "text": "This file introduces a vulnerable uglify-js package with a high severity vulnerability." + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "region": { + "startLine": 1 + } + }, + "logicalLocations": [ + { + "fullyQualifiedName": "uglify-js@2.2.5" + } + ] + } + ], + "fixes": [ + { + "description": { + "text": "Upgrade to false" + }, + "artifactChanges": [ + { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "replacements": [ + { + "deletedRegion": { + "startLine": 1 + }, + "insertedContent": { + "text": "false" + } + } + ] + } + ] + } + ] + }, + { + "ruleId": "npm:uglify-js:20151024", + "level": "warning", + "message": { + "text": "This file introduces a vulnerable uglify-js package with a medium severity vulnerability." + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "region": { + "startLine": 1 + } + }, + "logicalLocations": [ + { + "fullyQualifiedName": "uglify-js@2.2.5" + } + ] + } + ], + "fixes": [ + { + "description": { + "text": "Upgrade to false" + }, + "artifactChanges": [ + { + "artifactLocation": { + "uri": "https_//github.com/extwiii/Nodejs-Real-time-Chat-App" + }, + "replacements": [ + { + "deletedRegion": { + "startLine": 1 + }, + "insertedContent": { + "text": "false" + } + } + ] + } + ] + } + ] + } + ] + } + ] +} diff --git a/pkg/sarif/testdata/trivy_output.json b/pkg/sarif/testdata/trivy_output.json index 6afddcd59..e3637c692 100644 --- a/pkg/sarif/testdata/trivy_output.json +++ b/pkg/sarif/testdata/trivy_output.json @@ -1,48 +1,48 @@ { - "version": "2.1.0", - "$schema": "https://json.schemastore.org/sarif-2.1.0-rtm.5.json", - "runs": [ - { - "tool": { - "driver": { - "fullName": "Trivy Vulnerability Scanner", - "informationUri": "https://github.com/aquasecurity/trivy", - "name": "Trivy", - "version": "0.29.2" - } - }, - "results": [ - { - "ruleId": "CVE-2016-20013", - "ruleIndex": 3, - "level": "note", - "message": { - "text": "Package: libc6\nInstalled Version: 2.35-0ubuntu3\nVulnerability CVE-2016-20013\nSeverity: LOW\nFixed Version: \nLink: [CVE-2016-20013](https://avd.aquasec.com/nvd/cve-2016-20013)" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "library/ubuntu", - "uriBaseId": "ROOTPATH" - }, - "region": { - "startLine": 1, - "startColumn": 1, - "endLine": 1, - "endColumn": 1 - } - } - } - ] - } - ], - "columnKind": "utf16CodeUnits", - "originalUriBaseIds": { - "ROOTPATH": { - "uri": "file:///" - } - } - } - ] -} \ No newline at end of file + "version": "2.1.0", + "$schema": "https://json.schemastore.org/sarif-2.1.0-rtm.5.json", + "runs": [ + { + "tool": { + "driver": { + "fullName": "Trivy Vulnerability Scanner", + "informationUri": "https://github.com/aquasecurity/trivy", + "name": "Trivy", + "version": "0.29.2" + } + }, + "results": [ + { + "ruleId": "CVE-2016-20013", + "ruleIndex": 3, + "level": "note", + "message": { + "text": "Package: libc6\nInstalled Version: 2.35-0ubuntu3\nVulnerability CVE-2016-20013\nSeverity: LOW\nFixed Version: \nLink: [CVE-2016-20013](https://avd.aquasec.com/nvd/cve-2016-20013)" + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "library/ubuntu", + "uriBaseId": "ROOTPATH" + }, + "region": { + "startLine": 1, + "startColumn": 1, + "endLine": 1, + "endColumn": 1 + } + } + } + ] + } + ], + "columnKind": "utf16CodeUnits", + "originalUriBaseIds": { + "ROOTPATH": { + "uri": "file:///" + } + } + } + ] +}