diff --git a/tests/testdata/output/audit/audit_results.json b/tests/testdata/output/audit/audit_results.json deleted file mode 100644 index df0d0dd0..00000000 --- a/tests/testdata/output/audit/audit_results.json +++ /dev/null @@ -1,2581 +0,0 @@ -{ - "xray_version": "3.107.13", - "xsc_version": "1.12.5", - "jas_entitled": true, - "command_type": "source_code", - "multi_scan_id": "7d5e4733-3f93-11ef-8147-e610d09d7daa", - "targets": [ - { - "target": "/Users/user/ejs-frog-demo", - "technology": "npm", - "sca_scans": { - "is_multiple_root_project": false, - "descriptors": [ - "/Users/user/ejs-frog-demo/package.json" - ], - "xray_scan": [ - { - "scan": { - "scan_id": "711851ce-68c4-4dfd-7afb-c29737ebcb96", - "violations": [ - { - "summary": "Prototype pollution attack when using _.zipObjectDeep in lodash before 4.17.20.", - "severity": "High", - "type": "security", - "components": { - "npm://lodash:4.17.0": { - "fixed_versions": [ - "[4.17.19]" - ], - "impact_paths": [ - [ - { - "component_id": "npm://froghome:1.0.0" - }, - { - "component_id": "npm://lodash:4.17.0" - } - ] - ] - } - }, - "watch_name": "Security_watch_1", - "issue_id": "XRAY-114089", - "cves": [ - { - "cve": "CVE-2020-8203", - "cvss_v2_score": "5.8", - "cvss_v2_vector": "CVSS:2.0/AV:N/AC:M/Au:N/C:N/I:P/A:P", - "cvss_v3_score": "7.4", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:H" - } - ], - "references": [ - "https://nvd.nist.gov/vuln/detail/CVE-2020-8203", - "https://www.oracle.com/security-alerts/cpuapr2022.html", - "https://hackerone.com/reports/864701", - "https://hackerone.com/reports/712065", - "https://github.com/advisories/GHSA-p6mc-m468-83gw", - "https://www.oracle.com//security-alerts/cpujul2021.html", - "https://github.com/lodash/lodash/issues/4744", - "https://www.oracle.com/security-alerts/cpuApr2021.html", - "https://github.com/github/advisory-database/pull/2884", - "https://www.oracle.com/security-alerts/cpujan2022.html", - "https://github.com/lodash/lodash/commit/c84fe82760fb2d3e03a63379b297a1cc1a2fce12", - "https://security.netapp.com/advisory/ntap-20200724-0006/", - "https://web.archive.org/web/20210914001339/https://github.com/lodash/lodash/issues/4744", - "https://www.oracle.com/security-alerts/cpuoct2021.html", - "https://github.com/lodash/lodash/issues/4874", - "https://github.com/lodash/lodash/wiki/Changelog#v41719" - ], - "ignore_url": "https://platform.jfrog.io/ui/admin/xray/policiesGovernance/ignore-rules?graph_scan_id=711851ce-68c4-4dfd-7afb-c29737ebcb96\u0026issue_id=XRAY-114089\u0026on_demand_scanning=true\u0026show_popup=true\u0026type=security\u0026watch_name=Security_watch_1", - "extended_information": { - "short_description": "Prototype pollution in lodash object merging and zipping functions leads to code injection.", - "full_description": "[lodash](https://lodash.com/) is a JavaScript library which provides utility functions for common programming tasks.\n\nJavaScript frontend and Node.js-based backend applications that merge or zip objects using the lodash functions `mergeWith`, `merge` and `zipObjectDeep` are vulnerable to [prototype pollution](https://medium.com/node-modules/what-is-prototype-pollution-and-why-is-it-such-a-big-deal-2dd8d89a93c) if one or more of the objects it receives as arguments are obtained from user input. \nAn attacker controlling this input given to the vulnerable functions can inject properties to JavaScript special objects such as [Object.prototype](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes) from which all JavaScript objects inherit properties and methods. Any change on `Object.prototype` properties will then propagate through the prototype chain inheritance to all of the objects in a JavaScript application. This in turn would allow an attacker to add new properties or modify existing properties which will have application specific implications that could lead to DoS (denial of service), authentication bypass, privilege escalation and even RCE (remote code execution) in [some cases](https://youtu.be/LUsiFV3dsK8?t=1152). \nAs an example for privilege escalation, consider a JavaScript application that has a `user` object which has a Boolean property of `user.isAdmin` which is used to decide which actions the user may take. If an attacker can modify or add the `isAdmin` property through prototype pollution, it can escalate the privileges of its own user to those of an admin. \nAs exploitation is usually application specific, successful exploitation is much more likely if an attacker have access to the JavaScript application code. As such, frontend applications are more vulnerable to this vulnerability than Node.js backend applications.", - "jfrog_research_severity": "Critical", - "jfrog_research_severity_reasons": [ - { - "name": "The impact of exploiting the issue depends on the context of surrounding software. A severe impact such as RCE is not guaranteed.", - "is_positive": true - }, - { - "name": "The issue can be exploited by attackers over the network" - }, - { - "name": "The issue is trivial to exploit and does not require a published writeup or PoC" - } - ], - "remediation": "##### Deployment mitigations\n\nAs general guidelines against prototype pollution, first consider not merging objects originating from user input or using a Map structure instead of an object. If merging objects is needed, look into creating objects without a prototype with `Object.create(null)` or into freezing `Object.prototype` with `Object.freeze()`. Finally, it is always best to perform input validation with a a [JSON schema validator](https://github.com/ajv-validator/ajv), which could mitigate this issue entirely in many cases." - } - }, - { - "summary": "The ejs (aka Embedded JavaScript templates) package 3.1.6 for Node.js allows server-side template injection in settings[view options][outputFunctionName]. This is parsed as an internal option, and overwrites the outputFunctionName option with an arbitrary OS command (which is executed upon template compilation).", - "severity": "Critical", - "type": "security", - "components": { - "npm://ejs:3.1.6": { - "fixed_versions": [ - "[3.1.7]" - ], - "impact_paths": [ - [ - { - "component_id": "npm://froghome:1.0.0" - }, - { - "component_id": "npm://ejs:3.1.6" - } - ] - ] - } - }, - "watch_name": "Security_watch_1", - "issue_id": "XRAY-209002", - "cves": [ - { - "cve": "CVE-2022-29078", - "cvss_v2_score": "7.5", - "cvss_v2_vector": "CVSS:2.0/AV:N/AC:L/Au:N/C:P/I:P/A:P", - "cvss_v3_score": "9.8", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" - } - ], - "references": [ - "https://github.com/mde/ejs/commit/15ee698583c98dadc456639d6245580d17a24baf", - "https://eslam.io/posts/ejs-server-side-template-injection-rce/", - "https://security.netapp.com/advisory/ntap-20220804-0001", - "https://github.com/mde/ejs/releases", - "https://nvd.nist.gov/vuln/detail/CVE-2022-29078", - "https://eslam.io/posts/ejs-server-side-template-injection-rce", - "https://github.com/mde/ejs", - "https://security.netapp.com/advisory/ntap-20220804-0001/" - ], - "ignore_url": "https://platform.jfrog.io/ui/admin/xray/policiesGovernance/ignore-rules?graph_scan_id=711851ce-68c4-4dfd-7afb-c29737ebcb96\u0026issue_id=XRAY-209002\u0026on_demand_scanning=true\u0026show_popup=true\u0026type=security\u0026watch_name=Security_watch_1", - "extended_information": { - "short_description": "Insufficient input validation in EJS enables attackers to perform template injection when attacker can control the rendering options.", - "full_description": "[Embedded JavaScript templates](https://github.com/mde/ejs), also known as EJS, is one of the most popular Node.js templating engines, which is compiled with the Express JS view system.\n\nWhen rendering views using EJS, it is possible to perform template injection on the `opts.outputFunctionName` variable, since the variable is injected into the template body without any escaping. Although it is unlikely that the attacker can directly control the `outputFunctionName` property, it is possible that it can be influenced in conjunction with a prototype pollution vulnerability.\n\nOnce template injection is achieved, the attacker can immediately perform remote code execution since the template engine (EJS) allows executing arbitrary JavaScript code.\n\nExample of a vulnerable Node.js application -\n```js\nconst express = require('express');\nconst bodyParser = require('body-parser');\nconst lodash = require('lodash');\nconst ejs = require('ejs');\n\nconst app = express();\n\napp\n .use(bodyParser.urlencoded({extended: true}))\n .use(bodyParser.json());\n\napp.set('views', './');\napp.set('view engine', 'ejs');\n\napp.get(\"/\", (req, res) =\u003e {\n res.render('index');\n});\n\napp.post(\"/\", (req, res) =\u003e {\n let data = {};\n let input = JSON.parse(req.body.content);\n lodash.defaultsDeep(data, input);\n res.json({message: \"OK\"});\n});\n\nlet server = app.listen(8086, '0.0.0.0', function() {\n console.log('Listening on port %d', server.address().port);\n});\n```\n\nExploiting the above example for RCE -\n`curl 127.0.0.1:8086 -v --data 'content={\"constructor\": {\"prototype\": {\"outputFunctionName\": \"a; return global.process.mainModule.constructor._load(\\\"child_process\\\").execSync(\\\"whoami\\\"); //\"}}}'\n`\n\nDue to the prototype pollution in the `lodash.defaultsDeep` call, an attacker can inject the `outputFunctionName` property with an arbitrary value. The chosen value executes an arbitrary process via the `child_process` module.", - "jfrog_research_severity": "Medium", - "jfrog_research_severity_reasons": [ - { - "name": "The prerequisites for exploiting the issue are extremely unlikely", - "description": "The attacker has to find a way to get their malicious input to `opts.outputFunctionName`, which will usually require exploitation of a prototype pollution vulnerability somewhere else in the code. However, there could be cases where the attacker can pass malicious data to the render function directly because of design problems in other code using EJS.", - "is_positive": true - }, - { - "name": "The issue has an exploit published", - "description": "There are multiple examples of exploits for this vulnerability online." - }, - { - "name": "The issue results in a severe impact (such as remote code execution)", - "description": "Successful exploitation of this vulnerability leads to remote code execution." - } - ], - "remediation": "##### Development mitigations\n\nAdd the `Object.freeze(Object.prototype);` directive once at the beginning of your main JS source code file (ex. `index.js`), preferably after all your `require` directives. This will prevent any changes to the prototype object, thus completely negating prototype pollution attacks.\n\nNote that this mitigation is supposed to stop any prototype pollution attacks which can allow an attacker to control the `opts.outputFunctionName` parameter indirectly.\n\nThe mitigation will not stop any (extremely unlikely) scenarios where the JavaScript code allows external input to directly affect `opts.outputFunctionName`." - } - }, - { - "summary": "ejs v3.1.9 is vulnerable to server-side template injection. If the ejs file is controllable, template injection can be implemented through the configuration settings of the closeDelimiter parameter. NOTE: this is disputed by the vendor because the render function is not intended to be used with untrusted input.", - "severity": "Critical", - "type": "security", - "components": { - "npm://ejs:3.1.6": { - "impact_paths": [ - [ - { - "component_id": "npm://froghome:1.0.0" - }, - { - "component_id": "npm://ejs:3.1.6" - } - ] - ] - } - }, - "watch_name": "Security_watch_1", - "issue_id": "XRAY-520200", - "cves": [ - { - "cve": "CVE-2023-29827", - "cvss_v3_score": "9.8", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" - } - ], - "references": [ - "https://nvd.nist.gov/vuln/detail/CVE-2023-29827", - "https://github.com/mde/ejs/issues/720", - "https://github.com/mde/ejs/blob/main/SECURITY.md#out-of-scope-vulnerabilities" - ], - "ignore_url": "https://platform.jfrog.io/ui/admin/xray/policiesGovernance/ignore-rules?graph_scan_id=711851ce-68c4-4dfd-7afb-c29737ebcb96\u0026issue_id=XRAY-520200\u0026on_demand_scanning=true\u0026show_popup=true\u0026type=security\u0026watch_name=Security_watch_1", - "extended_information": { - "short_description": "Insufficient input validation can lead to template injection in ejs when attackers can control both the rendered template and rendering options.", - "full_description": "[Embedded JavaScript templates](https://github.com/mde/ejs), also known as EJS, is one of the most popular Node.js templating engines, which is compiled with the Express JS view system.\n\nWhen rendering views using EJS, it is possible to bypass ejs' template injection restrictions, by abusing the `closeDelimiter` rendering option, in the case when -\n1. The template itself can be partially controlled by the attacker\n2. The template rendering options can be fully controlled by the attacker\n\nThe vulnerability was **rightfully disputed** due to the fact that a vulnerable configuration is extremely unlikely to exist in any real-world setup. As such, the maintainers will not provide a fix for this (non-)issue.\n\nExample of a vulnerable application -\n```js\nconst express = require('express')\nconst app = express()\nconst port = 3000\n\napp.set('view engine', 'ejs');\n\napp.get('/page', (req,res) =\u003e {\n res.render('page', req.query); // OPTS (2nd parameter) IS ATTACKER-CONTROLLED\n})\n\napp.listen(port, () =\u003e {\n console.log(\"Example app listening on port ${port}\")\n})\n```\n\nContents of `page.ejs` (very unlikely to be attacker controlled) -\n```js\n%%1\");process.mainModule.require('child_process').execSync('calc');//\n```\n\nIn this case, sending `closeDelimiter` with the same malicious code that already exists at `page.ejs` will trigger the injection -\n`http://127.0.0.1:3000/page?settings[view%20options][closeDelimiter]=1\")%3bprocess.mainModule.require('child_process').execSync('calc')%3b//`", - "jfrog_research_severity": "Low", - "jfrog_research_severity_reasons": [ - { - "name": "The reported CVSS was either wrongly calculated, downgraded by other vendors, or does not reflect the vulnerability's impact", - "description": "The CVSS does not take into account the rarity of a vulnerable configuration to exist", - "is_positive": true - }, - { - "name": "The prerequisites for exploiting the issue are extremely unlikely", - "description": "The vulnerability can be exploited only under the following conditions -\n1. The template itself can be partially controlled by the attacker\n2. The template rendering options can be fully controlled by the attacker\nThis vulnerable configuration is extremely unlikely to exist in any real-world setup.", - "is_positive": true - }, - { - "name": "The issue has been disputed by the vendor", - "is_positive": true - }, - { - "name": "The issue has an exploit published", - "description": "Published exploit demonstrates template injection" - } - ] - } - }, - { - "summary": "Versions of lodash lower than 4.17.12 are vulnerable to Prototype Pollution. The function defaultsDeep could be tricked into adding or modifying properties of Object.prototype using a constructor payload.", - "severity": "Critical", - "type": "security", - "components": { - "npm://lodash:4.17.0": { - "fixed_versions": [ - "[4.17.12]" - ], - "impact_paths": [ - [ - { - "component_id": "npm://froghome:1.0.0" - }, - { - "component_id": "npm://lodash:4.17.0" - } - ] - ] - } - }, - "watch_name": "Security_watch_1", - "issue_id": "XRAY-85679", - "cves": [ - { - "cve": "CVE-2019-10744", - "cvss_v2_score": "6.4", - "cvss_v2_vector": "CVSS:2.0/AV:N/AC:L/Au:N/C:N/I:P/A:P", - "cvss_v3_score": "9.1", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H" - } - ], - "references": [ - "https://www.npmjs.com/advisories/1065", - "https://github.com/lodash/lodash/pull/4336", - "https://www.oracle.com/security-alerts/cpujan2021.html", - "https://security.netapp.com/advisory/ntap-20191004-0005/", - "https://snyk.io/vuln/SNYK-JS-LODASH-450202", - "https://support.f5.com/csp/article/K47105354?utm_source=f5support\u0026amp;utm_medium=RSS", - "https://access.redhat.com/errata/RHSA-2019:3024", - "https://www.oracle.com/security-alerts/cpuoct2020.html", - "https://support.f5.com/csp/article/K47105354?utm_source=f5support\u0026amp%3Butm_medium=RSS", - "https://github.com/advisories/GHSA-jf85-cpcp-j695", - "https://nvd.nist.gov/vuln/detail/CVE-2019-10744" - ], - "ignore_url": "https://platform.jfrog.io/ui/admin/xray/policiesGovernance/ignore-rules?graph_scan_id=711851ce-68c4-4dfd-7afb-c29737ebcb96\u0026issue_id=XRAY-85679\u0026on_demand_scanning=true\u0026show_popup=true\u0026type=security\u0026watch_name=Security_watch_1", - "extended_information": { - "short_description": "Insufficient input validation in lodash defaultsDeep() leads to prototype pollution.", - "full_description": "[lodash](https://www.npmjs.com/package/lodash) is a modern JavaScript utility library delivering modularity, performance, \u0026 extras.\n\nThe function `defaultsDeep` was found to be vulnerable to prototype pollution, when accepting arbitrary source objects from untrusted input\n\nExample of code vulnerable to this issue - \n```js\nconst lodash = require('lodash'); \nconst evilsrc = {constructor: {prototype: {evilkey: \"evilvalue\"}}};\nlodash.defaultsDeep({}, evilsrc)\n```", - "jfrog_research_severity": "High", - "jfrog_research_severity_reasons": [ - { - "name": "The issue has an exploit published", - "description": "A public PoC demonstrates exploitation of this issue" - }, - { - "name": "The impact of exploiting the issue depends on the context of surrounding software. A severe impact such as RCE is not guaranteed.", - "description": "A prototype pollution attack allows the attacker to inject new properties to all JavaScript objects (but not set existing properties).\nTherefore, the impact of a prototype pollution attack depends on the way the JavaScript code uses any object properties after the attack is triggered.\nUsually, a DoS attack is possible since invalid properties quickly lead to an exception being thrown. In more severe cases, RCE may be achievable.", - "is_positive": true - }, - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "An attacker must find remote input that propagates into the `defaultsDeep` method (2nd arg)", - "is_positive": true - } - ], - "remediation": "##### Development mitigations\n\nAdd the `Object.freeze(Object.prototype);` directive once at the beginning of your main JS source code file (ex. `index.js`), preferably after all your `require` directives. This will prevent any changes to the prototype object, thus completely negating prototype pollution attacks." - } - }, - { - "summary": "Lodash versions prior to 4.17.21 are vulnerable to Command Injection via the template function.", - "severity": "High", - "type": "security", - "components": { - "npm://lodash:4.17.0": { - "fixed_versions": [ - "[4.17.21]" - ], - "impact_paths": [ - [ - { - "component_id": "npm://froghome:1.0.0" - }, - { - "component_id": "npm://lodash:4.17.0" - } - ] - ] - } - }, - "watch_name": "Security_watch_1", - "issue_id": "XRAY-140575", - "cves": [ - { - "cve": "CVE-2021-23337", - "cvss_v2_score": "6.5", - "cvss_v2_vector": "CVSS:2.0/AV:N/AC:L/Au:S/C:P/I:P/A:P", - "cvss_v3_score": "7.2", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H" - } - ], - "references": [ - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSNPM-1074929", - "https://security.netapp.com/advisory/ntap-20210312-0006/", - "https://snyk.io/vuln/SNYK-JS-LODASH-1040724", - "https://security.netapp.com/advisory/ntap-20210312-0006", - "https://www.oracle.com/security-alerts/cpujan2022.html", - "https://github.com/lodash/lodash/commit/3469357cff396a26c363f8c1b5a91dde28ba4b1c", - "https://cert-portal.siemens.com/productcert/pdf/ssa-637483.pdf", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSBOWER-1074928", - "https://www.oracle.com/security-alerts/cpuoct2021.html", - "https://snyk.io/vuln/SNYK-JAVA-ORGFUJIONWEBJARS-1074932", - "https://github.com/lodash/lodash/blob/ddfd9b11a0126db2302cb70ec9973b66baec0975/lodash.js%23L14851", - "https://github.com/advisories/GHSA-35jh-r3h4-6jhm", - "https://www.oracle.com/security-alerts/cpujul2022.html", - "https://www.oracle.com//security-alerts/cpujul2021.html", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARS-1074930", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSBOWERGITHUBLODASH-1074931", - "https://nvd.nist.gov/vuln/detail/CVE-2021-23337", - "https://github.com/lodash/lodash/blob/ddfd9b11a0126db2302cb70ec9973b66baec0975/lodash.js#L14851" - ], - "ignore_url": "https://platform.jfrog.io/ui/admin/xray/policiesGovernance/ignore-rules?graph_scan_id=711851ce-68c4-4dfd-7afb-c29737ebcb96\u0026issue_id=XRAY-140575\u0026on_demand_scanning=true\u0026show_popup=true\u0026type=security\u0026watch_name=Security_watch_1", - "extended_information": { - "short_description": "Improper sanitization in the lodash template function leads to JavaScript code injection through the options argument.", - "full_description": "JavaScript-based applications (both frontend and backend) that use the [template function](https://lodash.com/docs/4.17.15#template) -`_.template([string=''], [options={}])` from the [lodash](https://lodash.com/) utility library and provide the `options` argument (specifically the `variable` option) from untrusted user input, are vulnerable to JavaScript code injection. This issue can be easily exploited, and an exploitation example is [publicly available](https://github.com/lodash/lodash/commit/3469357cff396a26c363f8c1b5a91dde28ba4b1c#diff-a561630bb56b82342bc66697aee2ad96efddcbc9d150665abd6fb7ecb7c0ab2fR22303) in the fix tests that was introduced in version 4.17.21 - \n```js\nlodash.template('', { variable: '){console.log(process.env)}; with(obj' })()\n```", - "jfrog_research_severity": "Medium", - "jfrog_research_severity_reasons": [ - { - "name": "The prerequisites for exploiting the issue are extremely unlikely", - "description": "It is highly unlikely that a JS program will accept arbitrary remote input into the template's `options` argument", - "is_positive": true - }, - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "The attacker must find remote input that propagates into the `options` argument of a `template` call", - "is_positive": true - }, - { - "name": "The issue results in a severe impact (such as remote code execution)", - "description": "Leads to remote code execution through JS code injection" - }, - { - "name": "The issue has an exploit published", - "description": "Published exploit demonstrates arbitrary JS code execution" - } - ] - } - } - ], - "vulnerabilities": [ - { - "cves": [ - { - "cve": "CVE-2024-39249" - } - ], - "summary": "Async \u003c= 2.6.4 and \u003c= 3.2.5 are vulnerable to ReDoS (Regular Expression Denial of Service) while parsing function in autoinject function. NOTE: this is disputed by the supplier because there is no realistic threat model: regular expressions are not used with untrusted input.", - "severity": "Unknown", - "components": { - "npm://async:3.2.4": { - "impact_paths": [ - [ - { - "component_id": "npm://froghome:1.0.0" - }, - { - "component_id": "npm://ejs:3.1.6" - }, - { - "component_id": "npm://jake:10.8.7" - }, - { - "component_id": "npm://async:3.2.4" - } - ] - ] - } - }, - "issue_id": "XRAY-609848", - "references": [ - "https://github.com/zunak/CVE-2024-39249", - "https://github.com/caolan/async/blob/v3.2.5/lib/autoInject.js#L41", - "https://nvd.nist.gov/vuln/detail/CVE-2024-39249", - "https://github.com/caolan/async/blob/v3.2.5/lib/autoInject.js#L6", - "https://github.com/caolan/async/issues/1975#issuecomment-2204528153", - "https://github.com/zunak/CVE-2024-39249/issues/1" - ], - "extended_information": { - "short_description": "ReDoS in Async may lead to denial of service while parsing malformed source code.", - "jfrog_research_severity": "Low", - "jfrog_research_severity_reasons": [ - { - "name": "The reported CVSS was either wrongly calculated, downgraded by other vendors, or does not reflect the vulnerability's impact", - "description": "The reported CVSS does not reflect the severity of the vulnerability.", - "is_positive": true - }, - { - "name": "The issue cannot result in a severe impact (such as remote code execution)", - "description": "To exploit this issue an attacker must change the source code of the application. In cases where an attacker can already modify (or fully control) the source code, the attacker can immediately achieve arbitrary code execution - thus this issue has almost no security impact.", - "is_positive": true - }, - { - "name": "The issue has an exploit published", - "description": "A proof-of-concept has been published in the advisory." - }, - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "The issue requires the use of the `async.autoInject` function to be vulnerable.", - "is_positive": true - } - ] - } - }, - { - "cves": [ - { - "cve": "CVE-2020-8203", - "cvss_v2_score": "5.8", - "cvss_v2_vector": "CVSS:2.0/AV:N/AC:M/Au:N/C:N/I:P/A:P", - "cvss_v3_score": "7.4", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:H", - "cwe": [ - "CWE-770", - "CWE-1321" - ], - "cwe_details": { - "CWE-1321": { - "name": "Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')", - "description": "The product receives input from an upstream component that specifies attributes that are to be initialized or updated in an object, but it does not properly control modifications of attributes of the object prototype." - }, - "CWE-770": { - "name": "Allocation of Resources Without Limits or Throttling", - "description": "The product allocates a reusable resource or group of resources on behalf of an actor without imposing any restrictions on the size or number of resources that can be allocated, in violation of the intended security policy for that actor." - } - } - } - ], - "summary": "Prototype pollution attack when using _.zipObjectDeep in lodash before 4.17.20.", - "severity": "High", - "components": { - "npm://lodash:4.17.0": { - "fixed_versions": [ - "[4.17.19]" - ], - "impact_paths": [ - [ - { - "component_id": "npm://froghome:1.0.0" - }, - { - "component_id": "npm://lodash:4.17.0" - } - ] - ] - } - }, - "issue_id": "XRAY-114089", - "references": [ - "https://nvd.nist.gov/vuln/detail/CVE-2020-8203", - "https://www.oracle.com/security-alerts/cpuapr2022.html", - "https://hackerone.com/reports/864701", - "https://hackerone.com/reports/712065", - "https://github.com/advisories/GHSA-p6mc-m468-83gw", - "https://www.oracle.com//security-alerts/cpujul2021.html", - "https://github.com/lodash/lodash/issues/4744", - "https://www.oracle.com/security-alerts/cpuApr2021.html", - "https://github.com/github/advisory-database/pull/2884", - "https://www.oracle.com/security-alerts/cpujan2022.html", - "https://github.com/lodash/lodash/commit/c84fe82760fb2d3e03a63379b297a1cc1a2fce12", - "https://security.netapp.com/advisory/ntap-20200724-0006/", - "https://web.archive.org/web/20210914001339/https://github.com/lodash/lodash/issues/4744", - "https://www.oracle.com/security-alerts/cpuoct2021.html", - "https://github.com/lodash/lodash/issues/4874", - "https://github.com/lodash/lodash/wiki/Changelog#v41719" - ], - "extended_information": { - "short_description": "Prototype pollution in lodash object merging and zipping functions leads to code injection.", - "full_description": "[lodash](https://lodash.com/) is a JavaScript library which provides utility functions for common programming tasks.\n\nJavaScript frontend and Node.js-based backend applications that merge or zip objects using the lodash functions `mergeWith`, `merge` and `zipObjectDeep` are vulnerable to [prototype pollution](https://medium.com/node-modules/what-is-prototype-pollution-and-why-is-it-such-a-big-deal-2dd8d89a93c) if one or more of the objects it receives as arguments are obtained from user input. \nAn attacker controlling this input given to the vulnerable functions can inject properties to JavaScript special objects such as [Object.prototype](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes) from which all JavaScript objects inherit properties and methods. Any change on `Object.prototype` properties will then propagate through the prototype chain inheritance to all of the objects in a JavaScript application. This in turn would allow an attacker to add new properties or modify existing properties which will have application specific implications that could lead to DoS (denial of service), authentication bypass, privilege escalation and even RCE (remote code execution) in [some cases](https://youtu.be/LUsiFV3dsK8?t=1152). \nAs an example for privilege escalation, consider a JavaScript application that has a `user` object which has a Boolean property of `user.isAdmin` which is used to decide which actions the user may take. If an attacker can modify or add the `isAdmin` property through prototype pollution, it can escalate the privileges of its own user to those of an admin. \nAs exploitation is usually application specific, successful exploitation is much more likely if an attacker have access to the JavaScript application code. As such, frontend applications are more vulnerable to this vulnerability than Node.js backend applications.", - "jfrog_research_severity": "Critical", - "jfrog_research_severity_reasons": [ - { - "name": "The impact of exploiting the issue depends on the context of surrounding software. A severe impact such as RCE is not guaranteed.", - "is_positive": true - }, - { - "name": "The issue can be exploited by attackers over the network" - }, - { - "name": "The issue is trivial to exploit and does not require a published writeup or PoC" - } - ], - "remediation": "##### Deployment mitigations\n\nAs general guidelines against prototype pollution, first consider not merging objects originating from user input or using a Map structure instead of an object. If merging objects is needed, look into creating objects without a prototype with `Object.create(null)` or into freezing `Object.prototype` with `Object.freeze()`. Finally, it is always best to perform input validation with a a [JSON schema validator](https://github.com/ajv-validator/ajv), which could mitigate this issue entirely in many cases." - } - }, - { - "cves": [ - { - "cve": "CVE-2019-10744", - "cvss_v2_score": "6.4", - "cvss_v2_vector": "CVSS:2.0/AV:N/AC:L/Au:N/C:N/I:P/A:P", - "cvss_v3_score": "9.1", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H", - "cwe": [ - "CWE-1321", - "CWE-20" - ], - "cwe_details": { - "CWE-1321": { - "name": "Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')", - "description": "The product receives input from an upstream component that specifies attributes that are to be initialized or updated in an object, but it does not properly control modifications of attributes of the object prototype." - }, - "CWE-20": { - "name": "Improper Input Validation", - "description": "The product receives input or data, but it does not validate or incorrectly validates that the input has the properties that are required to process the data safely and correctly.", - "categories": [ - { - "category": "2023 CWE Top 25", - "rank": "6" - } - ] - } - } - } - ], - "summary": "Versions of lodash lower than 4.17.12 are vulnerable to Prototype Pollution. The function defaultsDeep could be tricked into adding or modifying properties of Object.prototype using a constructor payload.", - "severity": "Critical", - "components": { - "npm://lodash:4.17.0": { - "fixed_versions": [ - "[4.17.12]" - ], - "impact_paths": [ - [ - { - "component_id": "npm://froghome:1.0.0" - }, - { - "component_id": "npm://lodash:4.17.0" - } - ] - ] - } - }, - "issue_id": "XRAY-85679", - "references": [ - "https://www.npmjs.com/advisories/1065", - "https://github.com/lodash/lodash/pull/4336", - "https://www.oracle.com/security-alerts/cpujan2021.html", - "https://security.netapp.com/advisory/ntap-20191004-0005/", - "https://snyk.io/vuln/SNYK-JS-LODASH-450202", - "https://support.f5.com/csp/article/K47105354?utm_source=f5support\u0026amp;utm_medium=RSS", - "https://access.redhat.com/errata/RHSA-2019:3024", - "https://www.oracle.com/security-alerts/cpuoct2020.html", - "https://support.f5.com/csp/article/K47105354?utm_source=f5support\u0026amp%3Butm_medium=RSS", - "https://github.com/advisories/GHSA-jf85-cpcp-j695", - "https://nvd.nist.gov/vuln/detail/CVE-2019-10744" - ], - "extended_information": { - "short_description": "Insufficient input validation in lodash defaultsDeep() leads to prototype pollution.", - "full_description": "[lodash](https://www.npmjs.com/package/lodash) is a modern JavaScript utility library delivering modularity, performance, \u0026 extras.\n\nThe function `defaultsDeep` was found to be vulnerable to prototype pollution, when accepting arbitrary source objects from untrusted input\n\nExample of code vulnerable to this issue - \n```js\nconst lodash = require('lodash'); \nconst evilsrc = {constructor: {prototype: {evilkey: \"evilvalue\"}}};\nlodash.defaultsDeep({}, evilsrc)\n```", - "jfrog_research_severity": "High", - "jfrog_research_severity_reasons": [ - { - "name": "The issue has an exploit published", - "description": "A public PoC demonstrates exploitation of this issue" - }, - { - "name": "The impact of exploiting the issue depends on the context of surrounding software. A severe impact such as RCE is not guaranteed.", - "description": "A prototype pollution attack allows the attacker to inject new properties to all JavaScript objects (but not set existing properties).\nTherefore, the impact of a prototype pollution attack depends on the way the JavaScript code uses any object properties after the attack is triggered.\nUsually, a DoS attack is possible since invalid properties quickly lead to an exception being thrown. In more severe cases, RCE may be achievable.", - "is_positive": true - }, - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "An attacker must find remote input that propagates into the `defaultsDeep` method (2nd arg)", - "is_positive": true - } - ], - "remediation": "##### Development mitigations\n\nAdd the `Object.freeze(Object.prototype);` directive once at the beginning of your main JS source code file (ex. `index.js`), preferably after all your `require` directives. This will prevent any changes to the prototype object, thus completely negating prototype pollution attacks." - } - }, - { - "cves": [ - { - "cve": "CVE-2019-1010266", - "cvss_v2_score": "4.0", - "cvss_v2_vector": "CVSS:2.0/AV:N/AC:L/Au:S/C:N/I:N/A:P", - "cvss_v3_score": "6.5", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H", - "cwe": [ - "CWE-400", - "CWE-770" - ], - "cwe_details": { - "CWE-400": { - "name": "Uncontrolled Resource Consumption", - "description": "The product does not properly control the allocation and maintenance of a limited resource, thereby enabling an actor to influence the amount of resources consumed, eventually leading to the exhaustion of available resources." - }, - "CWE-770": { - "name": "Allocation of Resources Without Limits or Throttling", - "description": "The product allocates a reusable resource or group of resources on behalf of an actor without imposing any restrictions on the size or number of resources that can be allocated, in violation of the intended security policy for that actor." - } - } - } - ], - "summary": "lodash prior to 4.17.11 is affected by: CWE-400: Uncontrolled Resource Consumption. The impact is: Denial of service. The component is: Date handler. The attack vector is: Attacker provides very long strings, which the library attempts to match using a regular expression. The fixed version is: 4.17.11.", - "severity": "Medium", - "components": { - "npm://lodash:4.17.0": { - "fixed_versions": [ - "[4.17.11]" - ], - "impact_paths": [ - [ - { - "component_id": "npm://froghome:1.0.0" - }, - { - "component_id": "npm://lodash:4.17.0" - } - ] - ] - } - }, - "issue_id": "XRAY-85049", - "references": [ - "https://nvd.nist.gov/vuln/detail/CVE-2019-1010266", - "https://github.com/lodash/lodash/wiki/Changelog", - "https://snyk.io/vuln/SNYK-JS-LODASH-73639", - "https://security.netapp.com/advisory/ntap-20190919-0004", - "https://security.netapp.com/advisory/ntap-20190919-0004/", - "https://github.com/lodash/lodash/issues/3359", - "https://github.com/lodash/lodash/commit/5c08f18d365b64063bfbfa686cbb97cdd6267347" - ] - }, - { - "cves": [ - { - "cve": "CVE-2020-28500", - "cvss_v2_score": "5.0", - "cvss_v2_vector": "CVSS:2.0/AV:N/AC:L/Au:N/C:N/I:N/A:P", - "cvss_v3_score": "5.3", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L", - "cwe": [ - "CWE-400", - "CWE-1333", - "NVD-CWE-Other" - ], - "cwe_details": { - "CWE-1333": { - "name": "Inefficient Regular Expression Complexity", - "description": "The product uses a regular expression with an inefficient, possibly exponential worst-case computational complexity that consumes excessive CPU cycles." - }, - "CWE-400": { - "name": "Uncontrolled Resource Consumption", - "description": "The product does not properly control the allocation and maintenance of a limited resource, thereby enabling an actor to influence the amount of resources consumed, eventually leading to the exhaustion of available resources." - } - } - } - ], - "summary": "Lodash versions prior to 4.17.21 are vulnerable to Regular Expression Denial of Service (ReDoS) via the toNumber, trim and trimEnd functions.", - "severity": "Medium", - "components": { - "npm://lodash:4.17.0": { - "fixed_versions": [ - "[4.17.21]" - ], - "impact_paths": [ - [ - { - "component_id": "npm://froghome:1.0.0" - }, - { - "component_id": "npm://lodash:4.17.0" - } - ] - ] - } - }, - "issue_id": "XRAY-140562", - "references": [ - "https://cert-portal.siemens.com/productcert/pdf/ssa-637483.pdf", - "https://github.com/lodash/lodash/commit/c4847ebe7d14540bb28a8b932a9ce1b9ecbfee1a", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARS-1074894", - "https://github.com/lodash/lodash/blob/npm/trimEnd.js%23L8", - "https://security.netapp.com/advisory/ntap-20210312-0006/", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSNPM-1074893", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSBOWER-1074892", - "https://www.oracle.com//security-alerts/cpujul2021.html", - "https://www.oracle.com/security-alerts/cpuoct2021.html", - "https://nvd.nist.gov/vuln/detail/CVE-2020-28500", - "https://www.oracle.com/security-alerts/cpujul2022.html", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSBOWERGITHUBLODASH-1074895", - "https://github.com/lodash/lodash/pull/5065/commits/02906b8191d3c100c193fe6f7b27d1c40f200bb7", - "https://www.oracle.com/security-alerts/cpujan2022.html", - "https://github.com/advisories/GHSA-29mw-wpgm-hmr9", - "https://github.com/lodash/lodash/pull/5065", - "https://snyk.io/vuln/SNYK-JAVA-ORGFUJIONWEBJARS-1074896", - "https://snyk.io/vuln/SNYK-JS-LODASH-1018905" - ], - "extended_information": { - "short_description": "ReDoS in lodash could lead to a denial of service when handling untrusted strings.", - "full_description": "JavaScript-based applications that use [lodash](https://github.com/lodash/lodash) and specifically the [_.toNumber](https://lodash.com/docs/4.17.15#toNumber), [_.trim](https://lodash.com/docs/4.17.15#trim) and [_.trimEnd](https://lodash.com/docs/4.17.15#trimEnd) functions, could be vulnerable to DoS (Denial of Service) through a faulty regular expression that introduces a ReDoS (Regular Expression DoS) vulnerability. This vulnerability is only triggered if untrusted user input flows into these vulnerable functions and the attacker can supply arbitrary long strings (over 50kB) that contain whitespaces. \n\nOn a modern Core i7-based system, calling the vulnerable functions with a 50kB string could take between 2 to 3 seconds to execute and 4.5 minutes for a longer 500kB string. The fix improved the regular expression performance so it took only a few milliseconds on the same Core i7-based system. This vulnerability is easily exploitable as all is required is to build a string that triggers it as can be seen in this PoC reproducing code - \n\n```js\nvar untrusted_user_input_50k = \"a\" + ' '.repeat(50000) + \"z\"; // assume this is provided over the network\nlo.trimEnd(untrusted_user_input_50k); // should take a few seconds to run\nvar untrusted_user_input_500k = \"a\" + ' '.repeat(500000) + \"z\"; // assume this is provided over the network\nlo.trimEnd(untrusted_user_input_500k); // should take a few minutes to run\n```", - "jfrog_research_severity": "Medium", - "jfrog_research_severity_reasons": [ - { - "name": "The issue has an exploit published", - "description": "Public exploit demonstrated ReDoS" - }, - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "Exploitation depends on parsing user input by the `.toNumber`, `.trim` or `.trimEnd` `lodash` functions, and requires the input to contain whitespaces and be very long (over 50KB)", - "is_positive": true - } - ], - "remediation": "##### Deployment mitigations\n\nTrim untrusted strings based on size before providing it to the vulnerable functions by using the `substring` function to with a fixed maximum size like so - ```js untrusted_user_input.substring(0, max_string_size_less_than_50kB); ```" - } - }, - { - "cves": [ - { - "cve": "CVE-2018-3721", - "cvss_v2_score": "4.0", - "cvss_v2_vector": "CVSS:2.0/AV:N/AC:L/Au:S/C:N/I:P/A:N", - "cvss_v3_score": "6.5", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N", - "cwe": [ - "CWE-1321", - "CWE-471" - ], - "cwe_details": { - "CWE-1321": { - "name": "Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')", - "description": "The product receives input from an upstream component that specifies attributes that are to be initialized or updated in an object, but it does not properly control modifications of attributes of the object prototype." - }, - "CWE-471": { - "name": "Modification of Assumed-Immutable Data (MAID)", - "description": "The product does not properly protect an assumed-immutable element from being modified by an attacker." - } - } - } - ], - "summary": "lodash node module before 4.17.5 suffers from a Modification of Assumed-Immutable Data (MAID) vulnerability via defaultsDeep, merge, and mergeWith functions, which allows a malicious user to modify the prototype of \"Object\" via __proto__, causing the addition or modification of an existing property that will exist on all objects.", - "severity": "Medium", - "components": { - "npm://lodash:4.17.0": { - "fixed_versions": [ - "[4.17.5]" - ], - "impact_paths": [ - [ - { - "component_id": "npm://froghome:1.0.0" - }, - { - "component_id": "npm://lodash:4.17.0" - } - ] - ] - } - }, - "issue_id": "XRAY-72918", - "references": [ - "https://www.npmjs.com/advisories/577", - "https://hackerone.com/reports/310443", - "https://github.com/advisories/GHSA-fvqr-27wr-82fm", - "https://nvd.nist.gov/vuln/detail/CVE-2018-3721", - "https://security.netapp.com/advisory/ntap-20190919-0004", - "https://security.netapp.com/advisory/ntap-20190919-0004/", - "https://github.com/lodash/lodash/commit/d8e069cc3410082e44eb18fcf8e7f3d08ebe1d4a" - ] - }, - { - "cves": [ - { - "cve": "CVE-2021-23337", - "cvss_v2_score": "6.5", - "cvss_v2_vector": "CVSS:2.0/AV:N/AC:L/Au:S/C:P/I:P/A:P", - "cvss_v3_score": "7.2", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H", - "cwe": [ - "CWE-77", - "CWE-94" - ], - "cwe_details": { - "CWE-77": { - "name": "Improper Neutralization of Special Elements used in a Command ('Command Injection')", - "description": "The product constructs all or part of a command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended command when it is sent to a downstream component.", - "categories": [ - { - "category": "2023 CWE Top 25", - "rank": "16" - } - ] - }, - "CWE-94": { - "name": "Improper Control of Generation of Code ('Code Injection')", - "description": "The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.", - "categories": [ - { - "category": "2023 CWE Top 25", - "rank": "23" - } - ] - } - } - } - ], - "summary": "Lodash versions prior to 4.17.21 are vulnerable to Command Injection via the template function.", - "severity": "High", - "components": { - "npm://lodash:4.17.0": { - "fixed_versions": [ - "[4.17.21]" - ], - "impact_paths": [ - [ - { - "component_id": "npm://froghome:1.0.0" - }, - { - "component_id": "npm://lodash:4.17.0" - } - ] - ] - } - }, - "issue_id": "XRAY-140575", - "references": [ - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSNPM-1074929", - "https://security.netapp.com/advisory/ntap-20210312-0006/", - "https://snyk.io/vuln/SNYK-JS-LODASH-1040724", - "https://security.netapp.com/advisory/ntap-20210312-0006", - "https://www.oracle.com/security-alerts/cpujan2022.html", - "https://github.com/lodash/lodash/commit/3469357cff396a26c363f8c1b5a91dde28ba4b1c", - "https://cert-portal.siemens.com/productcert/pdf/ssa-637483.pdf", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSBOWER-1074928", - "https://www.oracle.com/security-alerts/cpuoct2021.html", - "https://snyk.io/vuln/SNYK-JAVA-ORGFUJIONWEBJARS-1074932", - "https://github.com/lodash/lodash/blob/ddfd9b11a0126db2302cb70ec9973b66baec0975/lodash.js%23L14851", - "https://github.com/advisories/GHSA-35jh-r3h4-6jhm", - "https://www.oracle.com/security-alerts/cpujul2022.html", - "https://www.oracle.com//security-alerts/cpujul2021.html", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARS-1074930", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSBOWERGITHUBLODASH-1074931", - "https://nvd.nist.gov/vuln/detail/CVE-2021-23337", - "https://github.com/lodash/lodash/blob/ddfd9b11a0126db2302cb70ec9973b66baec0975/lodash.js#L14851" - ], - "extended_information": { - "short_description": "Improper sanitization in the lodash template function leads to JavaScript code injection through the options argument.", - "full_description": "JavaScript-based applications (both frontend and backend) that use the [template function](https://lodash.com/docs/4.17.15#template) -`_.template([string=''], [options={}])` from the [lodash](https://lodash.com/) utility library and provide the `options` argument (specifically the `variable` option) from untrusted user input, are vulnerable to JavaScript code injection. This issue can be easily exploited, and an exploitation example is [publicly available](https://github.com/lodash/lodash/commit/3469357cff396a26c363f8c1b5a91dde28ba4b1c#diff-a561630bb56b82342bc66697aee2ad96efddcbc9d150665abd6fb7ecb7c0ab2fR22303) in the fix tests that was introduced in version 4.17.21 - \n```js\nlodash.template('', { variable: '){console.log(process.env)}; with(obj' })()\n```", - "jfrog_research_severity": "Medium", - "jfrog_research_severity_reasons": [ - { - "name": "The prerequisites for exploiting the issue are extremely unlikely", - "description": "It is highly unlikely that a JS program will accept arbitrary remote input into the template's `options` argument", - "is_positive": true - }, - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "The attacker must find remote input that propagates into the `options` argument of a `template` call", - "is_positive": true - }, - { - "name": "The issue results in a severe impact (such as remote code execution)", - "description": "Leads to remote code execution through JS code injection" - }, - { - "name": "The issue has an exploit published", - "description": "Published exploit demonstrates arbitrary JS code execution" - } - ] - } - }, - { - "cves": [ - { - "cve": "CVE-2018-16487", - "cvss_v2_score": "6.8", - "cvss_v2_vector": "CVSS:2.0/AV:N/AC:M/Au:N/C:P/I:P/A:P", - "cvss_v3_score": "5.6", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L", - "cwe": [ - "CWE-400", - "NVD-CWE-noinfo" - ], - "cwe_details": { - "CWE-400": { - "name": "Uncontrolled Resource Consumption", - "description": "The product does not properly control the allocation and maintenance of a limited resource, thereby enabling an actor to influence the amount of resources consumed, eventually leading to the exhaustion of available resources." - } - } - } - ], - "summary": "A prototype pollution vulnerability was found in lodash \u003c4.17.11 where the functions merge, mergeWith, and defaultsDeep can be tricked into adding or modifying properties of Object.prototype.", - "severity": "Medium", - "components": { - "npm://lodash:4.17.0": { - "fixed_versions": [ - "[4.17.11]" - ], - "impact_paths": [ - [ - { - "component_id": "npm://froghome:1.0.0" - }, - { - "component_id": "npm://lodash:4.17.0" - } - ] - ] - } - }, - "issue_id": "XRAY-75300", - "references": [ - "https://nvd.nist.gov/vuln/detail/CVE-2018-16487", - "https://www.npmjs.com/advisories/782", - "https://security.netapp.com/advisory/ntap-20190919-0004/", - "https://github.com/advisories/GHSA-4xc9-xhrj-v574", - "https://github.com/lodash/lodash/commit/90e6199a161b6445b01454517b40ef65ebecd2ad", - "https://security.netapp.com/advisory/ntap-20190919-0004", - "https://hackerone.com/reports/380873" - ], - "extended_information": { - "short_description": "Insufficient input validation in the Lodash library leads to prototype pollution.", - "full_description": "The [Lodash](https://lodash.com/) library is an open-source JavaScript project that simplifies operations on string, arrays, numbers, and other objects. It is widely used in connected devices. \n\nThe `merge`, `mergeWith`, and `defaultsDeep` methods in Lodash are vulnerable to [prototype pollution](https://shieldfy.io/security-wiki/prototype-pollution/introduction-to-prototype-pollution/). Attackers can exploit this vulnerability by specifying a crafted `sources` parameter to any of these methods, which can modify the prototype properties of the `Object`, `Function`, `Array`, `String`, `Number`, and `Boolean` objects. A public [exploit](https://hackerone.com/reports/380873) exists which performs the prototype pollution with an arbitrary key and value.\n\nThe library implementation has a bug in the `safeGet()` function in the `lodash.js` module that allows for adding or modifying `prototype` properties of various objects. The official [solution](https://github.com/lodash/lodash/commit/90e6199a161b6445b01454517b40ef65ebecd2ad) fixes the bug by explicitly forbidding the addition or modification of `prototype` properties.\n\nA related CVE (CVE-2018-3721) covers the same issue prior to Lodash version 4.17.5, but the fix for that was incomplete.", - "jfrog_research_severity": "High", - "jfrog_research_severity_reasons": [ - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "An attacker must find remote input that propagates into one of the following methods - \n* `merge` - 2nd argument\n* `mergeWith` - 2nd argument\n* `defaultsDeep` - 2nd argument", - "is_positive": true - }, - { - "name": "The impact of exploiting the issue depends on the context of surrounding software. A severe impact such as RCE is not guaranteed.", - "description": "A prototype pollution attack allows the attacker to inject new properties to all JavaScript objects (but not set existing properties).\nTherefore, the impact of a prototype pollution attack depends on the way the JavaScript code uses any object properties after the attack is triggered.\nUsually, a DoS attack is possible since invalid properties quickly lead to an exception being thrown. In more severe cases, RCE may be achievable.", - "is_positive": true - }, - { - "name": "The issue has an exploit published", - "description": "A public PoC demonstrated exploitation by injecting an attacker controlled key and value into the prototype" - } - ], - "remediation": "##### Development mitigations\n\nAdd the `Object.freeze(Object.prototype);` directive once at the beginning of your main JS source code file (ex. `index.js`), preferably after all your `require` directives. This will prevent any changes to the prototype object, thus completely negating prototype pollution attacks." - } - }, - { - "cves": [ - { - "cve": "CVE-2024-29041", - "cvss_v3_score": "6.1", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N", - "cwe": [ - "CWE-601", - "CWE-1286" - ], - "cwe_details": { - "CWE-1286": { - "name": "Improper Validation of Syntactic Correctness of Input", - "description": "The product receives input that is expected to be well-formed - i.e., to comply with a certain syntax - but it does not validate or incorrectly validates that the input complies with the syntax." - }, - "CWE-601": { - "name": "URL Redirection to Untrusted Site ('Open Redirect')", - "description": "A web application accepts a user-controlled input that specifies a link to an external site, and uses that link in a Redirect. This simplifies phishing attacks." - } - } - } - ], - "summary": "Express.js minimalist web framework for node. Versions of Express.js prior to 4.19.0 and all pre-release alpha and beta versions of 5.0 are affected by an open redirect vulnerability using malformed URLs. When a user of Express performs a redirect using a user-provided URL Express performs an encode [using `encodeurl`](https://github.com/pillarjs/encodeurl) on the contents before passing it to the `location` header. This can cause malformed URLs to be evaluated in unexpected ways by common redirect allow list implementations in Express applications, leading to an Open Redirect via bypass of a properly implemented allow list. The main method impacted is `res.location()` but this is also called from within `res.redirect()`. The vulnerability is fixed in 4.19.2 and 5.0.0-beta.3.", - "severity": "Medium", - "components": { - "npm://express:4.18.2": { - "fixed_versions": [ - "[4.19.2]", - "[5.0.0-beta.3]" - ], - "impact_paths": [ - [ - { - "component_id": "npm://froghome:1.0.0" - }, - { - "component_id": "npm://express:4.18.2" - } - ] - ] - } - }, - "issue_id": "XRAY-594935", - "references": [ - "https://github.com/koajs/koa/issues/1800", - "https://github.com/expressjs/express/pull/5539", - "https://github.com/expressjs/express/commit/0b746953c4bd8e377123527db11f9cd866e39f94", - "https://github.com/expressjs/express/commit/0867302ddbde0e9463d0564fea5861feb708c2dd", - "https://github.com/advisories/GHSA-rv95-896h-c2vc", - "https://expressjs.com/en/4x/api.html#res.location", - "https://nvd.nist.gov/vuln/detail/CVE-2024-29041", - "https://github.com/expressjs/express/security/advisories/GHSA-rv95-896h-c2vc" - ] - }, - { - "cves": [ - { - "cve": "CVE-2022-29078", - "cvss_v2_score": "7.5", - "cvss_v2_vector": "CVSS:2.0/AV:N/AC:L/Au:N/C:P/I:P/A:P", - "cvss_v3_score": "9.8", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", - "cwe": [ - "CWE-94", - "CWE-74" - ], - "cwe_details": { - "CWE-74": { - "name": "Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection')", - "description": "The product constructs all or part of a command, data structure, or record using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify how it is parsed or interpreted when it is sent to a downstream component." - }, - "CWE-94": { - "name": "Improper Control of Generation of Code ('Code Injection')", - "description": "The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.", - "categories": [ - { - "category": "2023 CWE Top 25", - "rank": "23" - } - ] - } - } - } - ], - "summary": "The ejs (aka Embedded JavaScript templates) package 3.1.6 for Node.js allows server-side template injection in settings[view options][outputFunctionName]. This is parsed as an internal option, and overwrites the outputFunctionName option with an arbitrary OS command (which is executed upon template compilation).", - "severity": "Critical", - "components": { - "npm://ejs:3.1.6": { - "fixed_versions": [ - "[3.1.7]" - ], - "impact_paths": [ - [ - { - "component_id": "npm://froghome:1.0.0" - }, - { - "component_id": "npm://ejs:3.1.6" - } - ] - ] - } - }, - "issue_id": "XRAY-209002", - "references": [ - "https://github.com/mde/ejs/commit/15ee698583c98dadc456639d6245580d17a24baf", - "https://eslam.io/posts/ejs-server-side-template-injection-rce/", - "https://security.netapp.com/advisory/ntap-20220804-0001", - "https://github.com/mde/ejs/releases", - "https://nvd.nist.gov/vuln/detail/CVE-2022-29078", - "https://eslam.io/posts/ejs-server-side-template-injection-rce", - "https://github.com/mde/ejs", - "https://security.netapp.com/advisory/ntap-20220804-0001/" - ], - "extended_information": { - "short_description": "Insufficient input validation in EJS enables attackers to perform template injection when attacker can control the rendering options.", - "full_description": "[Embedded JavaScript templates](https://github.com/mde/ejs), also known as EJS, is one of the most popular Node.js templating engines, which is compiled with the Express JS view system.\n\nWhen rendering views using EJS, it is possible to perform template injection on the `opts.outputFunctionName` variable, since the variable is injected into the template body without any escaping. Although it is unlikely that the attacker can directly control the `outputFunctionName` property, it is possible that it can be influenced in conjunction with a prototype pollution vulnerability.\n\nOnce template injection is achieved, the attacker can immediately perform remote code execution since the template engine (EJS) allows executing arbitrary JavaScript code.\n\nExample of a vulnerable Node.js application -\n```js\nconst express = require('express');\nconst bodyParser = require('body-parser');\nconst lodash = require('lodash');\nconst ejs = require('ejs');\n\nconst app = express();\n\napp\n .use(bodyParser.urlencoded({extended: true}))\n .use(bodyParser.json());\n\napp.set('views', './');\napp.set('view engine', 'ejs');\n\napp.get(\"/\", (req, res) =\u003e {\n res.render('index');\n});\n\napp.post(\"/\", (req, res) =\u003e {\n let data = {};\n let input = JSON.parse(req.body.content);\n lodash.defaultsDeep(data, input);\n res.json({message: \"OK\"});\n});\n\nlet server = app.listen(8086, '0.0.0.0', function() {\n console.log('Listening on port %d', server.address().port);\n});\n```\n\nExploiting the above example for RCE -\n`curl 127.0.0.1:8086 -v --data 'content={\"constructor\": {\"prototype\": {\"outputFunctionName\": \"a; return global.process.mainModule.constructor._load(\\\"child_process\\\").execSync(\\\"whoami\\\"); //\"}}}'\n`\n\nDue to the prototype pollution in the `lodash.defaultsDeep` call, an attacker can inject the `outputFunctionName` property with an arbitrary value. The chosen value executes an arbitrary process via the `child_process` module.", - "jfrog_research_severity": "Medium", - "jfrog_research_severity_reasons": [ - { - "name": "The prerequisites for exploiting the issue are extremely unlikely", - "description": "The attacker has to find a way to get their malicious input to `opts.outputFunctionName`, which will usually require exploitation of a prototype pollution vulnerability somewhere else in the code. However, there could be cases where the attacker can pass malicious data to the render function directly because of design problems in other code using EJS.", - "is_positive": true - }, - { - "name": "The issue has an exploit published", - "description": "There are multiple examples of exploits for this vulnerability online." - }, - { - "name": "The issue results in a severe impact (such as remote code execution)", - "description": "Successful exploitation of this vulnerability leads to remote code execution." - } - ], - "remediation": "##### Development mitigations\n\nAdd the `Object.freeze(Object.prototype);` directive once at the beginning of your main JS source code file (ex. `index.js`), preferably after all your `require` directives. This will prevent any changes to the prototype object, thus completely negating prototype pollution attacks.\n\nNote that this mitigation is supposed to stop any prototype pollution attacks which can allow an attacker to control the `opts.outputFunctionName` parameter indirectly.\n\nThe mitigation will not stop any (extremely unlikely) scenarios where the JavaScript code allows external input to directly affect `opts.outputFunctionName`." - } - }, - { - "cves": [ - { - "cve": "CVE-2024-33883", - "cvss_v3_score": "4.0", - "cvss_v3_vector": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L", - "cwe": [ - "CWE-1321", - "CWE-693" - ], - "cwe_details": { - "CWE-1321": { - "name": "Improperly Controlled Modification of Object Prototype Attributes ('Prototype Pollution')", - "description": "The product receives input from an upstream component that specifies attributes that are to be initialized or updated in an object, but it does not properly control modifications of attributes of the object prototype." - }, - "CWE-693": { - "name": "Protection Mechanism Failure", - "description": "The product does not use or incorrectly uses a protection mechanism that provides sufficient defense against directed attacks against the product." - } - } - } - ], - "summary": "The ejs (aka Embedded JavaScript templates) package before 3.1.10 for Node.js lacks certain pollution protection.", - "severity": "Medium", - "components": { - "npm://ejs:3.1.6": { - "fixed_versions": [ - "[3.1.10]" - ], - "impact_paths": [ - [ - { - "component_id": "npm://froghome:1.0.0" - }, - { - "component_id": "npm://ejs:3.1.6" - } - ] - ] - } - }, - "issue_id": "XRAY-599735", - "references": [ - "https://security.netapp.com/advisory/ntap-20240605-0003/", - "https://security.netapp.com/advisory/ntap-20240605-0003", - "https://github.com/mde/ejs/commit/e469741dca7df2eb400199e1cdb74621e3f89aa5", - "https://github.com/mde/ejs/compare/v3.1.9...v3.1.10", - "https://github.com/advisories/GHSA-ghr5-ch3p-vcr6", - "https://nvd.nist.gov/vuln/detail/CVE-2024-33883" - ], - "extended_information": { - "short_description": "Insufficient input validation in EJS may lead to prototype pollution.", - "full_description": "[Embedded JavaScript templates](https://github.com/mde/ejs), also known as `EJS`, is one of the most popular Node.js templating engines, which is compiled with the Express JS view system.\n\nA prototype pollution gadget within the EJS template engine could potentially be leveraged by attackers to achieve remote code execution or DoS via prototype pollution.\n\n```\nfunction Template(text, opts) {\n opts = opts || utils.createNullProtoObjWherePossible();\n```\n\nWhen checking for the presence of a property within an object variable, the lookup scope isn't explicitly defined. In JavaScript, the absence of a defined lookup scope prompts a search up to the root prototype (`Object.prototype`). This could potentially be under the control of an attacker if another prototype pollution vulnerability is present within the application.\n\nIf the application server is using the EJS as the backend template engine, and there is another prototype pollution vulnerability in the application, then the attacker could leverage the found gadgets in the EJS template engine to escalate the prototype pollution to remote code execution or DoS.\n\nThe following code will execute a command on the server by polluting `opts.escapeFunction`:\n \n```\nconst express = require('express');\nconst app = express();\nconst port = 8008;\nconst ejs = require('ejs');\n\n// Set EJS as the view engine\napp.set('view engine', 'ejs');\n\napp.get('/', (req, res) =\u003e {\n \n const data = {title: 'Welcome', message: 'Hello'};\n\n // Sample EJS template string\n const templateString = `\u003chtml\u003e\u003chead\u003e\u003ctitle\u003e\u003c%= title %\u003e\u003c/title\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1\u003e\u003c%= message %\u003e\u003c/h1\u003e\u003c/body\u003e\u003c/html\u003e`;\n\n const { exec } = require('child_process');\n\n function myFunc() {\n exec('bash -c \"echo 123\"', (error, stdout, stderr) =\u003e {\n if (error) {\n console.error(`exec error: ${error}`);\n return;\n }\n if (stderr){\n console.log(`stderr : ${stderr}`);\n return;\n }\n // Handle success\n console.log(`Command executed successfully. Output: ${stdout}`);\n });\n }\n\n const options = {client:false};\n\n Object.prototype.escapeFunction = myFunc;\n \n const compiledTemplate = ejs.compile(templateString, options);\n const renderedHtml = compiledTemplate(data);\n res.send(renderedHtml);\n});\n\n// Start the server\napp.listen(port, () =\u003e {\n console.log(`Server is running on http://localhost:${port}`);\n});\n```", - "jfrog_research_severity": "Medium", - "jfrog_research_severity_reasons": [ - { - "name": "The prerequisites for exploiting the issue are extremely unlikely", - "description": "Attackers can only leverage this vulnerability when the application server is using the EJS as the backend template engine. Moreover, there must be a second prototype pollution vulnerability in the application.", - "is_positive": true - }, - { - "name": "The reported CVSS was either wrongly calculated, downgraded by other vendors, or does not reflect the vulnerability's impact", - "description": "CVSS does not take into account the unlikely prerequisites necessary for exploitation.", - "is_positive": true - }, - { - "name": "The issue results in a severe impact (such as remote code execution)", - "description": "A prototype pollution attack allows the attacker to inject new properties into all JavaScript objects.\nTherefore, the impact of a prototype pollution attack depends on the way the JavaScript code uses any object properties after the attack is triggered.\nUsually, a DoS attack is possible since invalid properties quickly lead to an exception being thrown. In more severe cases, RCE may be achievable." - } - ] - } - }, - { - "cves": [ - { - "cve": "CVE-2023-29827", - "cvss_v3_score": "9.8", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", - "cwe": [ - "CWE-74" - ], - "cwe_details": { - "CWE-74": { - "name": "Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection')", - "description": "The product constructs all or part of a command, data structure, or record using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify how it is parsed or interpreted when it is sent to a downstream component." - } - } - } - ], - "summary": "ejs v3.1.9 is vulnerable to server-side template injection. If the ejs file is controllable, template injection can be implemented through the configuration settings of the closeDelimiter parameter. NOTE: this is disputed by the vendor because the render function is not intended to be used with untrusted input.", - "severity": "Critical", - "components": { - "npm://ejs:3.1.6": { - "impact_paths": [ - [ - { - "component_id": "npm://froghome:1.0.0" - }, - { - "component_id": "npm://ejs:3.1.6" - } - ] - ] - } - }, - "issue_id": "XRAY-520200", - "references": [ - "https://nvd.nist.gov/vuln/detail/CVE-2023-29827", - "https://github.com/mde/ejs/issues/720", - "https://github.com/mde/ejs/blob/main/SECURITY.md#out-of-scope-vulnerabilities" - ], - "extended_information": { - "short_description": "Insufficient input validation can lead to template injection in ejs when attackers can control both the rendered template and rendering options.", - "full_description": "[Embedded JavaScript templates](https://github.com/mde/ejs), also known as EJS, is one of the most popular Node.js templating engines, which is compiled with the Express JS view system.\n\nWhen rendering views using EJS, it is possible to bypass ejs' template injection restrictions, by abusing the `closeDelimiter` rendering option, in the case when -\n1. The template itself can be partially controlled by the attacker\n2. The template rendering options can be fully controlled by the attacker\n\nThe vulnerability was **rightfully disputed** due to the fact that a vulnerable configuration is extremely unlikely to exist in any real-world setup. As such, the maintainers will not provide a fix for this (non-)issue.\n\nExample of a vulnerable application -\n```js\nconst express = require('express')\nconst app = express()\nconst port = 3000\n\napp.set('view engine', 'ejs');\n\napp.get('/page', (req,res) =\u003e {\n res.render('page', req.query); // OPTS (2nd parameter) IS ATTACKER-CONTROLLED\n})\n\napp.listen(port, () =\u003e {\n console.log(\"Example app listening on port ${port}\")\n})\n```\n\nContents of `page.ejs` (very unlikely to be attacker controlled) -\n```js\n%%1\");process.mainModule.require('child_process').execSync('calc');//\n```\n\nIn this case, sending `closeDelimiter` with the same malicious code that already exists at `page.ejs` will trigger the injection -\n`http://127.0.0.1:3000/page?settings[view%20options][closeDelimiter]=1\")%3bprocess.mainModule.require('child_process').execSync('calc')%3b//`", - "jfrog_research_severity": "Low", - "jfrog_research_severity_reasons": [ - { - "name": "The reported CVSS was either wrongly calculated, downgraded by other vendors, or does not reflect the vulnerability's impact", - "description": "The CVSS does not take into account the rarity of a vulnerable configuration to exist", - "is_positive": true - }, - { - "name": "The prerequisites for exploiting the issue are extremely unlikely", - "description": "The vulnerability can be exploited only under the following conditions -\n1. The template itself can be partially controlled by the attacker\n2. The template rendering options can be fully controlled by the attacker\nThis vulnerable configuration is extremely unlikely to exist in any real-world setup.", - "is_positive": true - }, - { - "name": "The issue has been disputed by the vendor", - "is_positive": true - }, - { - "name": "The issue has an exploit published", - "description": "Published exploit demonstrates template injection" - } - ] - } - } - ], - "component_id": "root", - "package_type": "generic", - "status": "completed" - }, - "status_code": 0 - } - ] - }, - "jas_scans": { - "contextual_analysis": [ - { - "scan_status": 0, - "scan": [ - { - "tool": { - "driver": { - "informationUri": "https://jfrog.com/help/r/jfrog-security-documentation/jfrog-advanced-security", - "name": "JFrog Applicability Scanner", - "rules": [ - { - "id": "applic_CVE-2018-16487", - "name": "CVE-2018-16487", - "shortDescription": { - "text": "Scanner for CVE-2018-16487" - }, - "fullDescription": { - "text": "The scanner checks whether any of the following vulnerable functions are called:\n\n* `lodash.merge` with external input to its 2nd (`sources`) argument.\n* `lodash.mergeWith` with external input to its 2nd (`sources`) argument.\n* `lodash.defaultsDeep` with external input to its 2nd (`sources`) argument.\n\nThe scanner also checks whether the `Object.freeze()` remediation is not present.", - "markdown": "The scanner checks whether any of the following vulnerable functions are called:\n\n* `lodash.merge` with external input to its 2nd (`sources`) argument.\n* `lodash.mergeWith` with external input to its 2nd (`sources`) argument.\n* `lodash.defaultsDeep` with external input to its 2nd (`sources`) argument.\n\nThe scanner also checks whether the `Object.freeze()` remediation is not present." - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive", - "security-severity": "6.9" - } - }, - { - "id": "applic_CVE-2019-10744", - "name": "CVE-2019-10744", - "shortDescription": { - "text": "Scanner for CVE-2019-10744" - }, - "fullDescription": { - "text": "The scanner checks whether the vulnerable function `defaultsDeep` is called with external input to its 2nd (`sources`) argument, and the `Object.freeze()` remediation is not present.", - "markdown": "The scanner checks whether the vulnerable function `defaultsDeep` is called with external input to its 2nd (`sources`) argument, and the `Object.freeze()` remediation is not present." - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive", - "security-severity": "6.9" - } - }, - { - "id": "applic_CVE-2020-28500", - "name": "CVE-2020-28500", - "shortDescription": { - "text": "Scanner for CVE-2020-28500" - }, - "fullDescription": { - "text": "The scanner checks whether any of the following vulnerable functions are called:\n\n* `lodash.trim` with external input to its 1st (`string`) argument.\n* `lodash.toNumber` with external input to its 1st (`value`) argument.\n* `lodash.trimEnd` with external input to its 1st (`string`) argument.", - "markdown": "The scanner checks whether any of the following vulnerable functions are called:\n\n* `lodash.trim` with external input to its 1st (`string`) argument.\n* `lodash.toNumber` with external input to its 1st (`value`) argument.\n* `lodash.trimEnd` with external input to its 1st (`string`) argument." - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive", - "security-severity": "6.9" - } - }, - { - "id": "applic_CVE-2020-8203", - "name": "CVE-2020-8203", - "shortDescription": { - "text": "Scanner for CVE-2020-8203" - }, - "fullDescription": { - "text": "The scanner checks whether the vulnerable function `zipObjectDeep` is called with external input to its 1st (`props`) and 2nd (`values`) arguments, and the `Object.freeze()` remediation is not present.", - "markdown": "The scanner checks whether the vulnerable function `zipObjectDeep` is called with external input to its 1st (`props`) and 2nd (`values`) arguments, and the `Object.freeze()` remediation is not present." - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive", - "security-severity": "6.9" - } - }, - { - "id": "applic_CVE-2021-23337", - "name": "CVE-2021-23337", - "shortDescription": { - "text": "Scanner for CVE-2021-23337" - }, - "fullDescription": { - "text": "The scanner checks whether the vulnerable function `lodash.template` is called with external input to its 2nd (`options`) argument.", - "markdown": "The scanner checks whether the vulnerable function `lodash.template` is called with external input to its 2nd (`options`) argument." - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive", - "security-severity": "6.9" - } - }, - { - "id": "applic_CVE-2022-29078", - "name": "CVE-2022-29078", - "shortDescription": { - "text": "Scanner for CVE-2022-29078" - }, - "fullDescription": { - "text": "The scanner checks for two vulnerable flows:\n\n1. Whether the `express.set` function is called with the arguments: `view engine` and `ejs`, or external input and if it's followed by a call to the vulnerable function `render` with an unknown second argument.\n\n2. Whether the `renderFile` function is called with an unknown second argument.\n\nThe scanner also checks whether the `Object.freeze()` remediation is not present.", - "markdown": "The scanner checks for two vulnerable flows:\n\n1. Whether the `express.set` function is called with the arguments: `view engine` and `ejs`, or external input and if it's followed by a call to the vulnerable function `render` with an unknown second argument.\n\n2. Whether the `renderFile` function is called with an unknown second argument.\n\nThe scanner also checks whether the `Object.freeze()` remediation is not present." - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive", - "security-severity": "6.9" - } - }, - { - "id": "applic_CVE-2024-33883", - "name": "CVE-2024-33883", - "shortDescription": { - "text": "Scanner for CVE-2024-33883" - }, - "fullDescription": { - "text": "The scanner checks whether the vulnerable function `ejs.compile()` is called.", - "markdown": "The scanner checks whether the vulnerable function `ejs.compile()` is called." - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive", - "security-severity": "6.9" - } - }, - { - "id": "applic_CVE-2023-29827", - "name": "CVE-2023-29827", - "shortDescription": { - "text": "Scanner for CVE-2023-29827" - }, - "fullDescription": { - "text": "The scanner checks whether any of the following conditions are met:\n\n1. The `ejs.renderFile` function is called with an unknown third argument.\n\n2. The `ejs.compile` function is called with an unknown second argument.\n\n3. The `express.set` function is called with any of the following arguments:\n\n* `express.set(\"view engine\", \"ejs\")`\n* `express.set(\"view engine\", {USER_INPUT})`\n* `express.set({USER_INPUT}, \"ejs\")`\n* `express.set({USER_INPUT}, {USER_INPUT})`", - "markdown": "The scanner checks whether any of the following conditions are met:\n\n1. The `ejs.renderFile` function is called with an unknown third argument.\n\n2. The `ejs.compile` function is called with an unknown second argument.\n\n3. The `express.set` function is called with any of the following arguments:\n\n* `express.set(\"view engine\", \"ejs\")`\n* `express.set(\"view engine\", {USER_INPUT})`\n* `express.set({USER_INPUT}, \"ejs\")`\n* `express.set({USER_INPUT}, {USER_INPUT})`" - }, - "properties": { - "applicability": "applicable", - "conclusion": "negative", - "security-severity": "6.9" - } - }, - { - "id": "applic_CVE-2018-3721", - "name": "CVE-2018-3721", - "shortDescription": { - "text": "Scanner for uncovered CVE-2018-3721" - }, - "fullDescription": { - "text": "", - "markdown": "" - }, - "properties": { - "applicability": "not_covered" - } - }, - { - "id": "applic_CVE-2019-1010266", - "name": "CVE-2019-1010266", - "shortDescription": { - "text": "Scanner for uncovered CVE-2019-1010266" - }, - "fullDescription": { - "text": "", - "markdown": "" - }, - "properties": { - "applicability": "not_covered" - } - }, - { - "id": "applic_CVE-2024-39249", - "name": "CVE-2024-39249", - "shortDescription": { - "text": "Scanner for uncovered CVE-2024-39249" - }, - "fullDescription": { - "text": "Never applicable. The vulnerability is exploitable only if an attacker has access to the source code.", - "markdown": "Never applicable. The vulnerability is exploitable only if an attacker has access to the source code." - }, - "properties": { - "applicability": "not_covered", - "security-severity": "6.9" - } - }, - { - "id": "applic_CVE-2024-29041", - "name": "CVE-2024-29041", - "shortDescription": { - "text": "Scanner for uncovered CVE-2024-29041" - }, - "fullDescription": { - "text": "", - "markdown": "" - }, - "properties": { - "applicability": "not_covered" - } - }, - { - "id": "applic_CVE-2024-39249", - "name": "CVE-2024-39249", - "shortDescription": { - "text": "Scanner for indirect dependency CVE-2024-39249" - }, - "fullDescription": { - "text": "Never applicable. The vulnerability is exploitable only if an attacker has access to the source code.", - "markdown": "Never applicable. The vulnerability is exploitable only if an attacker has access to the source code." - }, - "properties": { - "applicability": "not_applicable" - } - } - ], - "version": "1.0" - } - }, - "invocations": [ - { - "arguments": [ - "analyzerManager/jas_scanner/jas_scanner", - "scan", - "/Applicability_1725803037/config.yaml" - ], - "executionSuccessful": true, - "workingDirectory": { - "uri": "/Users/user/ejs-frog-demo" - } - } - ], - "results": [ - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "applic_CVE-2018-16487", - "message": { - "text": "Prototype pollution `Object.freeze` remediation was detected" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/server.js" - }, - "region": { - "startLine": 4, - "startColumn": 1, - "endLine": 4, - "endColumn": 32, - "snippet": { - "text": "Object.freeze(Object.prototype)" - } - } - } - } - ] - }, - { - "ruleId": "applic_CVE-2018-16487", - "kind": "pass", - "message": { - "text": "The scanner checks whether any of the following vulnerable functions are called:\n\n* `lodash.merge` with external input to its 2nd (`sources`) argument.\n* `lodash.mergeWith` with external input to its 2nd (`sources`) argument.\n* `lodash.defaultsDeep` with external input to its 2nd (`sources`) argument.\n\nThe scanner also checks whether the `Object.freeze()` remediation is not present." - } - }, - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "applic_CVE-2019-10744", - "message": { - "text": "Prototype pollution `Object.freeze` remediation was detected" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/server.js" - }, - "region": { - "startLine": 4, - "startColumn": 1, - "endLine": 4, - "endColumn": 32, - "snippet": { - "text": "Object.freeze(Object.prototype)" - } - } - } - } - ] - }, - { - "ruleId": "applic_CVE-2019-10744", - "kind": "pass", - "message": { - "text": "The scanner checks whether the vulnerable function `defaultsDeep` is called with external input to its 2nd (`sources`) argument, and the `Object.freeze()` remediation is not present." - } - }, - { - "ruleId": "applic_CVE-2020-28500", - "kind": "pass", - "message": { - "text": "The scanner checks whether any of the following vulnerable functions are called:\n\n* `lodash.trim` with external input to its 1st (`string`) argument.\n* `lodash.toNumber` with external input to its 1st (`value`) argument.\n* `lodash.trimEnd` with external input to its 1st (`string`) argument." - } - }, - { - "ruleId": "applic_CVE-2020-8203", - "kind": "pass", - "message": { - "text": "The scanner checks whether the vulnerable function `zipObjectDeep` is called with external input to its 1st (`props`) and 2nd (`values`) arguments, and the `Object.freeze()` remediation is not present." - } - }, - { - "ruleId": "applic_CVE-2021-23337", - "kind": "pass", - "message": { - "text": "The scanner checks whether the vulnerable function `lodash.template` is called with external input to its 2nd (`options`) argument." - } - }, - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "applic_CVE-2022-29078", - "message": { - "text": "Prototype pollution `Object.freeze` remediation was detected" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/server.js" - }, - "region": { - "startLine": 4, - "startColumn": 1, - "endLine": 4, - "endColumn": 32, - "snippet": { - "text": "Object.freeze(Object.prototype)" - } - } - } - } - ] - }, - { - "ruleId": "applic_CVE-2022-29078", - "kind": "pass", - "message": { - "text": "The scanner checks for two vulnerable flows:\n\n1. Whether the `express.set` function is called with the arguments: `view engine` and `ejs`, or external input and if it's followed by a call to the vulnerable function `render` with an unknown second argument.\n\n2. Whether the `renderFile` function is called with an unknown second argument.\n\nThe scanner also checks whether the `Object.freeze()` remediation is not present." - } - }, - { - "ruleId": "applic_CVE-2024-33883", - "kind": "pass", - "message": { - "text": "The scanner checks whether the vulnerable function `ejs.compile()` is called." - } - }, - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "applic_CVE-2023-29827", - "message": { - "text": "The vulnerable functionality is triggered since express.set is called with 'view engine' as the first argument and 'ejs' as the second argument or both arguments with external input" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/server.js" - }, - "region": { - "startLine": 14, - "startColumn": 1, - "endLine": 14, - "endColumn": 30, - "snippet": { - "text": "app.set('view engine', 'ejs')" - } - } - } - } - ] - }, - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "applic_CVE-2023-29827", - "message": { - "text": "The vulnerable function render is called" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/server.js" - }, - "region": { - "startLine": 26, - "startColumn": 3, - "endLine": 26, - "endColumn": 38, - "snippet": { - "text": "res.render('pages/index',req.query)" - } - } - } - } - ] - }, - { - "ruleId": "applic_CVE-2024-39249", - "kind": "pass", - "message": { - "text": "Never applicable. The vulnerability is exploitable only if an attacker has access to the source code." - } - } - ] - } - ] - } - ], - "jas_vulnerabilities": { - "secrets": [ - { - "status_code": 0, - "scan": [ - { - "tool": { - "driver": { - "informationUri": "https://jfrog.com/help/r/jfrog-security-documentation/jfrog-advanced-security", - "name": "JFrog Secrets scanner", - "rules": [ - { - "id": "REQ.SECRET.GENERIC.TEXT", - "name": "REQ.SECRET.GENERIC.TEXT", - "shortDescription": { - "text": "Scanner for REQ.SECRET.GENERIC.TEXT" - }, - "fullDescription": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive" - } - }, - { - "id": "REQ.SECRET.GENERIC.CODE", - "name": "REQ.SECRET.GENERIC.CODE", - "shortDescription": { - "text": "Scanner for REQ.SECRET.GENERIC.CODE" - }, - "fullDescription": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive" - } - }, - { - "id": "REQ.SECRET.KEYS", - "name": "REQ.SECRET.KEYS", - "shortDescription": { - "text": "Scanner for REQ.SECRET.KEYS" - }, - "fullDescription": { - "text": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops\u0026tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n", - "markdown": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops\u0026tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n" - }, - "properties": { - "applicability": "applicable", - "conclusion": "negative", - "security-severity": "6.9" - } - }, - { - "id": "REQ.CRED.PUBLIC-ONLY", - "name": "REQ.CRED.PUBLIC-ONLY", - "shortDescription": { - "text": "Scanner for REQ.CRED.PUBLIC-ONLY" - }, - "fullDescription": { - "text": "", - "markdown": "" - }, - "properties": { - "applicability": "undetermined", - "conclusion": "private" - } - }, - { - "id": "REQ.SECRET.GENERIC.URL-TEXT", - "name": "REQ.SECRET.GENERIC.URL-TEXT", - "shortDescription": { - "text": "Scanner for REQ.SECRET.GENERIC.URL-TEXT" - }, - "fullDescription": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive" - } - } - ], - "version": "1.0" - } - }, - "invocations": [ - { - "arguments": [ - "analyzerManager/jas_scanner/jas_scanner", - "scan", - "/Secrets_1725803029/config.yaml" - ], - "executionSuccessful": true, - "workingDirectory": { - "uri": "/Users/user/ejs-frog-demo" - } - } - ], - "results": [ - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "REQ.SECRET.KEYS", - "message": { - "text": "Secret keys were found" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/fake-creds.txt" - }, - "region": { - "startLine": 2, - "startColumn": 1, - "endLine": 2, - "endColumn": 11, - "snippet": { - "text": "Sqc************" - } - } - } - } - ] - }, - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "REQ.SECRET.KEYS", - "message": { - "text": "Secret keys were found" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/fake-creds.txt" - }, - "region": { - "startLine": 3, - "startColumn": 1, - "endLine": 3, - "endColumn": 11, - "snippet": { - "text": "gho************" - } - } - } - } - ] - }, - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "REQ.SECRET.KEYS", - "message": { - "text": "Secret keys were found" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/server.js" - }, - "region": { - "startLine": 11, - "startColumn": 14, - "endLine": 11, - "endColumn": 24, - "snippet": { - "text": "Sqc************" - } - } - } - } - ] - } - ] - } - ] - } - ], - "iac": [ - { - "status_code": 0, - "scan": [ - { - "tool": { - "driver": { - "informationUri": "https://docs.jfrog-applications.jfrog.io/jfrog-security-features/infrastructure-as-code-iac", - "name": "JFrog Terraform scanner", - "rules": [], - "version": "1.8.14" - } - }, - "invocations": [ - { - "arguments": [ - "analyzerManager/iac_scanner/tf_scanner", - "scan", - "/IaC_1725803037/config.yaml" - ], - "executionSuccessful": true, - "workingDirectory": { - "uri": "/Users/user/ejs-frog-demo" - } - } - ], - "results": [] - } - ] - } - ], - "sast": [ - { - "status_code": 0, - "scan": [ - { - "tool": { - "driver": { - "informationUri": "https://docs.jfrog-applications.jfrog.io/jfrog-security-features/sast", - "name": "🐸 JFrog SAST", - "rules": [ - { - "id": "js-express-without-helmet", - "shortDescription": { - "text": "Express Not Using Helmet" - }, - "fullDescription": { - "text": "\n### Overview\nHelmet library should be used when using Express in order to properly configure\nHTTP header settings to mitigate a range of well-known vulnerabilities.\n\n### Remediation\n```javascript\nconst helmet = require(\"helmet\");\nconst app = express()\n\napp.use(helmet())\n```\n\n### References\n[Best practices for Express](https://expressjs.com/en/advanced/best-practice-security.html)\n", - "markdown": "\n### Overview\nHelmet library should be used when using Express in order to properly configure\nHTTP header settings to mitigate a range of well-known vulnerabilities.\n\n### Remediation\n```javascript\nconst helmet = require(\"helmet\");\nconst app = express()\n\napp.use(helmet())\n```\n\n### References\n[Best practices for Express](https://expressjs.com/en/advanced/best-practice-security.html)\n" - }, - "defaultConfiguration": { - "parameters": { - "properties": { - "CWE": "693" - } - } - }, - "properties": { - "security-severity": "3.9" - } - }, - { - "id": "js-insecure-random", - "shortDescription": { - "text": "Use of Insecure Random" - }, - "fullDescription": { - "text": "\n### Overview\nA use of insecure random vulnerability is a type of security flaw that is\ncaused by the use of inadequate or predictable random numbers in a program\nor system. Random numbers are used in many security-related applications,\nsuch as generating cryptographic keys and if the numbers are not truly\nrandom, an attacker may be able to predict or recreate them, potentially\ncompromising the security of the system.\n\n### Vulnerable example\n```javascript\nvar randomNum = Math.random();\n```\n`Math.random` is not secured, as it creates predictable random numbers.\n\n### Remediation\n```diff\nvar randomNum = crypto.randomInt(0, 100)\n```\n`crypto.randomInt` is secured, and creates much less predictable random\nnumbers.\n", - "markdown": "\n### Overview\nA use of insecure random vulnerability is a type of security flaw that is\ncaused by the use of inadequate or predictable random numbers in a program\nor system. Random numbers are used in many security-related applications,\nsuch as generating cryptographic keys and if the numbers are not truly\nrandom, an attacker may be able to predict or recreate them, potentially\ncompromising the security of the system.\n\n### Vulnerable example\n```javascript\nvar randomNum = Math.random();\n```\n`Math.random` is not secured, as it creates predictable random numbers.\n\n### Remediation\n```diff\nvar randomNum = crypto.randomInt(0, 100)\n```\n`crypto.randomInt` is secured, and creates much less predictable random\nnumbers.\n" - }, - "defaultConfiguration": { - "parameters": { - "properties": { - "CWE": "338" - } - } - }, - "properties": { - "security-severity": "3.9" - } - }, - { - "id": "js-template-injection", - "shortDescription": { - "text": "Template Object Injection" - }, - "fullDescription": { - "text": "\n### Overview\nTemplate Object Injection (TOI) is a vulnerability that can occur in\nweb applications that use template engines to render dynamic content.\nTemplate engines are commonly used to generate HTML pages, emails, or\nother types of documents that include variable data. TOI happens when\nuntrusted user input is included as part of the template rendering\nprocess, and the template engine evaluates the input as a code\nexpression, leading to potential code injection or data tampering\nattacks. To prevent TOI vulnerabilities, it's important to sanitize and\nvalidate all user input that is used as part of the template rendering\nprocess.\n\n### Query operation\nIn this query we look for user inputs that flow directly to a\nrequest render.\n\n### Vulnerable example\n```javascript\nvar app = require('express')();\napp.set('view engine', 'hbs');\n\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n res.render('template', bodyParameter);\n});\n```\nIn this example, a user-provided data is injected directly into the\n`render` command, leading to potential code injection or data\ntampering attacks.\n\n### Remediation\n```diff\n+ const sanitizeHtml = require('sanitize-html');\nvar app = require('express')();\napp.set('view engine', 'hbs');\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n\n- res.render('template', bodyParameter);\n+ res.render('template', sanitizeHtml(bodyParameter));\n});\nUsing `sanitize-html`, the user-provided data is sanitized, before\nrendering to the response.\n```\n", - "markdown": "\n### Overview\nTemplate Object Injection (TOI) is a vulnerability that can occur in\nweb applications that use template engines to render dynamic content.\nTemplate engines are commonly used to generate HTML pages, emails, or\nother types of documents that include variable data. TOI happens when\nuntrusted user input is included as part of the template rendering\nprocess, and the template engine evaluates the input as a code\nexpression, leading to potential code injection or data tampering\nattacks. To prevent TOI vulnerabilities, it's important to sanitize and\nvalidate all user input that is used as part of the template rendering\nprocess.\n\n### Query operation\nIn this query we look for user inputs that flow directly to a\nrequest render.\n\n### Vulnerable example\n```javascript\nvar app = require('express')();\napp.set('view engine', 'hbs');\n\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n res.render('template', bodyParameter);\n});\n```\nIn this example, a user-provided data is injected directly into the\n`render` command, leading to potential code injection or data\ntampering attacks.\n\n### Remediation\n```diff\n+ const sanitizeHtml = require('sanitize-html');\nvar app = require('express')();\napp.set('view engine', 'hbs');\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n\n- res.render('template', bodyParameter);\n+ res.render('template', sanitizeHtml(bodyParameter));\n});\nUsing `sanitize-html`, the user-provided data is sanitized, before\nrendering to the response.\n```\n" - }, - "defaultConfiguration": { - "parameters": { - "properties": { - "CWE": "73" - } - } - }, - "properties": { - "security-severity": "8.9" - } - } - ], - "version": "1.8.14" - } - }, - "invocations": [ - { - "arguments": [ - "analyzerManager/zd_scanner/scanner", - "scan", - "/Sast_1725803040/results.sarif", - "/Sast_1725803040/config.yaml" - ], - "executionSuccessful": true, - "workingDirectory": { - "uri": "/Users/user/ejs-frog-demo" - } - } - ], - "results": [ - { - "ruleId": "js-template-injection", - "level": "error", - "message": { - "text": "Template Object Injection" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/server.js" - }, - "region": { - "startLine": 26, - "startColumn": 28, - "endLine": 26, - "endColumn": 37, - "snippet": { - "text": "req.query" - } - } - }, - "logicalLocations": [ - { - "fullyQualifiedName": "server.^_4" - } - ] - } - ], - "fingerprints": { - "precise_sink_and_sink_function": "a549106dc43cdc0d36b0f81d0465a5d2" - }, - "codeFlows": [ - { - "threadFlows": [ - { - "locations": [ - { - "location": { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/server.js" - }, - "region": { - "startLine": 21, - "startColumn": 23, - "endLine": 21, - "endColumn": 26, - "snippet": { - "text": "req" - } - } - }, - "logicalLocations": [ - { - "fullyQualifiedName": "server.^_4" - } - ] - } - }, - { - "location": { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/server.js" - }, - "region": { - "startLine": 26, - "startColumn": 28, - "endLine": 26, - "endColumn": 31, - "snippet": { - "text": "req" - } - } - }, - "logicalLocations": [ - { - "fullyQualifiedName": "server.^_4" - } - ] - } - }, - { - "location": { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/server.js" - }, - "region": { - "startLine": 26, - "startColumn": 28, - "endLine": 26, - "endColumn": 37, - "snippet": { - "text": "req.query" - } - } - }, - "logicalLocations": [ - { - "fullyQualifiedName": "server.^_4" - } - ] - } - } - ] - } - ] - } - ] - }, - { - "ruleId": "js-insecure-random", - "level": "note", - "message": { - "text": "Use of Insecure Random" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/public/js/bootstrap.js" - }, - "region": { - "startLine": 136, - "startColumn": 22, - "endLine": 136, - "endColumn": 35, - "snippet": { - "text": "Math.random()" - } - } - }, - "logicalLocations": [ - { - "fullyQualifiedName": "public.js.bootstrap.^_0.Util.getUID" - } - ] - } - ], - "fingerprints": { - "precise_sink_and_sink_function": "34331455b0d5edf4c232dd288225780e" - } - }, - { - "ruleId": "js-insecure-random", - "level": "note", - "message": { - "text": "Use of Insecure Random" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/public/js/bootstrap.bundle.js" - }, - "region": { - "startLine": 135, - "startColumn": 22, - "endLine": 135, - "endColumn": 35, - "snippet": { - "text": "Math.random()" - } - } - }, - "logicalLocations": [ - { - "fullyQualifiedName": "public.js.bootstrap\u003cdot\u003ebundle.^_0.Util.getUID" - } - ] - } - ], - "fingerprints": { - "precise_sink_and_sink_function": "281a027677521fa64de4ce1fe14e01ab" - } - }, - { - "ruleId": "js-express-without-helmet", - "level": "note", - "message": { - "text": "Express Not Using Helmet" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/server.js" - }, - "region": { - "startLine": 8, - "startColumn": 11, - "endLine": 8, - "endColumn": 20, - "snippet": { - "text": "express()" - } - } - }, - "logicalLocations": [ - { - "fullyQualifiedName": "server" - } - ] - } - ], - "fingerprints": { - "precise_sink_and_sink_function": "f8caf6a43a2c1eb41369843ca3c7d94c" - } - } - ] - } - ] - } - ] - }, - "jas_violations": { - "secrets": [ - { - "status_code": 0, - "scan": [ - { - "tool": { - "driver": { - "informationUri": "https://jfrog.com/help/r/jfrog-security-documentation/jfrog-advanced-security", - "name": "JFrog Secrets scanner", - "rules": [ - { - "id": "REQ.SECRET.GENERIC.TEXT", - "name": "REQ.SECRET.GENERIC.TEXT", - "shortDescription": { - "text": "Scanner for REQ.SECRET.GENERIC.TEXT" - }, - "fullDescription": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive" - } - }, - { - "id": "REQ.SECRET.GENERIC.CODE", - "name": "REQ.SECRET.GENERIC.CODE", - "shortDescription": { - "text": "Scanner for REQ.SECRET.GENERIC.CODE" - }, - "fullDescription": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive" - } - }, - { - "id": "REQ.SECRET.KEYS", - "name": "REQ.SECRET.KEYS", - "shortDescription": { - "text": "Scanner for REQ.SECRET.KEYS" - }, - "fullDescription": { - "text": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops\u0026tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n", - "markdown": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops\u0026tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n" - }, - "properties": { - "applicability": "applicable", - "conclusion": "negative", - "security-severity": "6.9" - } - }, - { - "id": "REQ.CRED.PUBLIC-ONLY", - "name": "REQ.CRED.PUBLIC-ONLY", - "shortDescription": { - "text": "Scanner for REQ.CRED.PUBLIC-ONLY" - }, - "fullDescription": { - "text": "", - "markdown": "" - }, - "properties": { - "applicability": "undetermined", - "conclusion": "private" - } - }, - { - "id": "REQ.SECRET.GENERIC.URL-TEXT", - "name": "REQ.SECRET.GENERIC.URL-TEXT", - "shortDescription": { - "text": "Scanner for REQ.SECRET.GENERIC.URL-TEXT" - }, - "fullDescription": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive" - } - } - ], - "version": "1.0" - } - }, - "invocations": [ - { - "arguments": [ - "analyzerManager/jas_scanner/jas_scanner", - "scan", - "/Secrets_1725803029/config.yaml" - ], - "executionSuccessful": true, - "workingDirectory": { - "uri": "/Users/user/ejs-frog-demo" - } - } - ], - "results": [ - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "REQ.SECRET.KEYS", - "message": { - "text": "Secret keys were found" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/fake-creds.txt" - }, - "region": { - "startLine": 3, - "startColumn": 1, - "endLine": 3, - "endColumn": 11, - "snippet": { - "text": "gho************" - } - } - } - } - ] - } - ] - } - ] - } - ], - "iac": [ - { - "status_code": 0, - "scan": [ - { - "tool": { - "driver": { - "informationUri": "https://docs.jfrog-applications.jfrog.io/jfrog-security-features/infrastructure-as-code-iac", - "name": "JFrog Terraform scanner", - "rules": [], - "version": "1.8.14" - } - }, - "invocations": [ - { - "arguments": [ - "analyzerManager/iac_scanner/tf_scanner", - "scan", - "/IaC_1725803037/config.yaml" - ], - "executionSuccessful": true, - "workingDirectory": { - "uri": "/Users/user/ejs-frog-demo" - } - } - ], - "results": [] - } - ] - } - ], - "sast": [ - { - "status_code": 0, - "scan": [ - { - "tool": { - "driver": { - "informationUri": "https://docs.jfrog-applications.jfrog.io/jfrog-security-features/sast", - "name": "🐸 JFrog SAST", - "rules": [ - { - "id": "js-express-without-helmet", - "shortDescription": { - "text": "Express Not Using Helmet" - }, - "fullDescription": { - "text": "\n### Overview\nHelmet library should be used when using Express in order to properly configure\nHTTP header settings to mitigate a range of well-known vulnerabilities.\n\n### Remediation\n```javascript\nconst helmet = require(\"helmet\");\nconst app = express()\n\napp.use(helmet())\n```\n\n### References\n[Best practices for Express](https://expressjs.com/en/advanced/best-practice-security.html)\n", - "markdown": "\n### Overview\nHelmet library should be used when using Express in order to properly configure\nHTTP header settings to mitigate a range of well-known vulnerabilities.\n\n### Remediation\n```javascript\nconst helmet = require(\"helmet\");\nconst app = express()\n\napp.use(helmet())\n```\n\n### References\n[Best practices for Express](https://expressjs.com/en/advanced/best-practice-security.html)\n" - }, - "defaultConfiguration": { - "parameters": { - "properties": { - "CWE": "693" - } - } - }, - "properties": { - "security-severity": "3.9" - } - }, - { - "id": "js-insecure-random", - "shortDescription": { - "text": "Use of Insecure Random" - }, - "fullDescription": { - "text": "\n### Overview\nA use of insecure random vulnerability is a type of security flaw that is\ncaused by the use of inadequate or predictable random numbers in a program\nor system. Random numbers are used in many security-related applications,\nsuch as generating cryptographic keys and if the numbers are not truly\nrandom, an attacker may be able to predict or recreate them, potentially\ncompromising the security of the system.\n\n### Vulnerable example\n```javascript\nvar randomNum = Math.random();\n```\n`Math.random` is not secured, as it creates predictable random numbers.\n\n### Remediation\n```diff\nvar randomNum = crypto.randomInt(0, 100)\n```\n`crypto.randomInt` is secured, and creates much less predictable random\nnumbers.\n", - "markdown": "\n### Overview\nA use of insecure random vulnerability is a type of security flaw that is\ncaused by the use of inadequate or predictable random numbers in a program\nor system. Random numbers are used in many security-related applications,\nsuch as generating cryptographic keys and if the numbers are not truly\nrandom, an attacker may be able to predict or recreate them, potentially\ncompromising the security of the system.\n\n### Vulnerable example\n```javascript\nvar randomNum = Math.random();\n```\n`Math.random` is not secured, as it creates predictable random numbers.\n\n### Remediation\n```diff\nvar randomNum = crypto.randomInt(0, 100)\n```\n`crypto.randomInt` is secured, and creates much less predictable random\nnumbers.\n" - }, - "defaultConfiguration": { - "parameters": { - "properties": { - "CWE": "338" - } - } - }, - "properties": { - "security-severity": "3.9" - } - }, - { - "id": "js-template-injection", - "shortDescription": { - "text": "Template Object Injection" - }, - "fullDescription": { - "text": "\n### Overview\nTemplate Object Injection (TOI) is a vulnerability that can occur in\nweb applications that use template engines to render dynamic content.\nTemplate engines are commonly used to generate HTML pages, emails, or\nother types of documents that include variable data. TOI happens when\nuntrusted user input is included as part of the template rendering\nprocess, and the template engine evaluates the input as a code\nexpression, leading to potential code injection or data tampering\nattacks. To prevent TOI vulnerabilities, it's important to sanitize and\nvalidate all user input that is used as part of the template rendering\nprocess.\n\n### Query operation\nIn this query we look for user inputs that flow directly to a\nrequest render.\n\n### Vulnerable example\n```javascript\nvar app = require('express')();\napp.set('view engine', 'hbs');\n\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n res.render('template', bodyParameter);\n});\n```\nIn this example, a user-provided data is injected directly into the\n`render` command, leading to potential code injection or data\ntampering attacks.\n\n### Remediation\n```diff\n+ const sanitizeHtml = require('sanitize-html');\nvar app = require('express')();\napp.set('view engine', 'hbs');\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n\n- res.render('template', bodyParameter);\n+ res.render('template', sanitizeHtml(bodyParameter));\n});\nUsing `sanitize-html`, the user-provided data is sanitized, before\nrendering to the response.\n```\n", - "markdown": "\n### Overview\nTemplate Object Injection (TOI) is a vulnerability that can occur in\nweb applications that use template engines to render dynamic content.\nTemplate engines are commonly used to generate HTML pages, emails, or\nother types of documents that include variable data. TOI happens when\nuntrusted user input is included as part of the template rendering\nprocess, and the template engine evaluates the input as a code\nexpression, leading to potential code injection or data tampering\nattacks. To prevent TOI vulnerabilities, it's important to sanitize and\nvalidate all user input that is used as part of the template rendering\nprocess.\n\n### Query operation\nIn this query we look for user inputs that flow directly to a\nrequest render.\n\n### Vulnerable example\n```javascript\nvar app = require('express')();\napp.set('view engine', 'hbs');\n\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n res.render('template', bodyParameter);\n});\n```\nIn this example, a user-provided data is injected directly into the\n`render` command, leading to potential code injection or data\ntampering attacks.\n\n### Remediation\n```diff\n+ const sanitizeHtml = require('sanitize-html');\nvar app = require('express')();\napp.set('view engine', 'hbs');\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n\n- res.render('template', bodyParameter);\n+ res.render('template', sanitizeHtml(bodyParameter));\n});\nUsing `sanitize-html`, the user-provided data is sanitized, before\nrendering to the response.\n```\n" - }, - "defaultConfiguration": { - "parameters": { - "properties": { - "CWE": "73" - } - } - }, - "properties": { - "security-severity": "8.9" - } - } - ], - "version": "1.8.14" - } - }, - "invocations": [ - { - "arguments": [ - "analyzerManager/zd_scanner/scanner", - "scan", - "/Sast_1725803040/results.sarif", - "/Sast_1725803040/config.yaml" - ], - "executionSuccessful": true, - "workingDirectory": { - "uri": "/Users/user/ejs-frog-demo" - } - } - ], - "results": [ - { - "ruleId": "js-template-injection", - "level": "error", - "message": { - "text": "Template Object Injection" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/server.js" - }, - "region": { - "startLine": 26, - "startColumn": 28, - "endLine": 26, - "endColumn": 37, - "snippet": { - "text": "req.query" - } - } - }, - "logicalLocations": [ - { - "fullyQualifiedName": "server.^_4" - } - ] - } - ], - "fingerprints": { - "precise_sink_and_sink_function": "a549106dc43cdc0d36b0f81d0465a5d2" - }, - "codeFlows": [ - { - "threadFlows": [ - { - "locations": [ - { - "location": { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/server.js" - }, - "region": { - "startLine": 21, - "startColumn": 23, - "endLine": 21, - "endColumn": 26, - "snippet": { - "text": "req" - } - } - }, - "logicalLocations": [ - { - "fullyQualifiedName": "server.^_4" - } - ] - } - }, - { - "location": { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/server.js" - }, - "region": { - "startLine": 26, - "startColumn": 28, - "endLine": 26, - "endColumn": 31, - "snippet": { - "text": "req" - } - } - }, - "logicalLocations": [ - { - "fullyQualifiedName": "server.^_4" - } - ] - } - }, - { - "location": { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///Users/user/ejs-frog-demo/server.js" - }, - "region": { - "startLine": 26, - "startColumn": 28, - "endLine": 26, - "endColumn": 37, - "snippet": { - "text": "req.query" - } - } - }, - "logicalLocations": [ - { - "fullyQualifiedName": "server.^_4" - } - ] - } - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - } - } - ] -} \ No newline at end of file diff --git a/tests/testdata/output/audit/audit_sarif.json b/tests/testdata/output/audit/audit_sarif.json index 56c0808a..51c46d1e 100644 --- a/tests/testdata/output/audit/audit_sarif.json +++ b/tests/testdata/output/audit/audit_sarif.json @@ -5,141 +5,117 @@ { "tool": { "driver": { - "informationUri": "https://jfrog.com/help/r/jfrog-security-documentation/jfrog-advanced-security", - "name": "JFrog Secrets scanner", + "informationUri": "https://docs.jfrog-applications.jfrog.io/jfrog-security-features/sca", + "name": "JFrog Xray Scanner", "rules": [ { - "id": "REQ.SECRET.GENERIC.TEXT", + "id": "CVE-2018-3721_lodash_4.17.0", "shortDescription": { - "text": "Scanner for REQ.SECRET.GENERIC.TEXT" - }, - "fullDescription": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" + "text": "[CVE-2018-3721] lodash 4.17.0" }, "help": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" + "text": "Improperly Controlled Modification of Object", + "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 6.9 | Not Covered | `lodash 4.17.0` | [4.17.5] |" }, "properties": { - "applicability": "not_applicable", - "conclusion": "positive" + "security-severity": "6.9" } }, { - "id": "REQ.SECRET.GENERIC.CODE", + "id": "CVE-2024-39249_async_3.2.4", "shortDescription": { - "text": "Scanner for REQ.SECRET.GENERIC.CODE" - }, - "fullDescription": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" + "text": "[CVE-2024-39249] async 3.2.4" }, "help": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" + "text": "Async vulnerable to ReDoS", + "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 0.0 | Applicable | `jake 10.8.7` | No fix available |" }, "properties": { - "applicability": "not_applicable", - "conclusion": "positive" + "security-severity": "0.0" } }, { - "id": "REQ.SECRET.KEYS", + "id": "CVE-2020-8203_lodash_4.17.0", "shortDescription": { - "text": "Scanner for REQ.SECRET.KEYS" - }, - "fullDescription": { - "text": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n", - "markdown": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n" + "text": "[CVE-2020-8203] lodash 4.17.0" }, "help": { - "text": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n", - "markdown": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n" + "text": "Code Injection", + "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 7.4 | Not Applicable | `lodash 4.17.0` | [4.17.19] |" }, "properties": { - "applicability": "applicable", - "conclusion": "negative", - "security-severity": "6.9" + "security-severity": "7.4" } }, { - "id": "REQ.CRED.PUBLIC-ONLY", + "id": "CVE-2020-8203_ejs_3.1.6", "shortDescription": { - "text": "Scanner for REQ.CRED.PUBLIC-ONLY" - }, - "fullDescription": { - "text": "", - "markdown": "" + "text": "[CVE-2020-8203] ejs 3.1.6" }, "help": { - "text": "", - "markdown": "" + "text": "Code Injection", + "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 7.4 | Not Applicable | `lodash 4.17.0` | [3.1.7] |" }, "properties": { - "applicability": "undetermined", - "conclusion": "private" + "security-severity": "7.4" } }, { - "id": "REQ.SECRET.GENERIC.URL-TEXT", + "id": "CVE-2018-16487_lodash_4.17.0", "shortDescription": { - "text": "Scanner for REQ.SECRET.GENERIC.URL-TEXT" + "text": "[CVE-2018-16487] lodash 4.17.0" }, - "fullDescription": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" + "help": { + "text": "Prototype Pollution", + "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 6.9 | Not Applicable | `lodash 4.17.0` | [4.17.11] |" + }, + "properties": { + "security-severity": "6.9" + } + }, + { + "id": "MIT_lodash_4.17.0", + "shortDescription": { + "text": "[MIT] in lodash 4.17.0 (license-watch)" }, "help": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" + "text": "Dependency lodash version 4.17.0 is using a license (MIT) that is not allowed.", + "markdown": "Dependency lodash version 4.17.0 is using a license (MIT) that is not allowed.\u003cbr/\u003eDirect dependencies:\u003cbr/\u003e`lodash 4.17.0`" }, "properties": { - "applicability": "not_applicable", - "conclusion": "positive" + "security-severity": "8.9" } } ], - "version": "1.0" + "version": "3.107.13" } }, "invocations": [ { - "arguments": [ - "analyzerManager/jas_scanner/jas_scanner", - "scan", - "/Secrets_1725867313/config.yaml" - ], "executionSuccessful": true, "workingDirectory": { - "uri": "/Users/user/ejs-frog-demo" + "uri": "/Users/user/project-with-issues" } } ], "results": [ { "properties": { - "metadata": "", - "tokenValidation": "" + "applicability": "Applicable", + "fixedVersion": "No fix available" }, - "ruleId": "REQ.SECRET.KEYS", + "ruleId": "CVE-2024-39249_async_3.2.4", + "ruleIndex": 1, + "level": "none", "message": { - "text": "Secret keys were found" + "text": "[CVE-2024-39249] jake 10.8.7", + "markdown": "[CVE-2024-39249] jake 10.8.7" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "fake-creds.txt" - }, - "region": { - "startLine": 2, - "startColumn": 1, - "endLine": 2, - "endColumn": 11, - "snippet": { - "text": "Sqc************" - } + "uri": "package.json" } } } @@ -147,27 +123,21 @@ }, { "properties": { - "metadata": "", - "tokenValidation": "" + "applicability": "Not Applicable", + "fixedVersion": "[4.17.19]" }, - "ruleId": "REQ.SECRET.KEYS", + "ruleId": "CVE-2020-8203_lodash_4.17.0", + "ruleIndex": 2, + "level": "error", "message": { - "text": "Secret keys were found" + "text": "[CVE-2020-8203] lodash 4.17.0", + "markdown": "[CVE-2020-8203] lodash 4.17.0" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "fake-creds.txt" - }, - "region": { - "startLine": 3, - "startColumn": 1, - "endLine": 3, - "endColumn": 11, - "snippet": { - "text": "gho************" - } + "uri": "package.json" } } } @@ -175,850 +145,131 @@ }, { "properties": { - "metadata": "", - "tokenValidation": "" + "applicability": "Not Applicable", + "fixedVersion": "[3.1.7]" }, - "ruleId": "REQ.SECRET.KEYS", + "ruleId": "CVE-2020-8203_ejs_3.1.6", + "ruleIndex": 3, + "level": "error", "message": { - "text": "Secret keys were found" + "text": "[CVE-2020-8203] lodash 4.17.0", + "markdown": "[CVE-2020-8203] lodash 4.17.0" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "server.js" - }, - "region": { - "startLine": 11, - "startColumn": 14, - "endLine": 11, - "endColumn": 24, - "snippet": { - "text": "Sqc************" - } + "uri": "package.json" } } } ] - } - ] - }, - { - "tool": { - "driver": { - "informationUri": "https://docs.jfrog-applications.jfrog.io/jfrog-security-features/infrastructure-as-code-iac", - "name": "JFrog Terraform scanner", - "rules": [], - "version": "1.8.14" - } - }, - "invocations": [ + }, { - "arguments": [ - "analyzerManager/iac_scanner/tf_scanner", - "scan", - "/IaC_1725867328/config.yaml" - ], - "executionSuccessful": true, - "workingDirectory": { - "uri": "/Users/user/ejs-frog-demo" - } - } - ], - "results": [] - }, - { - "tool": { - "driver": { - "informationUri": "https://docs.jfrog-applications.jfrog.io/jfrog-security-features/sast", - "name": "🐸 JFrog SAST", - "rules": [ - { - "id": "js-express-without-helmet", - "shortDescription": { - "text": "Express Not Using Helmet" - }, - "fullDescription": { - "text": "\n### Overview\nHelmet library should be used when using Express in order to properly configure\nHTTP header settings to mitigate a range of well-known vulnerabilities.\n\n### Remediation\n```javascript\nconst helmet = require(\"helmet\");\nconst app = express()\n\napp.use(helmet())\n```\n\n### References\n[Best practices for Express](https://expressjs.com/en/advanced/best-practice-security.html)\n", - "markdown": "\n### Overview\nHelmet library should be used when using Express in order to properly configure\nHTTP header settings to mitigate a range of well-known vulnerabilities.\n\n### Remediation\n```javascript\nconst helmet = require(\"helmet\");\nconst app = express()\n\napp.use(helmet())\n```\n\n### References\n[Best practices for Express](https://expressjs.com/en/advanced/best-practice-security.html)\n" - }, - "defaultConfiguration": { - "parameters": { - "properties": { - "CWE": "693" - } - } - }, - "help": { - "text": "\n### Overview\nHelmet library should be used when using Express in order to properly configure\nHTTP header settings to mitigate a range of well-known vulnerabilities.\n\n### Remediation\n```javascript\nconst helmet = require(\"helmet\");\nconst app = express()\n\napp.use(helmet())\n```\n\n### References\n[Best practices for Express](https://expressjs.com/en/advanced/best-practice-security.html)\n", - "markdown": "\n### Overview\nHelmet library should be used when using Express in order to properly configure\nHTTP header settings to mitigate a range of well-known vulnerabilities.\n\n### Remediation\n```javascript\nconst helmet = require(\"helmet\");\nconst app = express()\n\napp.use(helmet())\n```\n\n### References\n[Best practices for Express](https://expressjs.com/en/advanced/best-practice-security.html)\n" - }, - "properties": { - "security-severity": "3.9" - } - }, - { - "id": "js-insecure-random", - "shortDescription": { - "text": "Use of Insecure Random" - }, - "fullDescription": { - "text": "\n### Overview\nA use of insecure random vulnerability is a type of security flaw that is\ncaused by the use of inadequate or predictable random numbers in a program\nor system. Random numbers are used in many security-related applications,\nsuch as generating cryptographic keys and if the numbers are not truly\nrandom, an attacker may be able to predict or recreate them, potentially\ncompromising the security of the system.\n\n### Vulnerable example\n```javascript\nvar randomNum = Math.random();\n```\n`Math.random` is not secured, as it creates predictable random numbers.\n\n### Remediation\n```diff\nvar randomNum = crypto.randomInt(0, 100)\n```\n`crypto.randomInt` is secured, and creates much less predictable random\nnumbers.\n", - "markdown": "\n### Overview\nA use of insecure random vulnerability is a type of security flaw that is\ncaused by the use of inadequate or predictable random numbers in a program\nor system. Random numbers are used in many security-related applications,\nsuch as generating cryptographic keys and if the numbers are not truly\nrandom, an attacker may be able to predict or recreate them, potentially\ncompromising the security of the system.\n\n### Vulnerable example\n```javascript\nvar randomNum = Math.random();\n```\n`Math.random` is not secured, as it creates predictable random numbers.\n\n### Remediation\n```diff\nvar randomNum = crypto.randomInt(0, 100)\n```\n`crypto.randomInt` is secured, and creates much less predictable random\nnumbers.\n" - }, - "defaultConfiguration": { - "parameters": { - "properties": { - "CWE": "338" - } - } - }, - "help": { - "text": "\n### Overview\nA use of insecure random vulnerability is a type of security flaw that is\ncaused by the use of inadequate or predictable random numbers in a program\nor system. Random numbers are used in many security-related applications,\nsuch as generating cryptographic keys and if the numbers are not truly\nrandom, an attacker may be able to predict or recreate them, potentially\ncompromising the security of the system.\n\n### Vulnerable example\n```javascript\nvar randomNum = Math.random();\n```\n`Math.random` is not secured, as it creates predictable random numbers.\n\n### Remediation\n```diff\nvar randomNum = crypto.randomInt(0, 100)\n```\n`crypto.randomInt` is secured, and creates much less predictable random\nnumbers.\n", - "markdown": "\n### Overview\nA use of insecure random vulnerability is a type of security flaw that is\ncaused by the use of inadequate or predictable random numbers in a program\nor system. Random numbers are used in many security-related applications,\nsuch as generating cryptographic keys and if the numbers are not truly\nrandom, an attacker may be able to predict or recreate them, potentially\ncompromising the security of the system.\n\n### Vulnerable example\n```javascript\nvar randomNum = Math.random();\n```\n`Math.random` is not secured, as it creates predictable random numbers.\n\n### Remediation\n```diff\nvar randomNum = crypto.randomInt(0, 100)\n```\n`crypto.randomInt` is secured, and creates much less predictable random\nnumbers.\n" - }, - "properties": { - "security-severity": "3.9" - } - }, + "properties": { + "applicability": "Not Applicable", + "fixedVersion": "[4.17.11]" + }, + "ruleId": "CVE-2018-16487_lodash_4.17.0", + "ruleIndex": 4, + "level": "warning", + "message": { + "text": "[CVE-2018-16487] lodash 4.17.0", + "markdown": "[CVE-2018-16487] lodash 4.17.0" + }, + "locations": [ { - "id": "js-template-injection", - "shortDescription": { - "text": "Template Object Injection" - }, - "fullDescription": { - "text": "\n### Overview\nTemplate Object Injection (TOI) is a vulnerability that can occur in\nweb applications that use template engines to render dynamic content.\nTemplate engines are commonly used to generate HTML pages, emails, or\nother types of documents that include variable data. TOI happens when\nuntrusted user input is included as part of the template rendering\nprocess, and the template engine evaluates the input as a code\nexpression, leading to potential code injection or data tampering\nattacks. To prevent TOI vulnerabilities, it's important to sanitize and\nvalidate all user input that is used as part of the template rendering\nprocess.\n\n### Query operation\nIn this query we look for user inputs that flow directly to a\nrequest render.\n\n### Vulnerable example\n```javascript\nvar app = require('express')();\napp.set('view engine', 'hbs');\n\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n res.render('template', bodyParameter);\n});\n```\nIn this example, a user-provided data is injected directly into the\n`render` command, leading to potential code injection or data\ntampering attacks.\n\n### Remediation\n```diff\n+ const sanitizeHtml = require('sanitize-html');\nvar app = require('express')();\napp.set('view engine', 'hbs');\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n\n- res.render('template', bodyParameter);\n+ res.render('template', sanitizeHtml(bodyParameter));\n});\nUsing `sanitize-html`, the user-provided data is sanitized, before\nrendering to the response.\n```\n", - "markdown": "\n### Overview\nTemplate Object Injection (TOI) is a vulnerability that can occur in\nweb applications that use template engines to render dynamic content.\nTemplate engines are commonly used to generate HTML pages, emails, or\nother types of documents that include variable data. TOI happens when\nuntrusted user input is included as part of the template rendering\nprocess, and the template engine evaluates the input as a code\nexpression, leading to potential code injection or data tampering\nattacks. To prevent TOI vulnerabilities, it's important to sanitize and\nvalidate all user input that is used as part of the template rendering\nprocess.\n\n### Query operation\nIn this query we look for user inputs that flow directly to a\nrequest render.\n\n### Vulnerable example\n```javascript\nvar app = require('express')();\napp.set('view engine', 'hbs');\n\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n res.render('template', bodyParameter);\n});\n```\nIn this example, a user-provided data is injected directly into the\n`render` command, leading to potential code injection or data\ntampering attacks.\n\n### Remediation\n```diff\n+ const sanitizeHtml = require('sanitize-html');\nvar app = require('express')();\napp.set('view engine', 'hbs');\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n\n- res.render('template', bodyParameter);\n+ res.render('template', sanitizeHtml(bodyParameter));\n});\nUsing `sanitize-html`, the user-provided data is sanitized, before\nrendering to the response.\n```\n" - }, - "defaultConfiguration": { - "parameters": { - "properties": { - "CWE": "73" - } + "physicalLocation": { + "artifactLocation": { + "uri": "package.json" } - }, - "help": { - "text": "\n### Overview\nTemplate Object Injection (TOI) is a vulnerability that can occur in\nweb applications that use template engines to render dynamic content.\nTemplate engines are commonly used to generate HTML pages, emails, or\nother types of documents that include variable data. TOI happens when\nuntrusted user input is included as part of the template rendering\nprocess, and the template engine evaluates the input as a code\nexpression, leading to potential code injection or data tampering\nattacks. To prevent TOI vulnerabilities, it's important to sanitize and\nvalidate all user input that is used as part of the template rendering\nprocess.\n\n### Query operation\nIn this query we look for user inputs that flow directly to a\nrequest render.\n\n### Vulnerable example\n```javascript\nvar app = require('express')();\napp.set('view engine', 'hbs');\n\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n res.render('template', bodyParameter);\n});\n```\nIn this example, a user-provided data is injected directly into the\n`render` command, leading to potential code injection or data\ntampering attacks.\n\n### Remediation\n```diff\n+ const sanitizeHtml = require('sanitize-html');\nvar app = require('express')();\napp.set('view engine', 'hbs');\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n\n- res.render('template', bodyParameter);\n+ res.render('template', sanitizeHtml(bodyParameter));\n});\nUsing `sanitize-html`, the user-provided data is sanitized, before\nrendering to the response.\n```\n", - "markdown": "\n### Overview\nTemplate Object Injection (TOI) is a vulnerability that can occur in\nweb applications that use template engines to render dynamic content.\nTemplate engines are commonly used to generate HTML pages, emails, or\nother types of documents that include variable data. TOI happens when\nuntrusted user input is included as part of the template rendering\nprocess, and the template engine evaluates the input as a code\nexpression, leading to potential code injection or data tampering\nattacks. To prevent TOI vulnerabilities, it's important to sanitize and\nvalidate all user input that is used as part of the template rendering\nprocess.\n\n### Query operation\nIn this query we look for user inputs that flow directly to a\nrequest render.\n\n### Vulnerable example\n```javascript\nvar app = require('express')();\napp.set('view engine', 'hbs');\n\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n res.render('template', bodyParameter);\n});\n```\nIn this example, a user-provided data is injected directly into the\n`render` command, leading to potential code injection or data\ntampering attacks.\n\n### Remediation\n```diff\n+ const sanitizeHtml = require('sanitize-html');\nvar app = require('express')();\napp.set('view engine', 'hbs');\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n\n- res.render('template', bodyParameter);\n+ res.render('template', sanitizeHtml(bodyParameter));\n});\nUsing `sanitize-html`, the user-provided data is sanitized, before\nrendering to the response.\n```\n" - }, - "properties": { - "security-severity": "8.9" } } - ], - "version": "1.8.14" - } - }, - "invocations": [ - { - "arguments": [ - "analyzerManager/zd_scanner/scanner", - "scan", - "/Sast_1725867332/results.sarif", - "/Sast_1725867332/config.yaml" - ], - "executionSuccessful": true, - "workingDirectory": { - "uri": "/Users/user/ejs-frog-demo" - } - } - ], - "results": [ + ] + }, { - "ruleId": "js-insecure-random", - "level": "note", + "properties": { + "applicability": "Not Covered", + "fixedVersion": "[4.17.5]" + }, + "ruleId": "CVE-2018-3721_lodash_4.17.0", + "ruleIndex": 0, + "level": "warning", "message": { - "text": "Use of Insecure Random" + "text": "[CVE-2018-3721] lodash 4.17.0", + "markdown": "[CVE-2018-3721] lodash 4.17.0" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "public/js/bootstrap.js" - }, - "region": { - "startLine": 136, - "startColumn": 22, - "endLine": 136, - "endColumn": 35, - "snippet": { - "text": "Math.random()" - } - } - }, - "logicalLocations": [ - { - "fullyQualifiedName": "public.js.bootstrap.^_0.Util.getUID" + "uri": "package.json" } - ] + } } - ], - "fingerprints": { - "precise_sink_and_sink_function": "3cb8327f723c9d1b6664949748868899" - } + ] }, { - "ruleId": "js-insecure-random", - "level": "note", + "properties": { + "applicability": "Applicable", + "fixedVersion": "No fix available", + "policies": "npm-security", + "watch": "security-watch" + }, + "ruleId": "CVE-2024-39249_async_3.2.4", + "ruleIndex": 1, + "level": "none", "message": { - "text": "Use of Insecure Random" + "text": "[CVE-2024-39249] jake 10.8.7 (security-watch)", + "markdown": "[CVE-2024-39249] jake 10.8.7 (security-watch)" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "public/js/bootstrap.bundle.js" - }, - "region": { - "startLine": 135, - "startColumn": 22, - "endLine": 135, - "endColumn": 35, - "snippet": { - "text": "Math.random()" - } - } - }, - "logicalLocations": [ - { - "fullyQualifiedName": "public.js.bootstrapbundle.^_0.Util.getUID" + "uri": "package.json" } - ] + } } - ], - "fingerprints": { - "precise_sink_and_sink_function": "ec68d229b6bdd85b67dd2ddce27337bd" - } + ] }, { - "ruleId": "js-express-without-helmet", - "level": "note", + "properties": { + "applicability": "Not Covered", + "fixedVersion": "[4.17.5]", + "policies": "npm-security", + "watch": "security-watch" + }, + "ruleId": "CVE-2018-3721_lodash_4.17.0", + "ruleIndex": 0, + "level": "warning", "message": { - "text": "Express Not Using Helmet" + "text": "[CVE-2018-3721] lodash 4.17.0 (security-watch)", + "markdown": "[CVE-2018-3721] lodash 4.17.0 (security-watch)" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "server.js" - }, - "region": { - "startLine": 8, - "startColumn": 11, - "endLine": 8, - "endColumn": 20, - "snippet": { - "text": "express()" - } - } - }, - "logicalLocations": [ - { - "fullyQualifiedName": "server" + "uri": "package.json" } - ] + } } - ], - "fingerprints": { - "precise_sink_and_sink_function": "f8caf6a43a2c1eb41369843ca3c7d94c" - } + ] }, { - "ruleId": "js-template-injection", + "properties": { + "applicability": "Not Covered", + "fixedVersion": "No fix available", + "policies": "npm-license", + "watch": "license-watch" + }, + "ruleId": "MIT_lodash_4.17.0", + "ruleIndex": 5, "level": "error", "message": { - "text": "Template Object Injection" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "server.js" - }, - "region": { - "startLine": 26, - "startColumn": 28, - "endLine": 26, - "endColumn": 37, - "snippet": { - "text": "req.query" - } - } - }, - "logicalLocations": [ - { - "fullyQualifiedName": "server.^_4" - } - ] - } - ], - "fingerprints": { - "precise_sink_and_sink_function": "a549106dc43cdc0d36b0f81d0465a5d2" - }, - "codeFlows": [ - { - "threadFlows": [ - { - "locations": [ - { - "location": { - "physicalLocation": { - "artifactLocation": { - "uri": "server.js" - }, - "region": { - "startLine": 21, - "startColumn": 23, - "endLine": 21, - "endColumn": 26, - "snippet": { - "text": "req" - } - } - }, - "logicalLocations": [ - { - "fullyQualifiedName": "server.^_4" - } - ] - } - }, - { - "location": { - "physicalLocation": { - "artifactLocation": { - "uri": "server.js" - }, - "region": { - "startLine": 26, - "startColumn": 28, - "endLine": 26, - "endColumn": 31, - "snippet": { - "text": "req" - } - } - }, - "logicalLocations": [ - { - "fullyQualifiedName": "server.^_4" - } - ] - } - }, - { - "location": { - "physicalLocation": { - "artifactLocation": { - "uri": "server.js" - }, - "region": { - "startLine": 26, - "startColumn": 28, - "endLine": 26, - "endColumn": 37, - "snippet": { - "text": "req.query" - } - } - }, - "logicalLocations": [ - { - "fullyQualifiedName": "server.^_4" - } - ] - } - } - ] - } - ] - } - ] - } - ] - }, - { - "tool": { - "driver": { - "informationUri": "https://docs.jfrog-applications.jfrog.io/jfrog-security-features/sca", - "name": "JFrog Xray Scanner", - "rules": [ - { - "id": "CVE-2018-3721_lodash_4.17.0", - "shortDescription": { - "text": "[CVE-2018-3721] lodash 4.17.0" - }, - "help": { - "text": "lodash node module before 4.17.5 suffers from a Modification of Assumed-Immutable Data (MAID) vulnerability via defaultsDeep, merge, and mergeWith functions, which allows a malicious user to modify the prototype of \"Object\" via __proto__, causing the addition or modification of an existing property that will exist on all objects.", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 6.5 | Not Covered | `lodash 4.17.0` | [4.17.5] |" - }, - "properties": { - "security-severity": "6.5" - } - }, - { - "id": "CVE-2021-23337_lodash_4.17.0", - "shortDescription": { - "text": "[CVE-2021-23337] lodash 4.17.0" - }, - "help": { - "text": "Lodash versions prior to 4.17.21 are vulnerable to Command Injection via the template function.", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 7.2 | Not Applicable | `lodash 4.17.0` | [4.17.21] |" - }, - "properties": { - "security-severity": "7.2" - } - }, - { - "id": "CVE-2019-1010266_lodash_4.17.0", - "shortDescription": { - "text": "[CVE-2019-1010266] lodash 4.17.0" - }, - "help": { - "text": "lodash prior to 4.17.11 is affected by: CWE-400: Uncontrolled Resource Consumption. The impact is: Denial of service. The component is: Date handler. The attack vector is: Attacker provides very long strings, which the library attempts to match using a regular expression. The fixed version is: 4.17.11.", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 6.5 | Not Covered | `lodash 4.17.0` | [4.17.11] |" - }, - "properties": { - "security-severity": "6.5" - } - }, - { - "id": "CVE-2024-33883_ejs_3.1.6", - "shortDescription": { - "text": "[CVE-2024-33883] ejs 3.1.6" - }, - "help": { - "text": "The ejs (aka Embedded JavaScript templates) package before 3.1.10 for Node.js lacks certain pollution protection.", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 4.0 | Not Applicable | `ejs 3.1.6` | [3.1.10] |" - }, - "properties": { - "security-severity": "4.0" - } - }, - { - "id": "CVE-2023-29827_ejs_3.1.6", - "shortDescription": { - "text": "[CVE-2023-29827] ejs 3.1.6" - }, - "help": { - "text": "ejs v3.1.9 is vulnerable to server-side template injection. If the ejs file is controllable, template injection can be implemented through the configuration settings of the closeDelimiter parameter. NOTE: this is disputed by the vendor because the render function is not intended to be used with untrusted input.", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 9.8 | Applicable | `ejs 3.1.6` | No fix available |" - }, - "properties": { - "security-severity": "9.8" - } - }, - { - "id": "CVE-2024-39249_async_3.2.4", - "shortDescription": { - "text": "[CVE-2024-39249] async 3.2.4" - }, - "help": { - "text": "Async <= 2.6.4 and <= 3.2.5 are vulnerable to ReDoS (Regular Expression Denial of Service) while parsing function in autoinject function. NOTE: this is disputed by the supplier because there is no realistic threat model: regular expressions are not used with untrusted input.", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 0.0 | Not Covered | `ejs 3.1.6` | No fix available |" - }, - "properties": { - "security-severity": "0.0" - } - }, - { - "id": "CVE-2020-28500_lodash_4.17.0", - "shortDescription": { - "text": "[CVE-2020-28500] lodash 4.17.0" - }, - "help": { - "text": "Lodash versions prior to 4.17.21 are vulnerable to Regular Expression Denial of Service (ReDoS) via the toNumber, trim and trimEnd functions.", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 5.3 | Not Applicable | `lodash 4.17.0` | [4.17.21] |" - }, - "properties": { - "security-severity": "5.3" - } - }, - { - "id": "CVE-2020-8203_lodash_4.17.0", - "shortDescription": { - "text": "[CVE-2020-8203] lodash 4.17.0" - }, - "help": { - "text": "Prototype pollution attack when using _.zipObjectDeep in lodash before 4.17.20.", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 7.4 | Not Applicable | `lodash 4.17.0` | [4.17.19] |" - }, - "properties": { - "security-severity": "7.4" - } - }, - { - "id": "CVE-2019-10744_lodash_4.17.0", - "shortDescription": { - "text": "[CVE-2019-10744] lodash 4.17.0" - }, - "help": { - "text": "Versions of lodash lower than 4.17.12 are vulnerable to Prototype Pollution. The function defaultsDeep could be tricked into adding or modifying properties of Object.prototype using a constructor payload.", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 9.1 | Not Applicable | `lodash 4.17.0` | [4.17.12] |" - }, - "properties": { - "security-severity": "9.1" - } - }, - { - "id": "CVE-2022-29078_ejs_3.1.6", - "shortDescription": { - "text": "[CVE-2022-29078] ejs 3.1.6" - }, - "help": { - "text": "The ejs (aka Embedded JavaScript templates) package 3.1.6 for Node.js allows server-side template injection in settings[view options][outputFunctionName]. This is parsed as an internal option, and overwrites the outputFunctionName option with an arbitrary OS command (which is executed upon template compilation).", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 9.8 | Not Applicable | `ejs 3.1.6` | [3.1.7] |" - }, - "properties": { - "security-severity": "9.8" - } - }, - { - "id": "CVE-2024-29041_express_4.18.2", - "shortDescription": { - "text": "[CVE-2024-29041] express 4.18.2" - }, - "help": { - "text": "Express.js minimalist web framework for node. Versions of Express.js prior to 4.19.0 and all pre-release alpha and beta versions of 5.0 are affected by an open redirect vulnerability using malformed URLs. When a user of Express performs a redirect using a user-provided URL Express performs an encode [using `encodeurl`](https://github.com/pillarjs/encodeurl) on the contents before passing it to the `location` header. This can cause malformed URLs to be evaluated in unexpected ways by common redirect allow list implementations in Express applications, leading to an Open Redirect via bypass of a properly implemented allow list. The main method impacted is `res.location()` but this is also called from within `res.redirect()`. The vulnerability is fixed in 4.19.2 and 5.0.0-beta.3.", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 6.1 | Not Covered | `express 4.18.2` | [4.19.2], [5.0.0-beta.3] |" - }, - "properties": { - "security-severity": "6.1" - } - }, - { - "id": "CVE-2018-16487_lodash_4.17.0", - "shortDescription": { - "text": "[CVE-2018-16487] lodash 4.17.0" - }, - "help": { - "text": "A prototype pollution vulnerability was found in lodash <4.17.11 where the functions merge, mergeWith, and defaultsDeep can be tricked into adding or modifying properties of Object.prototype.", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 5.6 | Not Applicable | `lodash 4.17.0` | [4.17.11] |" - }, - "properties": { - "security-severity": "5.6" - } - } - ], - "version": "3.104.8" - } - }, - "invocations": [ - { - "executionSuccessful": true, - "workingDirectory": { - "uri": "/Users/user/ejs-frog-demo" - } - } - ], - "results": [ - { - "properties": { - "applicability": "Not Covered", - "fixedVersion": "[4.19.2], [5.0.0-beta.3]" - }, - "ruleId": "CVE-2024-29041_express_4.18.2", - "ruleIndex": 10, - "level": "warning", - "message": { - "text": "[CVE-2024-29041] express 4.18.2" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "package.json" - } - } - } - ] - }, - { - "properties": { - "applicability": "Not Covered", - "fixedVersion": "No fix available" - }, - "ruleId": "CVE-2024-39249_async_3.2.4", - "ruleIndex": 5, - "level": "none", - "message": { - "text": "[CVE-2024-39249] ejs 3.1.6" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "package.json" - } - } - } - ] - }, - { - "properties": { - "applicability": "Not Applicable", - "fixedVersion": "[4.17.21]" - }, - "ruleId": "CVE-2020-28500_lodash_4.17.0", - "ruleIndex": 6, - "level": "warning", - "message": { - "text": "[CVE-2020-28500] lodash 4.17.0" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "package.json" - } - } - } - ] - }, - { - "properties": { - "applicability": "Not Covered", - "fixedVersion": "[4.17.5]" - }, - "ruleId": "CVE-2018-3721_lodash_4.17.0", - "ruleIndex": 0, - "level": "warning", - "message": { - "text": "[CVE-2018-3721] lodash 4.17.0" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "package.json" - } - } - } - ] - }, - { - "properties": { - "applicability": "Not Applicable", - "fixedVersion": "[4.17.21]" - }, - "ruleId": "CVE-2021-23337_lodash_4.17.0", - "ruleIndex": 1, - "level": "error", - "message": { - "text": "[CVE-2021-23337] lodash 4.17.0" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "package.json" - } - } - } - ] - }, - { - "properties": { - "applicability": "Not Applicable", - "fixedVersion": "[4.17.11]" - }, - "ruleId": "CVE-2018-16487_lodash_4.17.0", - "ruleIndex": 11, - "level": "warning", - "message": { - "text": "[CVE-2018-16487] lodash 4.17.0" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "package.json" - } - } - } - ] - }, - { - "properties": { - "applicability": "Not Applicable", - "fixedVersion": "[4.17.19]" - }, - "ruleId": "CVE-2020-8203_lodash_4.17.0", - "ruleIndex": 7, - "level": "error", - "message": { - "text": "[CVE-2020-8203] lodash 4.17.0" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "package.json" - } - } - } - ] - }, - { - "properties": { - "applicability": "Not Applicable", - "fixedVersion": "[4.17.12]" - }, - "ruleId": "CVE-2019-10744_lodash_4.17.0", - "ruleIndex": 8, - "level": "error", - "message": { - "text": "[CVE-2019-10744] lodash 4.17.0" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "package.json" - } - } - } - ] - }, - { - "properties": { - "applicability": "Not Covered", - "fixedVersion": "[4.17.11]" - }, - "ruleId": "CVE-2019-1010266_lodash_4.17.0", - "ruleIndex": 2, - "level": "warning", - "message": { - "text": "[CVE-2019-1010266] lodash 4.17.0" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "package.json" - } - } - } - ] - }, - { - "properties": { - "applicability": "Not Applicable", - "fixedVersion": "[3.1.7]" - }, - "ruleId": "CVE-2022-29078_ejs_3.1.6", - "ruleIndex": 9, - "level": "error", - "message": { - "text": "[CVE-2022-29078] ejs 3.1.6" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "package.json" - } - } - } - ] - }, - { - "properties": { - "applicability": "Not Applicable", - "fixedVersion": "[3.1.10]" - }, - "ruleId": "CVE-2024-33883_ejs_3.1.6", - "ruleIndex": 3, - "level": "warning", - "message": { - "text": "[CVE-2024-33883] ejs 3.1.6" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "package.json" - } - } - } - ] - }, - { - "properties": { - "applicability": "Applicable", - "fixedVersion": "No fix available" - }, - "ruleId": "CVE-2023-29827_ejs_3.1.6", - "ruleIndex": 4, - "level": "error", - "message": { - "text": "[CVE-2023-29827] ejs 3.1.6" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "package.json" - } - } - } - ] - }, - { - "properties": { - "applicability": "Not Covered", - "fixedVersion": "[4.19.2], [5.0.0-beta.3]", - "watch": "Security_watch_1" - }, - "ruleId": "CVE-2024-29041_express_4.18.2", - "ruleIndex": 10, - "level": "warning", - "message": { - "text": "[CVE-2024-29041] express 4.18.2" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "package.json" - } - } - } - ] - }, - { - "properties": { - "applicability": "Not Applicable", - "fixedVersion": "[4.17.11]", - "watch": "Security_watch_1" - }, - "ruleId": "CVE-2018-16487_lodash_4.17.0", - "ruleIndex": 11, - "level": "warning", - "message": { - "text": "[CVE-2018-16487] lodash 4.17.0" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "package.json" - } - } - } - ] - }, - { - "properties": { - "applicability": "Not Covered", - "fixedVersion": "[4.17.11]", - "watch": "Security_watch_1" - }, - "ruleId": "CVE-2019-1010266_lodash_4.17.0", - "ruleIndex": 2, - "level": "warning", - "message": { - "text": "[CVE-2019-1010266] lodash 4.17.0" + "text": "[MIT] in lodash 4.17.0 (license-watch)", + "markdown": "[MIT] in lodash 4.17.0 (license-watch)" }, "locations": [ { @@ -1029,46 +280,66 @@ } } ] - }, - { - "properties": { - "applicability": "Not Applicable", - "fixedVersion": "[3.1.10]", - "watch": "Security_watch_1" - }, - "ruleId": "CVE-2024-33883_ejs_3.1.6", - "ruleIndex": 3, - "level": "warning", - "message": { - "text": "[CVE-2024-33883] ejs 3.1.6" - }, - "locations": [ + } + ] + }, + { + "tool": { + "driver": { + "name": "JFrog Secrets scanner", + "rules": [ { - "physicalLocation": { - "artifactLocation": { - "uri": "package.json" - } + "id": "REQ.SECRET.KEYS", + "shortDescription": { + "text": "Scanner for REQ.SECRET.KEYS", + "markdown": "Scanner for REQ.SECRET.KEYS" + }, + "fullDescription": { + "text": "The Scanner checks for REQ.SECRET.KEYS", + "markdown": "The Scanner checks for REQ.SECRET.KEYS" + }, + "help": { + "text": "The Scanner checks for REQ.SECRET.KEYS", + "markdown": "The Scanner checks for REQ.SECRET.KEYS" } } ] - }, + } + }, + "invocations": [ + { + "executionSuccessful": null, + "workingDirectory": { + "uri": "/Users/user/project-with-issues" + } + } + ], + "results": [ { "properties": { - "applicability": "Applicable", - "fixedVersion": "No fix available", - "watch": "Security_watch_1" + "metadata": "active token", + "tokenValidation": "Active" }, - "ruleId": "CVE-2023-29827_ejs_3.1.6", - "ruleIndex": 4, - "level": "error", + "ruleId": "REQ.SECRET.KEYS", + "level": "info", "message": { - "text": "[CVE-2023-29827] ejs 3.1.6" + "text": "Secret REQ.SECRET.KEYS were found", + "markdown": "Secret REQ.SECRET.KEYS were found" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "package.json" + "uri": "fake-creds.txt" + }, + "region": { + "startLine": 2, + "startColumn": 1, + "endLine": 2, + "endColumn": 11, + "snippet": { + "text": "Sqc************" + } } } } @@ -1076,21 +347,29 @@ }, { "properties": { - "applicability": "Not Applicable", - "fixedVersion": "[4.17.12]", - "watch": "Security_watch_1" + "metadata": "", + "tokenValidation": "Not a token" }, - "ruleId": "CVE-2019-10744_lodash_4.17.0", - "ruleIndex": 8, - "level": "error", + "ruleId": "REQ.SECRET.KEYS", + "level": "info", "message": { - "text": "[CVE-2019-10744] lodash 4.17.0" + "text": "Secret REQ.SECRET.KEYS were found", + "markdown": "Secret REQ.SECRET.KEYS were found" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "package.json" + "uri": "dir/server.js" + }, + "region": { + "startLine": 3, + "startColumn": 1, + "endLine": 3, + "endColumn": 11, + "snippet": { + "text": "gho************" + } } } } @@ -1098,21 +377,35 @@ }, { "properties": { - "applicability": "Not Applicable", - "fixedVersion": "[4.17.21]", - "watch": "Security_watch_1" + "issueId": "sec-violation-1", + "metadata": "active token", + "policies": [ + "policy" + ], + "tokenValidation": "Active", + "watch": "watch" }, - "ruleId": "CVE-2020-28500_lodash_4.17.0", - "ruleIndex": 6, - "level": "warning", + "ruleId": "REQ.SECRET.KEYS", + "ruleIndex": 0, + "level": "info", "message": { - "text": "Security violation [CVE-2020-28500] lodash 4.17.0" + "text": "Secret REQ.SECRET.KEYS were found", + "markdown": "Security violation Secret REQ.SECRET.KEYS were found" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "package.json" + "uri": "fake-creds.txt" + }, + "region": { + "startLine": 2, + "startColumn": 1, + "endLine": 2, + "endColumn": 11, + "snippet": { + "text": "Sqc************" + } } } } @@ -1120,65 +413,194 @@ }, { "properties": { - "applicability": "Not Covered", - "fixedVersion": "[4.17.5]", - "watch": "Security_watch_1" + "issueId": "sec-violation-2", + "metadata": "", + "policies": [ + "policy" + ], + "tokenValidation": "Not a token", + "watch": "watch" }, - "ruleId": "CVE-2018-3721_lodash_4.17.0", + "ruleId": "REQ.SECRET.KEYS", "ruleIndex": 0, - "level": "warning", + "level": "info", "message": { - "text": "[CVE-2018-3721] lodash 4.17.0" + "text": "Secret REQ.SECRET.KEYS were found", + "markdown": "Security violation Secret REQ.SECRET.KEYS were found" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "package.json" + "uri": "dir/server.js" + }, + "region": { + "startLine": 3, + "startColumn": 1, + "endLine": 3, + "endColumn": 11, + "snippet": { + "text": "gho************" + } } } } ] - }, + } + ] + }, + { + "tool": { + "driver": { + "name": "JFrog Terraform scanner", + "rules": [ + { + "id": "aws_cloudfront_tls_only", + "shortDescription": { + "text": "Scanner for aws_cloudfront_tls_only", + "markdown": "Scanner for aws_cloudfront_tls_only" + }, + "fullDescription": { + "text": "The Scanner checks for aws_cloudfront_tls_only", + "markdown": "The Scanner checks for aws_cloudfront_tls_only" + }, + "help": { + "text": "The Scanner checks for aws_cloudfront_tls_only", + "markdown": "The Scanner checks for aws_cloudfront_tls_only" + } + } + ] + } + }, + "invocations": [ { - "properties": { - "applicability": "Not Applicable", - "fixedVersion": "[4.17.21]", - "watch": "Security_watch_1" - }, - "ruleId": "CVE-2021-23337_lodash_4.17.0", - "ruleIndex": 1, + "executionSuccessful": null, + "workingDirectory": { + "uri": "/Users/user/project-with-issues" + } + } + ], + "results": [ + { + "ruleId": "aws_cloudfront_tls_only", "level": "error", "message": { - "text": "[CVE-2021-23337] lodash 4.17.0" + "text": "Vulnerability aws_cloudfront_tls_only were found", + "markdown": "Vulnerability aws_cloudfront_tls_only were found" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "package.json" + "uri": "req_sw_terraform_aws_cloudfront_tls_only.tf" + }, + "region": { + "startLine": 2, + "startColumn": 1, + "endLine": 21, + "endColumn": 1, + "snippet": { + "text": "viewer_protocol_policy..." + } } } } ] - }, + } + ] + }, + { + "tool": { + "driver": { + "name": "🐸 JFrog SAST", + "rules": [ + { + "id": "aws_cloudfront_tls_only", + "shortDescription": { + "text": "Scanner for aws_cloudfront_tls_only", + "markdown": "Scanner for aws_cloudfront_tls_only" + }, + "fullDescription": { + "text": "The Scanner checks for aws_cloudfront_tls_only", + "markdown": "The Scanner checks for aws_cloudfront_tls_only" + }, + "help": { + "text": "The Scanner checks for aws_cloudfront_tls_only", + "markdown": "The Scanner checks for aws_cloudfront_tls_only" + } + }, + { + "id": "js-template-injection", + "shortDescription": { + "text": "[Security Violation] Scanner for js-template-injection", + "markdown": "Scanner for js-template-injection" + }, + "fullDescription": { + "text": "The Scanner checks for js-template-injection", + "markdown": "The Scanner checks for js-template-injection" + }, + "help": { + "text": "The Scanner checks for js-template-injection", + "markdown": "The Scanner checks for js-template-injection" + } + }, + { + "id": "js-insecure-random", + "shortDescription": { + "text": "[Security Violation] Scanner for js-insecure-random", + "markdown": "Scanner for js-insecure-random" + }, + "fullDescription": { + "text": "The Scanner checks for js-insecure-random", + "markdown": "The Scanner checks for js-insecure-random" + }, + "help": { + "text": "The Scanner checks for js-insecure-random", + "markdown": "The Scanner checks for js-insecure-random" + } + } + ] + } + }, + "invocations": [ + { + "executionSuccessful": null, + "workingDirectory": { + "uri": "/Users/user/project-with-issues" + } + } + ], + "results": [ { "properties": { - "applicability": "Not Applicable", - "fixedVersion": "[4.17.19]", - "watch": "Security_watch_1" + "issueId": "sast-violation-1", + "policies": [ + "policy", + "policy2" + ], + "watch": "watch" }, - "ruleId": "CVE-2020-8203_lodash_4.17.0", - "ruleIndex": 7, - "level": "error", + "ruleId": "js-insecure-random", + "ruleIndex": 2, + "level": "note", "message": { - "text": "[CVE-2020-8203] lodash 4.17.0" + "text": "Vulnerability js-insecure-random were found", + "markdown": "Security violation Vulnerability js-insecure-random were found" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "package.json" + "uri": "public/js/bootstrap.bundle.js" + }, + "region": { + "startLine": 136, + "startColumn": 22, + "endLine": 136, + "endColumn": 35, + "snippet": { + "text": "Math.random()" + } } } } @@ -1186,24 +608,83 @@ }, { "properties": { - "applicability": "Not Applicable", - "fixedVersion": "[3.1.7]", - "watch": "Security_watch_1" + "issueId": "sast-violation-2", + "policies": [ + "policy", + "policy2" + ], + "watch": "watch" }, - "ruleId": "CVE-2022-29078_ejs_3.1.6", - "ruleIndex": 9, + "ruleId": "js-template-injection", + "ruleIndex": 1, "level": "error", "message": { - "text": "[CVE-2022-29078] ejs 3.1.6" + "text": "Vulnerability js-template-injection were found", + "markdown": "Security violation Vulnerability js-template-injection were found" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "package.json" + "uri": "server.js" + }, + "region": { + "startLine": 26, + "startColumn": 28, + "endLine": 26, + "endColumn": 37, + "snippet": { + "text": "req.query" + } } } } + ], + "codeFlows": [ + { + "threadFlows": [ + { + "locations": [ + { + "location": { + "physicalLocation": { + "artifactLocation": { + "uri": "server.js" + }, + "region": { + "startLine": 27, + "startColumn": 28, + "endLine": 26, + "endColumn": 31, + "snippet": { + "text": "req" + } + } + } + } + }, + { + "location": { + "physicalLocation": { + "artifactLocation": { + "uri": "server.js" + }, + "region": { + "startLine": 26, + "startColumn": 28, + "endLine": 26, + "endColumn": 37, + "snippet": { + "text": "req.query" + } + } + } + } + } + ] + } + ] + } ] } ] diff --git a/tests/testdata/output/audit/audit_simple_json.json b/tests/testdata/output/audit/audit_simple_json.json index 65961c9f..f1c148df 100644 --- a/tests/testdata/output/audit/audit_simple_json.json +++ b/tests/testdata/output/audit/audit_simple_json.json @@ -1,51 +1,37 @@ { - "multiScanId": "7d5e4733-3f93-11ef-8147-e610d09d7daa", "vulnerabilities": [ { - "severity": "Critical", - "impactedPackageName": "ejs", - "impactedPackageVersion": "3.1.6", + "severity": "High", + "impactedPackageName": "lodash", + "impactedPackageVersion": "4.17.0", "impactedPackageType": "npm", "components": [ { - "name": "ejs", - "version": "3.1.6", + "name": "lodash", + "version": "4.17.0", "location": { - "file": "/Users/user/ejs-frog-demo/package.json" + "file": "/Users/user/project-with-issues/package.json" } } ], - "summary": "ejs v3.1.9 is vulnerable to server-side template injection. If the ejs file is controllable, template injection can be implemented through the configuration settings of the closeDelimiter parameter. NOTE: this is disputed by the vendor because the render function is not intended to be used with untrusted input.", - "applicable": "Applicable", - "fixedVersions": null, + "summary": "Code Injection", + "applicable": "Not Applicable", + "fixedVersions": [ + "[4.17.19]" + ], "cves": [ { - "id": "CVE-2023-29827", - "cvssV2": "", - "cvssV3": "9.8", + "id": "CVE-2020-8203", + "cvssV2": "5.8", + "cvssV3": "7.4", "applicability": { - "status": "Applicable", - "scannerDescription": "The scanner checks whether any of the following conditions are met:\n\n1. The `ejs.renderFile` function is called with an unknown third argument.\n\n2. The `ejs.compile` function is called with an unknown second argument.\n\n3. The `express.set` function is called with any of the following arguments:\n\n* `express.set(\"view engine\", \"ejs\")`\n* `express.set(\"view engine\", {USER_INPUT})`\n* `express.set({USER_INPUT}, \"ejs\")`\n* `express.set({USER_INPUT}, {USER_INPUT})`", - "evidence": [ - { - "file": "server.js", - "startLine": 14, - "startColumn": 1, - "endLine": 14, - "endColumn": 30, - "snippet": "app.set('view engine', 'ejs')", - "reason": "The vulnerable functionality is triggered since express.set is called with 'view engine' as the first argument and 'ejs' as the second argument or both arguments with external input" - } - ] + "status": "Not Applicable", + "scannerDescription": "The Scanner checks for CVE-2020-8203" } } ], - "issueId": "XRAY-520200", - "references": [ - "https://nvd.nist.gov/vuln/detail/CVE-2023-29827", - "https://github.com/mde/ejs/issues/720", - "https://github.com/mde/ejs/blob/main/SECURITY.md#out-of-scope-vulnerabilities" - ], + "issueId": "XRAY-114089", + "references": null, "impactPaths": [ [ { @@ -53,76 +39,47 @@ "version": "1.0.0" }, { - "name": "ejs", - "version": "3.1.6" + "name": "lodash", + "version": "4.17.0" } ] ], "jfrogResearchInformation": { - "severity": "Low", - "summary": "Insufficient input validation can lead to template injection in ejs when attackers can control both the rendered template and rendering options.", - "details": "[Embedded JavaScript templates](https://github.com/mde/ejs), also known as EJS, is one of the most popular Node.js templating engines, which is compiled with the Express JS view system.\n\nWhen rendering views using EJS, it is possible to bypass ejs' template injection restrictions, by abusing the `closeDelimiter` rendering option, in the case when -\n1. The template itself can be partially controlled by the attacker\n2. The template rendering options can be fully controlled by the attacker\n\nThe vulnerability was **rightfully disputed** due to the fact that a vulnerable configuration is extremely unlikely to exist in any real-world setup. As such, the maintainers will not provide a fix for this (non-)issue.\n\nExample of a vulnerable application -\n```js\nconst express = require('express')\nconst app = express()\nconst port = 3000\n\napp.set('view engine', 'ejs');\n\napp.get('/page', (req,res) =\u003e {\n res.render('page', req.query); // OPTS (2nd parameter) IS ATTACKER-CONTROLLED\n})\n\napp.listen(port, () =\u003e {\n console.log(\"Example app listening on port ${port}\")\n})\n```\n\nContents of `page.ejs` (very unlikely to be attacker controlled) -\n```js\n%%1\");process.mainModule.require('child_process').execSync('calc');//\n```\n\nIn this case, sending `closeDelimiter` with the same malicious code that already exists at `page.ejs` will trigger the injection -\n`http://127.0.0.1:3000/page?settings[view%20options][closeDelimiter]=1\")%3bprocess.mainModule.require('child_process').execSync('calc')%3b//`", - "severityReasons": [ - { - "name": "The reported CVSS was either wrongly calculated, downgraded by other vendors, or does not reflect the vulnerability's impact", - "description": "The CVSS does not take into account the rarity of a vulnerable configuration to exist", - "isPositive": true - }, - { - "name": "The prerequisites for exploiting the issue are extremely unlikely", - "description": "The vulnerability can be exploited only under the following conditions -\n1. The template itself can be partially controlled by the attacker\n2. The template rendering options can be fully controlled by the attacker\nThis vulnerable configuration is extremely unlikely to exist in any real-world setup.", - "isPositive": true - }, - { - "name": "The issue has been disputed by the vendor", - "isPositive": true - }, - { - "name": "The issue has an exploit published", - "description": "Published exploit demonstrates template injection" - } - ] + "severity": "Low" } }, { - "severity": "Medium", - "impactedPackageName": "lodash", - "impactedPackageVersion": "4.17.0", + "severity": "High", + "impactedPackageName": "ejs", + "impactedPackageVersion": "3.1.6", "impactedPackageType": "npm", "components": [ { "name": "lodash", "version": "4.17.0", "location": { - "file": "/Users/user/ejs-frog-demo/package.json" + "file": "/Users/user/project-with-issues/package.json" } } ], - "summary": "lodash prior to 4.17.11 is affected by: CWE-400: Uncontrolled Resource Consumption. The impact is: Denial of service. The component is: Date handler. The attack vector is: Attacker provides very long strings, which the library attempts to match using a regular expression. The fixed version is: 4.17.11.", - "applicable": "Not Covered", + "summary": "Code Injection", + "applicable": "Not Applicable", "fixedVersions": [ - "[4.17.11]" + "[3.1.7]" ], "cves": [ { - "id": "CVE-2019-1010266", - "cvssV2": "4.0", - "cvssV3": "6.5", + "id": "CVE-2020-8203", + "cvssV2": "5.8", + "cvssV3": "7.4", "applicability": { - "status": "Not Covered" + "status": "Not Applicable", + "scannerDescription": "The Scanner checks for CVE-2020-8203" } } ], - "issueId": "XRAY-85049", - "references": [ - "https://nvd.nist.gov/vuln/detail/CVE-2019-1010266", - "https://github.com/lodash/lodash/wiki/Changelog", - "https://snyk.io/vuln/SNYK-JS-LODASH-73639", - "https://security.netapp.com/advisory/ntap-20190919-0004", - "https://security.netapp.com/advisory/ntap-20190919-0004/", - "https://github.com/lodash/lodash/issues/3359", - "https://github.com/lodash/lodash/commit/5c08f18d365b64063bfbfa686cbb97cdd6267347" - ], + "issueId": "XRAY-114089", + "references": null, "impactPaths": [ [ { @@ -132,10 +89,16 @@ { "name": "lodash", "version": "4.17.0" + }, + { + "name": "ejs", + "version": "3.1.6" } ] ], - "jfrogResearchInformation": null + "jfrogResearchInformation": { + "severity": "Low" + } }, { "severity": "Medium", @@ -147,35 +110,39 @@ "name": "lodash", "version": "4.17.0", "location": { - "file": "/Users/user/ejs-frog-demo/package.json" + "file": "/Users/user/project-with-issues/package.json" } } ], - "summary": "lodash node module before 4.17.5 suffers from a Modification of Assumed-Immutable Data (MAID) vulnerability via defaultsDeep, merge, and mergeWith functions, which allows a malicious user to modify the prototype of \"Object\" via __proto__, causing the addition or modification of an existing property that will exist on all objects.", - "applicable": "Not Covered", + "summary": "Prototype Pollution", + "applicable": "Not Applicable", "fixedVersions": [ - "[4.17.5]" + "[4.17.11]" ], "cves": [ { - "id": "CVE-2018-3721", - "cvssV2": "4.0", - "cvssV3": "6.5", + "id": "CVE-2018-16487", + "cvssV2": "", + "cvssV3": "", "applicability": { - "status": "Not Covered" + "status": "Not Applicable", + "scannerDescription": "The Scanner checks for CVE-2018-16487", + "evidence": [ + { + "file": "file-C", + "startLine": 1, + "startColumn": 2, + "endLine": 3, + "endColumn": 4, + "snippet": "snippet3", + "reason": "ca msg" + } + ] } } ], - "issueId": "XRAY-72918", - "references": [ - "https://www.npmjs.com/advisories/577", - "https://hackerone.com/reports/310443", - "https://github.com/advisories/GHSA-fvqr-27wr-82fm", - "https://nvd.nist.gov/vuln/detail/CVE-2018-3721", - "https://security.netapp.com/advisory/ntap-20190919-0004", - "https://security.netapp.com/advisory/ntap-20190919-0004/", - "https://github.com/lodash/lodash/commit/d8e069cc3410082e44eb18fcf8e7f3d08ebe1d4a" - ], + "issueId": "XRAY-75300", + "references": null, "impactPaths": [ [ { @@ -188,49 +155,43 @@ } ] ], - "jfrogResearchInformation": null + "jfrogResearchInformation": { + "severity": "", + "remediation": "Some remediation" + } }, { "severity": "Medium", - "impactedPackageName": "express", - "impactedPackageVersion": "4.18.2", + "impactedPackageName": "lodash", + "impactedPackageVersion": "4.17.0", "impactedPackageType": "npm", "components": [ { - "name": "express", - "version": "4.18.2", + "name": "lodash", + "version": "4.17.0", "location": { - "file": "/Users/user/ejs-frog-demo/package.json" + "file": "/Users/user/project-with-issues/package.json" } } ], - "summary": "Express.js minimalist web framework for node. Versions of Express.js prior to 4.19.0 and all pre-release alpha and beta versions of 5.0 are affected by an open redirect vulnerability using malformed URLs. When a user of Express performs a redirect using a user-provided URL Express performs an encode [using `encodeurl`](https://github.com/pillarjs/encodeurl) on the contents before passing it to the `location` header. This can cause malformed URLs to be evaluated in unexpected ways by common redirect allow list implementations in Express applications, leading to an Open Redirect via bypass of a properly implemented allow list. The main method impacted is `res.location()` but this is also called from within `res.redirect()`. The vulnerability is fixed in 4.19.2 and 5.0.0-beta.3.", + "summary": "Improperly Controlled Modification of Object", "applicable": "Not Covered", "fixedVersions": [ - "[4.19.2]", - "[5.0.0-beta.3]" + "[4.17.5]" ], "cves": [ { - "id": "CVE-2024-29041", + "id": "CVE-2018-3721", "cvssV2": "", - "cvssV3": "6.1", + "cvssV3": "", "applicability": { - "status": "Not Covered" + "status": "Not Covered", + "scannerDescription": "The Scanner checks for CVE-2018-3721" } } ], - "issueId": "XRAY-594935", - "references": [ - "https://github.com/koajs/koa/issues/1800", - "https://github.com/expressjs/express/pull/5539", - "https://github.com/expressjs/express/commit/0b746953c4bd8e377123527db11f9cd866e39f94", - "https://github.com/expressjs/express/commit/0867302ddbde0e9463d0564fea5861feb708c2dd", - "https://github.com/advisories/GHSA-rv95-896h-c2vc", - "https://expressjs.com/en/4x/api.html#res.location", - "https://nvd.nist.gov/vuln/detail/CVE-2024-29041", - "https://github.com/expressjs/express/security/advisories/GHSA-rv95-896h-c2vc" - ], + "issueId": "XRAY-72918", + "references": null, "impactPaths": [ [ { @@ -238,8 +199,8 @@ "version": "1.0.0" }, { - "name": "express", - "version": "4.18.2" + "name": "lodash", + "version": "4.17.0" } ] ], @@ -252,15 +213,15 @@ "impactedPackageType": "npm", "components": [ { - "name": "ejs", - "version": "3.1.6", + "name": "jake", + "version": "10.8.7", "location": { - "file": "/Users/user/ejs-frog-demo/package.json" + "file": "/Users/user/project-with-issues/package.json" } } ], - "summary": "Async \u003c= 2.6.4 and \u003c= 3.2.5 are vulnerable to ReDoS (Regular Expression Denial of Service) while parsing function in autoinject function. NOTE: this is disputed by the supplier because there is no realistic threat model: regular expressions are not used with untrusted input.", - "applicable": "Not Covered", + "summary": "Async vulnerable to ReDoS", + "applicable": "Applicable", "fixedVersions": null, "cves": [ { @@ -268,19 +229,26 @@ "cvssV2": "", "cvssV3": "", "applicability": { - "status": "Not Covered", - "scannerDescription": "Never applicable. The vulnerability is exploitable only if an attacker has access to the source code." + "status": "Applicable", + "scannerDescription": "The Scanner checks for CVE-2024-39249", + "evidence": [ + { + "file": "file-A", + "startLine": 1, + "startColumn": 2, + "endLine": 3, + "endColumn": 4, + "snippet": "snippet", + "reason": "ca msg" + } + ] } } ], "issueId": "XRAY-609848", "references": [ "https://github.com/zunak/CVE-2024-39249", - "https://github.com/caolan/async/blob/v3.2.5/lib/autoInject.js#L41", - "https://nvd.nist.gov/vuln/detail/CVE-2024-39249", - "https://github.com/caolan/async/blob/v3.2.5/lib/autoInject.js#L6", - "https://github.com/caolan/async/issues/1975#issuecomment-2204528153", - "https://github.com/zunak/CVE-2024-39249/issues/1" + "https://nvd.nist.gov/vuln/detail/CVE-2024-39249" ], "impactPaths": [ [ @@ -288,10 +256,6 @@ "name": "froghome", "version": "1.0.0" }, - { - "name": "ejs", - "version": "3.1.6" - }, { "name": "jake", "version": "10.8.7" @@ -304,32 +268,20 @@ ], "jfrogResearchInformation": { "severity": "Low", - "summary": "ReDoS in Async may lead to denial of service while parsing malformed source code.", + "summary": "ReDoS in Async may lead to denial of service while parsing", "severityReasons": [ { - "name": "The reported CVSS was either wrongly calculated, downgraded by other vendors, or does not reflect the vulnerability's impact", - "description": "The reported CVSS does not reflect the severity of the vulnerability.", - "isPositive": true - }, - { - "name": "The issue cannot result in a severe impact (such as remote code execution)", - "description": "To exploit this issue an attacker must change the source code of the application. In cases where an attacker can already modify (or fully control) the source code, the attacker can immediately achieve arbitrary code execution - thus this issue has almost no security impact.", - "isPositive": true - }, - { - "name": "The issue has an exploit published", - "description": "A proof-of-concept has been published in the advisory." - }, - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "The issue requires the use of the `async.autoInject` function to be vulnerable.", + "name": "The reported CVSS was either wrongly calculated", + "description": "The reported CVSS does not reflect the severity of the vulnerability", "isPositive": true } ] } - }, + } + ], + "securityViolations": [ { - "severity": "Critical", + "severity": "Medium", "impactedPackageName": "lodash", "impactedPackageVersion": "4.17.0", "impactedPackageType": "npm", @@ -338,51 +290,32 @@ "name": "lodash", "version": "4.17.0", "location": { - "file": "/Users/user/ejs-frog-demo/package.json" + "file": "/Users/user/project-with-issues/package.json" } } ], - "summary": "Versions of lodash lower than 4.17.12 are vulnerable to Prototype Pollution. The function defaultsDeep could be tricked into adding or modifying properties of Object.prototype using a constructor payload.", - "applicable": "Not Applicable", + "watch": "security-watch", + "policies": [ + "npm-security" + ], + "summary": "Improperly Controlled Modification of Object", + "applicable": "Not Covered", "fixedVersions": [ - "[4.17.12]" + "[4.17.5]" ], "cves": [ { - "id": "CVE-2019-10744", - "cvssV2": "6.4", - "cvssV3": "9.1", + "id": "CVE-2018-3721", + "cvssV2": "", + "cvssV3": "", "applicability": { - "status": "Not Applicable", - "scannerDescription": "The scanner checks whether the vulnerable function `defaultsDeep` is called with external input to its 2nd (`sources`) argument, and the `Object.freeze()` remediation is not present.", - "evidence": [ - { - "file": "server.js", - "startLine": 4, - "startColumn": 1, - "endLine": 4, - "endColumn": 32, - "snippet": "Object.freeze(Object.prototype)", - "reason": "Prototype pollution `Object.freeze` remediation was detected" - } - ] + "status": "Not Covered", + "scannerDescription": "The Scanner checks for CVE-2018-3721" } } ], - "issueId": "XRAY-85679", - "references": [ - "https://www.npmjs.com/advisories/1065", - "https://github.com/lodash/lodash/pull/4336", - "https://www.oracle.com/security-alerts/cpujan2021.html", - "https://security.netapp.com/advisory/ntap-20191004-0005/", - "https://snyk.io/vuln/SNYK-JS-LODASH-450202", - "https://support.f5.com/csp/article/K47105354?utm_source=f5support\u0026amp;utm_medium=RSS", - "https://access.redhat.com/errata/RHSA-2019:3024", - "https://www.oracle.com/security-alerts/cpuoct2020.html", - "https://support.f5.com/csp/article/K47105354?utm_source=f5support\u0026amp%3Butm_medium=RSS", - "https://github.com/advisories/GHSA-jf85-cpcp-j695", - "https://nvd.nist.gov/vuln/detail/CVE-2019-10744" - ], + "issueId": "XRAY-72918", + "references": null, "impactPaths": [ [ { @@ -395,81 +328,53 @@ } ] ], - "jfrogResearchInformation": { - "severity": "High", - "summary": "Insufficient input validation in lodash defaultsDeep() leads to prototype pollution.", - "details": "[lodash](https://www.npmjs.com/package/lodash) is a modern JavaScript utility library delivering modularity, performance, \u0026 extras.\n\nThe function `defaultsDeep` was found to be vulnerable to prototype pollution, when accepting arbitrary source objects from untrusted input\n\nExample of code vulnerable to this issue - \n```js\nconst lodash = require('lodash'); \nconst evilsrc = {constructor: {prototype: {evilkey: \"evilvalue\"}}};\nlodash.defaultsDeep({}, evilsrc)\n```", - "severityReasons": [ - { - "name": "The issue has an exploit published", - "description": "A public PoC demonstrates exploitation of this issue" - }, - { - "name": "The impact of exploiting the issue depends on the context of surrounding software. A severe impact such as RCE is not guaranteed.", - "description": "A prototype pollution attack allows the attacker to inject new properties to all JavaScript objects (but not set existing properties).\nTherefore, the impact of a prototype pollution attack depends on the way the JavaScript code uses any object properties after the attack is triggered.\nUsually, a DoS attack is possible since invalid properties quickly lead to an exception being thrown. In more severe cases, RCE may be achievable.", - "isPositive": true - }, - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "An attacker must find remote input that propagates into the `defaultsDeep` method (2nd arg)", - "isPositive": true - } - ], - "remediation": "##### Development mitigations\n\nAdd the `Object.freeze(Object.prototype);` directive once at the beginning of your main JS source code file (ex. `index.js`), preferably after all your `require` directives. This will prevent any changes to the prototype object, thus completely negating prototype pollution attacks." - } + "jfrogResearchInformation": null }, { - "severity": "Critical", - "impactedPackageName": "ejs", - "impactedPackageVersion": "3.1.6", + "severity": "Unknown", + "impactedPackageName": "async", + "impactedPackageVersion": "3.2.4", "impactedPackageType": "npm", "components": [ { - "name": "ejs", - "version": "3.1.6", + "name": "jake", + "version": "10.8.7", "location": { - "file": "/Users/user/ejs-frog-demo/package.json" + "file": "/Users/user/project-with-issues/package.json" } } ], - "summary": "The ejs (aka Embedded JavaScript templates) package 3.1.6 for Node.js allows server-side template injection in settings[view options][outputFunctionName]. This is parsed as an internal option, and overwrites the outputFunctionName option with an arbitrary OS command (which is executed upon template compilation).", - "applicable": "Not Applicable", - "fixedVersions": [ - "[3.1.7]" + "watch": "security-watch", + "policies": [ + "npm-security" ], + "summary": "Async vulnerable to ReDoS", + "applicable": "Applicable", + "fixedVersions": null, "cves": [ { - "id": "CVE-2022-29078", - "cvssV2": "7.5", - "cvssV3": "9.8", + "id": "CVE-2024-39249", + "cvssV2": "", + "cvssV3": "", "applicability": { - "status": "Not Applicable", - "scannerDescription": "The scanner checks for two vulnerable flows:\n\n1. Whether the `express.set` function is called with the arguments: `view engine` and `ejs`, or external input and if it's followed by a call to the vulnerable function `render` with an unknown second argument.\n\n2. Whether the `renderFile` function is called with an unknown second argument.\n\nThe scanner also checks whether the `Object.freeze()` remediation is not present.", + "status": "Applicable", + "scannerDescription": "The Scanner checks for CVE-2024-39249", "evidence": [ { - "file": "server.js", - "startLine": 4, - "startColumn": 1, - "endLine": 4, - "endColumn": 32, - "snippet": "Object.freeze(Object.prototype)", - "reason": "Prototype pollution `Object.freeze` remediation was detected" + "file": "file-A", + "startLine": 1, + "startColumn": 2, + "endLine": 3, + "endColumn": 4, + "snippet": "snippet", + "reason": "ca msg" } ] } } ], - "issueId": "XRAY-209002", - "references": [ - "https://github.com/mde/ejs/commit/15ee698583c98dadc456639d6245580d17a24baf", - "https://eslam.io/posts/ejs-server-side-template-injection-rce/", - "https://security.netapp.com/advisory/ntap-20220804-0001", - "https://github.com/mde/ejs/releases", - "https://nvd.nist.gov/vuln/detail/CVE-2022-29078", - "https://eslam.io/posts/ejs-server-side-template-injection-rce", - "https://github.com/mde/ejs", - "https://security.netapp.com/advisory/ntap-20220804-0001/" - ], + "issueId": "XRAY-609848", + "references": null, "impactPaths": [ [ { @@ -477,33 +382,21 @@ "version": "1.0.0" }, { - "name": "ejs", - "version": "3.1.6" + "name": "jake", + "version": "10.8.7" + }, + { + "name": "async", + "version": "3.2.4" } ] ], "jfrogResearchInformation": { - "severity": "Medium", - "summary": "Insufficient input validation in EJS enables attackers to perform template injection when attacker can control the rendering options.", - "details": "[Embedded JavaScript templates](https://github.com/mde/ejs), also known as EJS, is one of the most popular Node.js templating engines, which is compiled with the Express JS view system.\n\nWhen rendering views using EJS, it is possible to perform template injection on the `opts.outputFunctionName` variable, since the variable is injected into the template body without any escaping. Although it is unlikely that the attacker can directly control the `outputFunctionName` property, it is possible that it can be influenced in conjunction with a prototype pollution vulnerability.\n\nOnce template injection is achieved, the attacker can immediately perform remote code execution since the template engine (EJS) allows executing arbitrary JavaScript code.\n\nExample of a vulnerable Node.js application -\n```js\nconst express = require('express');\nconst bodyParser = require('body-parser');\nconst lodash = require('lodash');\nconst ejs = require('ejs');\n\nconst app = express();\n\napp\n .use(bodyParser.urlencoded({extended: true}))\n .use(bodyParser.json());\n\napp.set('views', './');\napp.set('view engine', 'ejs');\n\napp.get(\"/\", (req, res) =\u003e {\n res.render('index');\n});\n\napp.post(\"/\", (req, res) =\u003e {\n let data = {};\n let input = JSON.parse(req.body.content);\n lodash.defaultsDeep(data, input);\n res.json({message: \"OK\"});\n});\n\nlet server = app.listen(8086, '0.0.0.0', function() {\n console.log('Listening on port %d', server.address().port);\n});\n```\n\nExploiting the above example for RCE -\n`curl 127.0.0.1:8086 -v --data 'content={\"constructor\": {\"prototype\": {\"outputFunctionName\": \"a; return global.process.mainModule.constructor._load(\\\"child_process\\\").execSync(\\\"whoami\\\"); //\"}}}'\n`\n\nDue to the prototype pollution in the `lodash.defaultsDeep` call, an attacker can inject the `outputFunctionName` property with an arbitrary value. The chosen value executes an arbitrary process via the `child_process` module.", - "severityReasons": [ - { - "name": "The prerequisites for exploiting the issue are extremely unlikely", - "description": "The attacker has to find a way to get their malicious input to `opts.outputFunctionName`, which will usually require exploitation of a prototype pollution vulnerability somewhere else in the code. However, there could be cases where the attacker can pass malicious data to the render function directly because of design problems in other code using EJS.", - "isPositive": true - }, - { - "name": "The issue has an exploit published", - "description": "There are multiple examples of exploits for this vulnerability online." - }, - { - "name": "The issue results in a severe impact (such as remote code execution)", - "description": "Successful exploitation of this vulnerability leads to remote code execution." - } - ], - "remediation": "##### Development mitigations\n\nAdd the `Object.freeze(Object.prototype);` directive once at the beginning of your main JS source code file (ex. `index.js`), preferably after all your `require` directives. This will prevent any changes to the prototype object, thus completely negating prototype pollution attacks.\n\nNote that this mitigation is supposed to stop any prototype pollution attacks which can allow an attacker to control the `opts.outputFunctionName` parameter indirectly.\n\nThe mitigation will not stop any (extremely unlikely) scenarios where the JavaScript code allows external input to directly affect `opts.outputFunctionName`." + "severity": "Low" } - }, + } + ], + "licensesViolations": [ { "severity": "High", "impactedPackageName": "lodash", @@ -514,87 +407,22 @@ "name": "lodash", "version": "4.17.0", "location": { - "file": "/Users/user/ejs-frog-demo/package.json" - } - } - ], - "summary": "Lodash versions prior to 4.17.21 are vulnerable to Command Injection via the template function.", - "applicable": "Not Applicable", - "fixedVersions": [ - "[4.17.21]" - ], - "cves": [ - { - "id": "CVE-2021-23337", - "cvssV2": "6.5", - "cvssV3": "7.2", - "applicability": { - "status": "Not Applicable", - "scannerDescription": "The scanner checks whether the vulnerable function `lodash.template` is called with external input to its 2nd (`options`) argument." + "file": "/Users/user/project-with-issues/package.json" } } ], - "issueId": "XRAY-140575", - "references": [ - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSNPM-1074929", - "https://security.netapp.com/advisory/ntap-20210312-0006/", - "https://snyk.io/vuln/SNYK-JS-LODASH-1040724", - "https://security.netapp.com/advisory/ntap-20210312-0006", - "https://www.oracle.com/security-alerts/cpujan2022.html", - "https://github.com/lodash/lodash/commit/3469357cff396a26c363f8c1b5a91dde28ba4b1c", - "https://cert-portal.siemens.com/productcert/pdf/ssa-637483.pdf", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSBOWER-1074928", - "https://www.oracle.com/security-alerts/cpuoct2021.html", - "https://snyk.io/vuln/SNYK-JAVA-ORGFUJIONWEBJARS-1074932", - "https://github.com/lodash/lodash/blob/ddfd9b11a0126db2302cb70ec9973b66baec0975/lodash.js%23L14851", - "https://github.com/advisories/GHSA-35jh-r3h4-6jhm", - "https://www.oracle.com/security-alerts/cpujul2022.html", - "https://www.oracle.com//security-alerts/cpujul2021.html", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARS-1074930", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSBOWERGITHUBLODASH-1074931", - "https://nvd.nist.gov/vuln/detail/CVE-2021-23337", - "https://github.com/lodash/lodash/blob/ddfd9b11a0126db2302cb70ec9973b66baec0975/lodash.js#L14851" - ], - "impactPaths": [ - [ - { - "name": "froghome", - "version": "1.0.0" - }, - { - "name": "lodash", - "version": "4.17.0" - } - ] - ], - "jfrogResearchInformation": { - "severity": "Medium", - "summary": "Improper sanitization in the lodash template function leads to JavaScript code injection through the options argument.", - "details": "JavaScript-based applications (both frontend and backend) that use the [template function](https://lodash.com/docs/4.17.15#template) -`_.template([string=''], [options={}])` from the [lodash](https://lodash.com/) utility library and provide the `options` argument (specifically the `variable` option) from untrusted user input, are vulnerable to JavaScript code injection. This issue can be easily exploited, and an exploitation example is [publicly available](https://github.com/lodash/lodash/commit/3469357cff396a26c363f8c1b5a91dde28ba4b1c#diff-a561630bb56b82342bc66697aee2ad96efddcbc9d150665abd6fb7ecb7c0ab2fR22303) in the fix tests that was introduced in version 4.17.21 - \n```js\nlodash.template('', { variable: '){console.log(process.env)}; with(obj' })()\n```", - "severityReasons": [ - { - "name": "The prerequisites for exploiting the issue are extremely unlikely", - "description": "It is highly unlikely that a JS program will accept arbitrary remote input into the template's `options` argument", - "isPositive": true - }, - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "The attacker must find remote input that propagates into the `options` argument of a `template` call", - "isPositive": true - }, - { - "name": "The issue results in a severe impact (such as remote code execution)", - "description": "Leads to remote code execution through JS code injection" - }, - { - "name": "The issue has an exploit published", - "description": "Published exploit demonstrates arbitrary JS code execution" - } - ] - } - }, + "licenseKey": "MIT", + "licenseName": "MIT full name", + "impactPaths": null, + "watch": "license-watch", + "policies": [ + "npm-license" + ] + } + ], + "licenses": [ { - "severity": "High", + "severity": "", "impactedPackageName": "lodash", "impactedPackageVersion": "4.17.0", "impactedPackageType": "npm", @@ -603,45 +431,11 @@ "name": "lodash", "version": "4.17.0", "location": { - "file": "/Users/user/ejs-frog-demo/package.json" - } - } - ], - "summary": "Prototype pollution attack when using _.zipObjectDeep in lodash before 4.17.20.", - "applicable": "Not Applicable", - "fixedVersions": [ - "[4.17.19]" - ], - "cves": [ - { - "id": "CVE-2020-8203", - "cvssV2": "5.8", - "cvssV3": "7.4", - "applicability": { - "status": "Not Applicable", - "scannerDescription": "The scanner checks whether the vulnerable function `zipObjectDeep` is called with external input to its 1st (`props`) and 2nd (`values`) arguments, and the `Object.freeze()` remediation is not present." + "file": "/Users/user/project-with-issues/package.json" } } ], - "issueId": "XRAY-114089", - "references": [ - "https://nvd.nist.gov/vuln/detail/CVE-2020-8203", - "https://www.oracle.com/security-alerts/cpuapr2022.html", - "https://hackerone.com/reports/864701", - "https://hackerone.com/reports/712065", - "https://github.com/advisories/GHSA-p6mc-m468-83gw", - "https://www.oracle.com//security-alerts/cpujul2021.html", - "https://github.com/lodash/lodash/issues/4744", - "https://www.oracle.com/security-alerts/cpuApr2021.html", - "https://github.com/github/advisory-database/pull/2884", - "https://www.oracle.com/security-alerts/cpujan2022.html", - "https://github.com/lodash/lodash/commit/c84fe82760fb2d3e03a63379b297a1cc1a2fce12", - "https://security.netapp.com/advisory/ntap-20200724-0006/", - "https://web.archive.org/web/20210914001339/https://github.com/lodash/lodash/issues/4744", - "https://www.oracle.com/security-alerts/cpuoct2021.html", - "https://github.com/lodash/lodash/issues/4874", - "https://github.com/lodash/lodash/wiki/Changelog#v41719" - ], + "licenseKey": "MIT", "impactPaths": [ [ { @@ -653,774 +447,124 @@ "version": "4.17.0" } ] - ], - "jfrogResearchInformation": { - "severity": "Critical", - "summary": "Prototype pollution in lodash object merging and zipping functions leads to code injection.", - "details": "[lodash](https://lodash.com/) is a JavaScript library which provides utility functions for common programming tasks.\n\nJavaScript frontend and Node.js-based backend applications that merge or zip objects using the lodash functions `mergeWith`, `merge` and `zipObjectDeep` are vulnerable to [prototype pollution](https://medium.com/node-modules/what-is-prototype-pollution-and-why-is-it-such-a-big-deal-2dd8d89a93c) if one or more of the objects it receives as arguments are obtained from user input. \nAn attacker controlling this input given to the vulnerable functions can inject properties to JavaScript special objects such as [Object.prototype](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes) from which all JavaScript objects inherit properties and methods. Any change on `Object.prototype` properties will then propagate through the prototype chain inheritance to all of the objects in a JavaScript application. This in turn would allow an attacker to add new properties or modify existing properties which will have application specific implications that could lead to DoS (denial of service), authentication bypass, privilege escalation and even RCE (remote code execution) in [some cases](https://youtu.be/LUsiFV3dsK8?t=1152). \nAs an example for privilege escalation, consider a JavaScript application that has a `user` object which has a Boolean property of `user.isAdmin` which is used to decide which actions the user may take. If an attacker can modify or add the `isAdmin` property through prototype pollution, it can escalate the privileges of its own user to those of an admin. \nAs exploitation is usually application specific, successful exploitation is much more likely if an attacker have access to the JavaScript application code. As such, frontend applications are more vulnerable to this vulnerability than Node.js backend applications.", - "severityReasons": [ - { - "name": "The impact of exploiting the issue depends on the context of surrounding software. A severe impact such as RCE is not guaranteed.", - "isPositive": true - }, - { - "name": "The issue can be exploited by attackers over the network" - }, - { - "name": "The issue is trivial to exploit and does not require a published writeup or PoC" - } - ], - "remediation": "##### Deployment mitigations\n\nAs general guidelines against prototype pollution, first consider not merging objects originating from user input or using a Map structure instead of an object. If merging objects is needed, look into creating objects without a prototype with `Object.create(null)` or into freezing `Object.prototype` with `Object.freeze()`. Finally, it is always best to perform input validation with a a [JSON schema validator](https://github.com/ajv-validator/ajv), which could mitigate this issue entirely in many cases." - } - }, - { - "severity": "Medium", - "impactedPackageName": "lodash", - "impactedPackageVersion": "4.17.0", - "impactedPackageType": "npm", - "components": [ - { - "name": "lodash", - "version": "4.17.0", - "location": { - "file": "/Users/user/ejs-frog-demo/package.json" - } - } - ], - "summary": "A prototype pollution vulnerability was found in lodash \u003c4.17.11 where the functions merge, mergeWith, and defaultsDeep can be tricked into adding or modifying properties of Object.prototype.", - "applicable": "Not Applicable", - "fixedVersions": [ - "[4.17.11]" - ], - "cves": [ - { - "id": "CVE-2018-16487", - "cvssV2": "6.8", - "cvssV3": "5.6", - "applicability": { - "status": "Not Applicable", - "scannerDescription": "The scanner checks whether any of the following vulnerable functions are called:\n\n* `lodash.merge` with external input to its 2nd (`sources`) argument.\n* `lodash.mergeWith` with external input to its 2nd (`sources`) argument.\n* `lodash.defaultsDeep` with external input to its 2nd (`sources`) argument.\n\nThe scanner also checks whether the `Object.freeze()` remediation is not present.", - "evidence": [ - { - "file": "server.js", - "startLine": 4, - "startColumn": 1, - "endLine": 4, - "endColumn": 32, - "snippet": "Object.freeze(Object.prototype)", - "reason": "Prototype pollution `Object.freeze` remediation was detected" - } - ] - } - } - ], - "issueId": "XRAY-75300", - "references": [ - "https://nvd.nist.gov/vuln/detail/CVE-2018-16487", - "https://www.npmjs.com/advisories/782", - "https://security.netapp.com/advisory/ntap-20190919-0004/", - "https://github.com/advisories/GHSA-4xc9-xhrj-v574", - "https://github.com/lodash/lodash/commit/90e6199a161b6445b01454517b40ef65ebecd2ad", - "https://security.netapp.com/advisory/ntap-20190919-0004", - "https://hackerone.com/reports/380873" - ], - "impactPaths": [ - [ - { - "name": "froghome", - "version": "1.0.0" - }, - { - "name": "lodash", - "version": "4.17.0" - } - ] - ], - "jfrogResearchInformation": { - "severity": "High", - "summary": "Insufficient input validation in the Lodash library leads to prototype pollution.", - "details": "The [Lodash](https://lodash.com/) library is an open-source JavaScript project that simplifies operations on string, arrays, numbers, and other objects. It is widely used in connected devices. \n\nThe `merge`, `mergeWith`, and `defaultsDeep` methods in Lodash are vulnerable to [prototype pollution](https://shieldfy.io/security-wiki/prototype-pollution/introduction-to-prototype-pollution/). Attackers can exploit this vulnerability by specifying a crafted `sources` parameter to any of these methods, which can modify the prototype properties of the `Object`, `Function`, `Array`, `String`, `Number`, and `Boolean` objects. A public [exploit](https://hackerone.com/reports/380873) exists which performs the prototype pollution with an arbitrary key and value.\n\nThe library implementation has a bug in the `safeGet()` function in the `lodash.js` module that allows for adding or modifying `prototype` properties of various objects. The official [solution](https://github.com/lodash/lodash/commit/90e6199a161b6445b01454517b40ef65ebecd2ad) fixes the bug by explicitly forbidding the addition or modification of `prototype` properties.\n\nA related CVE (CVE-2018-3721) covers the same issue prior to Lodash version 4.17.5, but the fix for that was incomplete.", - "severityReasons": [ - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "An attacker must find remote input that propagates into one of the following methods - \n* `merge` - 2nd argument\n* `mergeWith` - 2nd argument\n* `defaultsDeep` - 2nd argument", - "isPositive": true - }, - { - "name": "The impact of exploiting the issue depends on the context of surrounding software. A severe impact such as RCE is not guaranteed.", - "description": "A prototype pollution attack allows the attacker to inject new properties to all JavaScript objects (but not set existing properties).\nTherefore, the impact of a prototype pollution attack depends on the way the JavaScript code uses any object properties after the attack is triggered.\nUsually, a DoS attack is possible since invalid properties quickly lead to an exception being thrown. In more severe cases, RCE may be achievable.", - "isPositive": true - }, - { - "name": "The issue has an exploit published", - "description": "A public PoC demonstrated exploitation by injecting an attacker controlled key and value into the prototype" - } - ], - "remediation": "##### Development mitigations\n\nAdd the `Object.freeze(Object.prototype);` directive once at the beginning of your main JS source code file (ex. `index.js`), preferably after all your `require` directives. This will prevent any changes to the prototype object, thus completely negating prototype pollution attacks." - } - }, - { - "severity": "Medium", - "impactedPackageName": "ejs", - "impactedPackageVersion": "3.1.6", - "impactedPackageType": "npm", - "components": [ - { - "name": "ejs", - "version": "3.1.6", - "location": { - "file": "/Users/user/ejs-frog-demo/package.json" - } - } - ], - "summary": "The ejs (aka Embedded JavaScript templates) package before 3.1.10 for Node.js lacks certain pollution protection.", - "applicable": "Not Applicable", - "fixedVersions": [ - "[3.1.10]" - ], - "cves": [ - { - "id": "CVE-2024-33883", - "cvssV2": "", - "cvssV3": "4.0", - "applicability": { - "status": "Not Applicable", - "scannerDescription": "The scanner checks whether the vulnerable function `ejs.compile()` is called." - } - } - ], - "issueId": "XRAY-599735", - "references": [ - "https://security.netapp.com/advisory/ntap-20240605-0003/", - "https://security.netapp.com/advisory/ntap-20240605-0003", - "https://github.com/mde/ejs/commit/e469741dca7df2eb400199e1cdb74621e3f89aa5", - "https://github.com/mde/ejs/compare/v3.1.9...v3.1.10", - "https://github.com/advisories/GHSA-ghr5-ch3p-vcr6", - "https://nvd.nist.gov/vuln/detail/CVE-2024-33883" - ], - "impactPaths": [ - [ - { - "name": "froghome", - "version": "1.0.0" - }, - { - "name": "ejs", - "version": "3.1.6" - } - ] - ], - "jfrogResearchInformation": { - "severity": "Medium", - "summary": "Insufficient input validation in EJS may lead to prototype pollution.", - "details": "[Embedded JavaScript templates](https://github.com/mde/ejs), also known as `EJS`, is one of the most popular Node.js templating engines, which is compiled with the Express JS view system.\n\nA prototype pollution gadget within the EJS template engine could potentially be leveraged by attackers to achieve remote code execution or DoS via prototype pollution.\n\n```\nfunction Template(text, opts) {\n opts = opts || utils.createNullProtoObjWherePossible();\n```\n\nWhen checking for the presence of a property within an object variable, the lookup scope isn't explicitly defined. In JavaScript, the absence of a defined lookup scope prompts a search up to the root prototype (`Object.prototype`). This could potentially be under the control of an attacker if another prototype pollution vulnerability is present within the application.\n\nIf the application server is using the EJS as the backend template engine, and there is another prototype pollution vulnerability in the application, then the attacker could leverage the found gadgets in the EJS template engine to escalate the prototype pollution to remote code execution or DoS.\n\nThe following code will execute a command on the server by polluting `opts.escapeFunction`:\n \n```\nconst express = require('express');\nconst app = express();\nconst port = 8008;\nconst ejs = require('ejs');\n\n// Set EJS as the view engine\napp.set('view engine', 'ejs');\n\napp.get('/', (req, res) =\u003e {\n \n const data = {title: 'Welcome', message: 'Hello'};\n\n // Sample EJS template string\n const templateString = `\u003chtml\u003e\u003chead\u003e\u003ctitle\u003e\u003c%= title %\u003e\u003c/title\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1\u003e\u003c%= message %\u003e\u003c/h1\u003e\u003c/body\u003e\u003c/html\u003e`;\n\n const { exec } = require('child_process');\n\n function myFunc() {\n exec('bash -c \"echo 123\"', (error, stdout, stderr) =\u003e {\n if (error) {\n console.error(`exec error: ${error}`);\n return;\n }\n if (stderr){\n console.log(`stderr : ${stderr}`);\n return;\n }\n // Handle success\n console.log(`Command executed successfully. Output: ${stdout}`);\n });\n }\n\n const options = {client:false};\n\n Object.prototype.escapeFunction = myFunc;\n \n const compiledTemplate = ejs.compile(templateString, options);\n const renderedHtml = compiledTemplate(data);\n res.send(renderedHtml);\n});\n\n// Start the server\napp.listen(port, () =\u003e {\n console.log(`Server is running on http://localhost:${port}`);\n});\n```", - "severityReasons": [ - { - "name": "The prerequisites for exploiting the issue are extremely unlikely", - "description": "Attackers can only leverage this vulnerability when the application server is using the EJS as the backend template engine. Moreover, there must be a second prototype pollution vulnerability in the application.", - "isPositive": true - }, - { - "name": "The reported CVSS was either wrongly calculated, downgraded by other vendors, or does not reflect the vulnerability's impact", - "description": "CVSS does not take into account the unlikely prerequisites necessary for exploitation.", - "isPositive": true - }, - { - "name": "The issue results in a severe impact (such as remote code execution)", - "description": "A prototype pollution attack allows the attacker to inject new properties into all JavaScript objects.\nTherefore, the impact of a prototype pollution attack depends on the way the JavaScript code uses any object properties after the attack is triggered.\nUsually, a DoS attack is possible since invalid properties quickly lead to an exception being thrown. In more severe cases, RCE may be achievable." - } - ] - } - }, - { - "severity": "Medium", - "impactedPackageName": "lodash", - "impactedPackageVersion": "4.17.0", - "impactedPackageType": "npm", - "components": [ - { - "name": "lodash", - "version": "4.17.0", - "location": { - "file": "/Users/user/ejs-frog-demo/package.json" - } - } - ], - "summary": "Lodash versions prior to 4.17.21 are vulnerable to Regular Expression Denial of Service (ReDoS) via the toNumber, trim and trimEnd functions.", - "applicable": "Not Applicable", - "fixedVersions": [ - "[4.17.21]" - ], - "cves": [ - { - "id": "CVE-2020-28500", - "cvssV2": "5.0", - "cvssV3": "5.3", - "applicability": { - "status": "Not Applicable", - "scannerDescription": "The scanner checks whether any of the following vulnerable functions are called:\n\n* `lodash.trim` with external input to its 1st (`string`) argument.\n* `lodash.toNumber` with external input to its 1st (`value`) argument.\n* `lodash.trimEnd` with external input to its 1st (`string`) argument." - } - } - ], - "issueId": "XRAY-140562", - "references": [ - "https://cert-portal.siemens.com/productcert/pdf/ssa-637483.pdf", - "https://github.com/lodash/lodash/commit/c4847ebe7d14540bb28a8b932a9ce1b9ecbfee1a", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARS-1074894", - "https://github.com/lodash/lodash/blob/npm/trimEnd.js%23L8", - "https://security.netapp.com/advisory/ntap-20210312-0006/", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSNPM-1074893", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSBOWER-1074892", - "https://www.oracle.com//security-alerts/cpujul2021.html", - "https://www.oracle.com/security-alerts/cpuoct2021.html", - "https://nvd.nist.gov/vuln/detail/CVE-2020-28500", - "https://www.oracle.com/security-alerts/cpujul2022.html", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSBOWERGITHUBLODASH-1074895", - "https://github.com/lodash/lodash/pull/5065/commits/02906b8191d3c100c193fe6f7b27d1c40f200bb7", - "https://www.oracle.com/security-alerts/cpujan2022.html", - "https://github.com/advisories/GHSA-29mw-wpgm-hmr9", - "https://github.com/lodash/lodash/pull/5065", - "https://snyk.io/vuln/SNYK-JAVA-ORGFUJIONWEBJARS-1074896", - "https://snyk.io/vuln/SNYK-JS-LODASH-1018905" - ], - "impactPaths": [ - [ - { - "name": "froghome", - "version": "1.0.0" - }, - { - "name": "lodash", - "version": "4.17.0" - } - ] - ], - "jfrogResearchInformation": { - "severity": "Medium", - "summary": "ReDoS in lodash could lead to a denial of service when handling untrusted strings.", - "details": "JavaScript-based applications that use [lodash](https://github.com/lodash/lodash) and specifically the [_.toNumber](https://lodash.com/docs/4.17.15#toNumber), [_.trim](https://lodash.com/docs/4.17.15#trim) and [_.trimEnd](https://lodash.com/docs/4.17.15#trimEnd) functions, could be vulnerable to DoS (Denial of Service) through a faulty regular expression that introduces a ReDoS (Regular Expression DoS) vulnerability. This vulnerability is only triggered if untrusted user input flows into these vulnerable functions and the attacker can supply arbitrary long strings (over 50kB) that contain whitespaces. \n\nOn a modern Core i7-based system, calling the vulnerable functions with a 50kB string could take between 2 to 3 seconds to execute and 4.5 minutes for a longer 500kB string. The fix improved the regular expression performance so it took only a few milliseconds on the same Core i7-based system. This vulnerability is easily exploitable as all is required is to build a string that triggers it as can be seen in this PoC reproducing code - \n\n```js\nvar untrusted_user_input_50k = \"a\" + ' '.repeat(50000) + \"z\"; // assume this is provided over the network\nlo.trimEnd(untrusted_user_input_50k); // should take a few seconds to run\nvar untrusted_user_input_500k = \"a\" + ' '.repeat(500000) + \"z\"; // assume this is provided over the network\nlo.trimEnd(untrusted_user_input_500k); // should take a few minutes to run\n```", - "severityReasons": [ - { - "name": "The issue has an exploit published", - "description": "Public exploit demonstrated ReDoS" - }, - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "Exploitation depends on parsing user input by the `.toNumber`, `.trim` or `.trimEnd` `lodash` functions, and requires the input to contain whitespaces and be very long (over 50KB)", - "isPositive": true - } - ], - "remediation": "##### Deployment mitigations\n\nTrim untrusted strings based on size before providing it to the vulnerable functions by using the `substring` function to with a fixed maximum size like so - ```js untrusted_user_input.substring(0, max_string_size_less_than_50kB); ```" - } - } - ], - "securityViolations": [ - { - "severity": "Critical", - "impactedPackageName": "ejs", - "impactedPackageVersion": "3.1.6", - "impactedPackageType": "npm", - "components": [ - { - "name": "ejs", - "version": "3.1.6", - "location": { - "file": "/Users/user/ejs-frog-demo/package.json" - } - } - ], - "summary": "ejs v3.1.9 is vulnerable to server-side template injection. If the ejs file is controllable, template injection can be implemented through the configuration settings of the closeDelimiter parameter. NOTE: this is disputed by the vendor because the render function is not intended to be used with untrusted input.", - "applicable": "Applicable", - "fixedVersions": null, - "cves": [ - { - "id": "CVE-2023-29827", - "cvssV2": "", - "cvssV3": "9.8", - "applicability": { - "status": "Applicable", - "scannerDescription": "The scanner checks whether any of the following conditions are met:\n\n1. The `ejs.renderFile` function is called with an unknown third argument.\n\n2. The `ejs.compile` function is called with an unknown second argument.\n\n3. The `express.set` function is called with any of the following arguments:\n\n* `express.set(\"view engine\", \"ejs\")`\n* `express.set(\"view engine\", {USER_INPUT})`\n* `express.set({USER_INPUT}, \"ejs\")`\n* `express.set({USER_INPUT}, {USER_INPUT})`", - "evidence": [ - { - "file": "server.js", - "startLine": 14, - "startColumn": 1, - "endLine": 14, - "endColumn": 30, - "snippet": "app.set('view engine', 'ejs')", - "reason": "The vulnerable functionality is triggered since express.set is called with 'view engine' as the first argument and 'ejs' as the second argument or both arguments with external input" - } - ] - } - } - ], - "issueId": "XRAY-520200", - "references": [ - "https://nvd.nist.gov/vuln/detail/CVE-2023-29827", - "https://github.com/mde/ejs/issues/720", - "https://github.com/mde/ejs/blob/main/SECURITY.md#out-of-scope-vulnerabilities" - ], - "impactPaths": [ - [ - { - "name": "froghome", - "version": "1.0.0" - }, - { - "name": "ejs", - "version": "3.1.6" - } - ] - ], - "jfrogResearchInformation": { - "severity": "Low", - "summary": "Insufficient input validation can lead to template injection in ejs when attackers can control both the rendered template and rendering options.", - "details": "[Embedded JavaScript templates](https://github.com/mde/ejs), also known as EJS, is one of the most popular Node.js templating engines, which is compiled with the Express JS view system.\n\nWhen rendering views using EJS, it is possible to bypass ejs' template injection restrictions, by abusing the `closeDelimiter` rendering option, in the case when -\n1. The template itself can be partially controlled by the attacker\n2. The template rendering options can be fully controlled by the attacker\n\nThe vulnerability was **rightfully disputed** due to the fact that a vulnerable configuration is extremely unlikely to exist in any real-world setup. As such, the maintainers will not provide a fix for this (non-)issue.\n\nExample of a vulnerable application -\n```js\nconst express = require('express')\nconst app = express()\nconst port = 3000\n\napp.set('view engine', 'ejs');\n\napp.get('/page', (req,res) =\u003e {\n res.render('page', req.query); // OPTS (2nd parameter) IS ATTACKER-CONTROLLED\n})\n\napp.listen(port, () =\u003e {\n console.log(\"Example app listening on port ${port}\")\n})\n```\n\nContents of `page.ejs` (very unlikely to be attacker controlled) -\n```js\n%%1\");process.mainModule.require('child_process').execSync('calc');//\n```\n\nIn this case, sending `closeDelimiter` with the same malicious code that already exists at `page.ejs` will trigger the injection -\n`http://127.0.0.1:3000/page?settings[view%20options][closeDelimiter]=1\")%3bprocess.mainModule.require('child_process').execSync('calc')%3b//`", - "severityReasons": [ - { - "name": "The reported CVSS was either wrongly calculated, downgraded by other vendors, or does not reflect the vulnerability's impact", - "description": "The CVSS does not take into account the rarity of a vulnerable configuration to exist", - "isPositive": true - }, - { - "name": "The prerequisites for exploiting the issue are extremely unlikely", - "description": "The vulnerability can be exploited only under the following conditions -\n1. The template itself can be partially controlled by the attacker\n2. The template rendering options can be fully controlled by the attacker\nThis vulnerable configuration is extremely unlikely to exist in any real-world setup.", - "isPositive": true - }, - { - "name": "The issue has been disputed by the vendor", - "isPositive": true - }, - { - "name": "The issue has an exploit published", - "description": "Published exploit demonstrates template injection" - } - ] - } - }, - { - "severity": "Critical", - "impactedPackageName": "lodash", - "impactedPackageVersion": "4.17.0", - "impactedPackageType": "npm", - "components": [ - { - "name": "lodash", - "version": "4.17.0", - "location": { - "file": "/Users/user/ejs-frog-demo/package.json" - } - } - ], - "summary": "Versions of lodash lower than 4.17.12 are vulnerable to Prototype Pollution. The function defaultsDeep could be tricked into adding or modifying properties of Object.prototype using a constructor payload.", - "applicable": "Not Applicable", - "fixedVersions": [ - "[4.17.12]" - ], - "cves": [ - { - "id": "CVE-2019-10744", - "cvssV2": "6.4", - "cvssV3": "9.1", - "applicability": { - "status": "Not Applicable", - "scannerDescription": "The scanner checks whether the vulnerable function `defaultsDeep` is called with external input to its 2nd (`sources`) argument, and the `Object.freeze()` remediation is not present.", - "evidence": [ - { - "file": "server.js", - "startLine": 4, - "startColumn": 1, - "endLine": 4, - "endColumn": 32, - "snippet": "Object.freeze(Object.prototype)", - "reason": "Prototype pollution `Object.freeze` remediation was detected" - } - ] - } - } - ], - "issueId": "XRAY-85679", - "references": [ - "https://www.npmjs.com/advisories/1065", - "https://github.com/lodash/lodash/pull/4336", - "https://www.oracle.com/security-alerts/cpujan2021.html", - "https://security.netapp.com/advisory/ntap-20191004-0005/", - "https://snyk.io/vuln/SNYK-JS-LODASH-450202", - "https://support.f5.com/csp/article/K47105354?utm_source=f5support\u0026amp;utm_medium=RSS", - "https://access.redhat.com/errata/RHSA-2019:3024", - "https://www.oracle.com/security-alerts/cpuoct2020.html", - "https://support.f5.com/csp/article/K47105354?utm_source=f5support\u0026amp%3Butm_medium=RSS", - "https://github.com/advisories/GHSA-jf85-cpcp-j695", - "https://nvd.nist.gov/vuln/detail/CVE-2019-10744" - ], - "impactPaths": [ - [ - { - "name": "froghome", - "version": "1.0.0" - }, - { - "name": "lodash", - "version": "4.17.0" - } - ] - ], - "jfrogResearchInformation": { - "severity": "High", - "summary": "Insufficient input validation in lodash defaultsDeep() leads to prototype pollution.", - "details": "[lodash](https://www.npmjs.com/package/lodash) is a modern JavaScript utility library delivering modularity, performance, \u0026 extras.\n\nThe function `defaultsDeep` was found to be vulnerable to prototype pollution, when accepting arbitrary source objects from untrusted input\n\nExample of code vulnerable to this issue - \n```js\nconst lodash = require('lodash'); \nconst evilsrc = {constructor: {prototype: {evilkey: \"evilvalue\"}}};\nlodash.defaultsDeep({}, evilsrc)\n```", - "severityReasons": [ - { - "name": "The issue has an exploit published", - "description": "A public PoC demonstrates exploitation of this issue" - }, - { - "name": "The impact of exploiting the issue depends on the context of surrounding software. A severe impact such as RCE is not guaranteed.", - "description": "A prototype pollution attack allows the attacker to inject new properties to all JavaScript objects (but not set existing properties).\nTherefore, the impact of a prototype pollution attack depends on the way the JavaScript code uses any object properties after the attack is triggered.\nUsually, a DoS attack is possible since invalid properties quickly lead to an exception being thrown. In more severe cases, RCE may be achievable.", - "isPositive": true - }, - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "An attacker must find remote input that propagates into the `defaultsDeep` method (2nd arg)", - "isPositive": true - } - ], - "remediation": "##### Development mitigations\n\nAdd the `Object.freeze(Object.prototype);` directive once at the beginning of your main JS source code file (ex. `index.js`), preferably after all your `require` directives. This will prevent any changes to the prototype object, thus completely negating prototype pollution attacks." - } - }, - { - "severity": "Critical", - "impactedPackageName": "ejs", - "impactedPackageVersion": "3.1.6", - "impactedPackageType": "npm", - "components": [ - { - "name": "ejs", - "version": "3.1.6", - "location": { - "file": "/Users/user/ejs-frog-demo/package.json" - } - } - ], - "summary": "The ejs (aka Embedded JavaScript templates) package 3.1.6 for Node.js allows server-side template injection in settings[view options][outputFunctionName]. This is parsed as an internal option, and overwrites the outputFunctionName option with an arbitrary OS command (which is executed upon template compilation).", - "applicable": "Not Applicable", - "fixedVersions": [ - "[3.1.7]" - ], - "cves": [ - { - "id": "CVE-2022-29078", - "cvssV2": "7.5", - "cvssV3": "9.8", - "applicability": { - "status": "Not Applicable", - "scannerDescription": "The scanner checks for two vulnerable flows:\n\n1. Whether the `express.set` function is called with the arguments: `view engine` and `ejs`, or external input and if it's followed by a call to the vulnerable function `render` with an unknown second argument.\n\n2. Whether the `renderFile` function is called with an unknown second argument.\n\nThe scanner also checks whether the `Object.freeze()` remediation is not present.", - "evidence": [ - { - "file": "server.js", - "startLine": 4, - "startColumn": 1, - "endLine": 4, - "endColumn": 32, - "snippet": "Object.freeze(Object.prototype)", - "reason": "Prototype pollution `Object.freeze` remediation was detected" - } - ] - } - } - ], - "issueId": "XRAY-209002", - "references": [ - "https://github.com/mde/ejs/commit/15ee698583c98dadc456639d6245580d17a24baf", - "https://eslam.io/posts/ejs-server-side-template-injection-rce/", - "https://security.netapp.com/advisory/ntap-20220804-0001", - "https://github.com/mde/ejs/releases", - "https://nvd.nist.gov/vuln/detail/CVE-2022-29078", - "https://eslam.io/posts/ejs-server-side-template-injection-rce", - "https://github.com/mde/ejs", - "https://security.netapp.com/advisory/ntap-20220804-0001/" - ], - "impactPaths": [ - [ - { - "name": "froghome", - "version": "1.0.0" - }, - { - "name": "ejs", - "version": "3.1.6" - } - ] - ], - "jfrogResearchInformation": { - "severity": "Medium", - "summary": "Insufficient input validation in EJS enables attackers to perform template injection when attacker can control the rendering options.", - "details": "[Embedded JavaScript templates](https://github.com/mde/ejs), also known as EJS, is one of the most popular Node.js templating engines, which is compiled with the Express JS view system.\n\nWhen rendering views using EJS, it is possible to perform template injection on the `opts.outputFunctionName` variable, since the variable is injected into the template body without any escaping. Although it is unlikely that the attacker can directly control the `outputFunctionName` property, it is possible that it can be influenced in conjunction with a prototype pollution vulnerability.\n\nOnce template injection is achieved, the attacker can immediately perform remote code execution since the template engine (EJS) allows executing arbitrary JavaScript code.\n\nExample of a vulnerable Node.js application -\n```js\nconst express = require('express');\nconst bodyParser = require('body-parser');\nconst lodash = require('lodash');\nconst ejs = require('ejs');\n\nconst app = express();\n\napp\n .use(bodyParser.urlencoded({extended: true}))\n .use(bodyParser.json());\n\napp.set('views', './');\napp.set('view engine', 'ejs');\n\napp.get(\"/\", (req, res) =\u003e {\n res.render('index');\n});\n\napp.post(\"/\", (req, res) =\u003e {\n let data = {};\n let input = JSON.parse(req.body.content);\n lodash.defaultsDeep(data, input);\n res.json({message: \"OK\"});\n});\n\nlet server = app.listen(8086, '0.0.0.0', function() {\n console.log('Listening on port %d', server.address().port);\n});\n```\n\nExploiting the above example for RCE -\n`curl 127.0.0.1:8086 -v --data 'content={\"constructor\": {\"prototype\": {\"outputFunctionName\": \"a; return global.process.mainModule.constructor._load(\\\"child_process\\\").execSync(\\\"whoami\\\"); //\"}}}'\n`\n\nDue to the prototype pollution in the `lodash.defaultsDeep` call, an attacker can inject the `outputFunctionName` property with an arbitrary value. The chosen value executes an arbitrary process via the `child_process` module.", - "severityReasons": [ - { - "name": "The prerequisites for exploiting the issue are extremely unlikely", - "description": "The attacker has to find a way to get their malicious input to `opts.outputFunctionName`, which will usually require exploitation of a prototype pollution vulnerability somewhere else in the code. However, there could be cases where the attacker can pass malicious data to the render function directly because of design problems in other code using EJS.", - "isPositive": true - }, - { - "name": "The issue has an exploit published", - "description": "There are multiple examples of exploits for this vulnerability online." - }, - { - "name": "The issue results in a severe impact (such as remote code execution)", - "description": "Successful exploitation of this vulnerability leads to remote code execution." - } - ], - "remediation": "##### Development mitigations\n\nAdd the `Object.freeze(Object.prototype);` directive once at the beginning of your main JS source code file (ex. `index.js`), preferably after all your `require` directives. This will prevent any changes to the prototype object, thus completely negating prototype pollution attacks.\n\nNote that this mitigation is supposed to stop any prototype pollution attacks which can allow an attacker to control the `opts.outputFunctionName` parameter indirectly.\n\nThe mitigation will not stop any (extremely unlikely) scenarios where the JavaScript code allows external input to directly affect `opts.outputFunctionName`." - } - }, - { - "severity": "High", - "impactedPackageName": "lodash", - "impactedPackageVersion": "4.17.0", - "impactedPackageType": "npm", - "components": [ - { - "name": "lodash", - "version": "4.17.0", - "location": { - "file": "/Users/user/ejs-frog-demo/package.json" - } - } - ], - "summary": "Lodash versions prior to 4.17.21 are vulnerable to Command Injection via the template function.", - "applicable": "Not Applicable", - "fixedVersions": [ - "[4.17.21]" - ], - "cves": [ - { - "id": "CVE-2021-23337", - "cvssV2": "6.5", - "cvssV3": "7.2", - "applicability": { - "status": "Not Applicable", - "scannerDescription": "The scanner checks whether the vulnerable function `lodash.template` is called with external input to its 2nd (`options`) argument." - } - } - ], - "issueId": "XRAY-140575", - "references": [ - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSNPM-1074929", - "https://security.netapp.com/advisory/ntap-20210312-0006/", - "https://snyk.io/vuln/SNYK-JS-LODASH-1040724", - "https://security.netapp.com/advisory/ntap-20210312-0006", - "https://www.oracle.com/security-alerts/cpujan2022.html", - "https://github.com/lodash/lodash/commit/3469357cff396a26c363f8c1b5a91dde28ba4b1c", - "https://cert-portal.siemens.com/productcert/pdf/ssa-637483.pdf", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSBOWER-1074928", - "https://www.oracle.com/security-alerts/cpuoct2021.html", - "https://snyk.io/vuln/SNYK-JAVA-ORGFUJIONWEBJARS-1074932", - "https://github.com/lodash/lodash/blob/ddfd9b11a0126db2302cb70ec9973b66baec0975/lodash.js%23L14851", - "https://github.com/advisories/GHSA-35jh-r3h4-6jhm", - "https://www.oracle.com/security-alerts/cpujul2022.html", - "https://www.oracle.com//security-alerts/cpujul2021.html", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARS-1074930", - "https://snyk.io/vuln/SNYK-JAVA-ORGWEBJARSBOWERGITHUBLODASH-1074931", - "https://nvd.nist.gov/vuln/detail/CVE-2021-23337", - "https://github.com/lodash/lodash/blob/ddfd9b11a0126db2302cb70ec9973b66baec0975/lodash.js#L14851" - ], - "impactPaths": [ - [ - { - "name": "froghome", - "version": "1.0.0" - }, - { - "name": "lodash", - "version": "4.17.0" - } - ] - ], - "jfrogResearchInformation": { - "severity": "Medium", - "summary": "Improper sanitization in the lodash template function leads to JavaScript code injection through the options argument.", - "details": "JavaScript-based applications (both frontend and backend) that use the [template function](https://lodash.com/docs/4.17.15#template) -`_.template([string=''], [options={}])` from the [lodash](https://lodash.com/) utility library and provide the `options` argument (specifically the `variable` option) from untrusted user input, are vulnerable to JavaScript code injection. This issue can be easily exploited, and an exploitation example is [publicly available](https://github.com/lodash/lodash/commit/3469357cff396a26c363f8c1b5a91dde28ba4b1c#diff-a561630bb56b82342bc66697aee2ad96efddcbc9d150665abd6fb7ecb7c0ab2fR22303) in the fix tests that was introduced in version 4.17.21 - \n```js\nlodash.template('', { variable: '){console.log(process.env)}; with(obj' })()\n```", - "severityReasons": [ - { - "name": "The prerequisites for exploiting the issue are extremely unlikely", - "description": "It is highly unlikely that a JS program will accept arbitrary remote input into the template's `options` argument", - "isPositive": true - }, - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "The attacker must find remote input that propagates into the `options` argument of a `template` call", - "isPositive": true - }, - { - "name": "The issue results in a severe impact (such as remote code execution)", - "description": "Leads to remote code execution through JS code injection" - }, - { - "name": "The issue has an exploit published", - "description": "Published exploit demonstrates arbitrary JS code execution" - } - ] - } - }, - { - "severity": "High", - "impactedPackageName": "lodash", - "impactedPackageVersion": "4.17.0", - "impactedPackageType": "npm", - "components": [ - { - "name": "lodash", - "version": "4.17.0", - "location": { - "file": "/Users/user/ejs-frog-demo/package.json" - } - } - ], - "summary": "Prototype pollution attack when using _.zipObjectDeep in lodash before 4.17.20.", - "applicable": "Not Applicable", - "fixedVersions": [ - "[4.17.19]" - ], - "cves": [ - { - "id": "CVE-2020-8203", - "cvssV2": "5.8", - "cvssV3": "7.4", - "applicability": { - "status": "Not Applicable", - "scannerDescription": "The scanner checks whether the vulnerable function `zipObjectDeep` is called with external input to its 1st (`props`) and 2nd (`values`) arguments, and the `Object.freeze()` remediation is not present." - } - } - ], - "issueId": "XRAY-114089", - "references": [ - "https://nvd.nist.gov/vuln/detail/CVE-2020-8203", - "https://www.oracle.com/security-alerts/cpuapr2022.html", - "https://hackerone.com/reports/864701", - "https://hackerone.com/reports/712065", - "https://github.com/advisories/GHSA-p6mc-m468-83gw", - "https://www.oracle.com//security-alerts/cpujul2021.html", - "https://github.com/lodash/lodash/issues/4744", - "https://www.oracle.com/security-alerts/cpuApr2021.html", - "https://github.com/github/advisory-database/pull/2884", - "https://www.oracle.com/security-alerts/cpujan2022.html", - "https://github.com/lodash/lodash/commit/c84fe82760fb2d3e03a63379b297a1cc1a2fce12", - "https://security.netapp.com/advisory/ntap-20200724-0006/", - "https://web.archive.org/web/20210914001339/https://github.com/lodash/lodash/issues/4744", - "https://www.oracle.com/security-alerts/cpuoct2021.html", - "https://github.com/lodash/lodash/issues/4874", - "https://github.com/lodash/lodash/wiki/Changelog#v41719" - ], - "impactPaths": [ - [ - { - "name": "froghome", - "version": "1.0.0" - }, - { - "name": "lodash", - "version": "4.17.0" - } - ] - ], - "jfrogResearchInformation": { - "severity": "Critical", - "summary": "Prototype pollution in lodash object merging and zipping functions leads to code injection.", - "details": "[lodash](https://lodash.com/) is a JavaScript library which provides utility functions for common programming tasks.\n\nJavaScript frontend and Node.js-based backend applications that merge or zip objects using the lodash functions `mergeWith`, `merge` and `zipObjectDeep` are vulnerable to [prototype pollution](https://medium.com/node-modules/what-is-prototype-pollution-and-why-is-it-such-a-big-deal-2dd8d89a93c) if one or more of the objects it receives as arguments are obtained from user input. \nAn attacker controlling this input given to the vulnerable functions can inject properties to JavaScript special objects such as [Object.prototype](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes) from which all JavaScript objects inherit properties and methods. Any change on `Object.prototype` properties will then propagate through the prototype chain inheritance to all of the objects in a JavaScript application. This in turn would allow an attacker to add new properties or modify existing properties which will have application specific implications that could lead to DoS (denial of service), authentication bypass, privilege escalation and even RCE (remote code execution) in [some cases](https://youtu.be/LUsiFV3dsK8?t=1152). \nAs an example for privilege escalation, consider a JavaScript application that has a `user` object which has a Boolean property of `user.isAdmin` which is used to decide which actions the user may take. If an attacker can modify or add the `isAdmin` property through prototype pollution, it can escalate the privileges of its own user to those of an admin. \nAs exploitation is usually application specific, successful exploitation is much more likely if an attacker have access to the JavaScript application code. As such, frontend applications are more vulnerable to this vulnerability than Node.js backend applications.", - "severityReasons": [ - { - "name": "The impact of exploiting the issue depends on the context of surrounding software. A severe impact such as RCE is not guaranteed.", - "isPositive": true - }, - { - "name": "The issue can be exploited by attackers over the network" - }, - { - "name": "The issue is trivial to exploit and does not require a published writeup or PoC" - } - ], - "remediation": "##### Deployment mitigations\n\nAs general guidelines against prototype pollution, first consider not merging objects originating from user input or using a Map structure instead of an object. If merging objects is needed, look into creating objects without a prototype with `Object.create(null)` or into freezing `Object.prototype` with `Object.freeze()`. Finally, it is always best to perform input validation with a a [JSON schema validator](https://github.com/ajv-validator/ajv), which could mitigate this issue entirely in many cases." - } + ] } ], - "licensesViolations": null, - "licenses": null, "operationalRiskViolations": null, "secrets": [ { "severity": "Medium", - "file": "server.js", - "startLine": 11, - "startColumn": 14, - "endLine": 11, - "endColumn": 24, - "snippet": "Sqc************", - "finding": "Secret keys were found", - "scannerDescription": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops\u0026tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n" - }, - { - "severity": "Medium", + "ruleId": "REQ.SECRET.KEYS", + "scannerShortDescription": "Scanner for REQ.SECRET.KEYS", + "scannerDescription": "The Scanner checks for REQ.SECRET.KEYS", "file": "fake-creds.txt", "startLine": 2, "startColumn": 1, "endLine": 2, "endColumn": 11, "snippet": "Sqc************", - "finding": "Secret keys were found", - "scannerDescription": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops\u0026tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n" + "finding": "Secret REQ.SECRET.KEYS were found", + "applicability": { + "status": "Active", + "scannerDescription": "active token" + } }, { "severity": "Medium", - "file": "fake-creds.txt", + "ruleId": "REQ.SECRET.KEYS", + "scannerShortDescription": "Scanner for REQ.SECRET.KEYS", + "scannerDescription": "The Scanner checks for REQ.SECRET.KEYS", + "file": "dir/server.js", "startLine": 3, "startColumn": 1, "endLine": 3, "endColumn": 11, "snippet": "gho************", - "finding": "Secret keys were found", - "scannerDescription": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops\u0026tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n" + "finding": "Secret REQ.SECRET.KEYS were found", + "applicability": { + "status": "Not a token" + } } ], + "iac": [ + { + "severity": "High", + "ruleId": "aws_cloudfront_tls_only", + "scannerShortDescription": "Scanner for aws_cloudfront_tls_only", + "scannerDescription": "The Scanner checks for aws_cloudfront_tls_only", + "file": "req_sw_terraform_aws_cloudfront_tls_only.tf", + "startLine": 2, + "startColumn": 1, + "endLine": 21, + "endColumn": 1, + "snippet": "viewer_protocol_policy...", + "finding": "Vulnerability aws_cloudfront_tls_only were found" + } + ], + "sast": null, "secretsViolations": [ { "severity": "Medium", + "watch": "watch", + "issueId": "sec-violation-1", + "ruleId": "REQ.SECRET.KEYS", + "scannerShortDescription": "Scanner for REQ.SECRET.KEYS", + "scannerDescription": "The Scanner checks for REQ.SECRET.KEYS", "file": "fake-creds.txt", + "startLine": 2, + "startColumn": 1, + "endLine": 2, + "endColumn": 11, + "snippet": "Sqc************", + "finding": "Secret REQ.SECRET.KEYS were found", + "applicability": { + "status": "Active", + "scannerDescription": "active token" + } + }, + { + "severity": "Medium", + "watch": "watch", + "issueId": "sec-violation-2", + "ruleId": "REQ.SECRET.KEYS", + "scannerShortDescription": "Scanner for REQ.SECRET.KEYS", + "scannerDescription": "The Scanner checks for REQ.SECRET.KEYS", + "file": "dir/server.js", "startLine": 3, "startColumn": 1, "endLine": 3, "endColumn": 11, "snippet": "gho************", - "finding": "Secret keys were found", - "scannerDescription": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops\u0026tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n" + "finding": "Secret REQ.SECRET.KEYS were found", + "applicability": { + "status": "Not a token" + } } ], - "iac": null, "iacViolations": null, - "sast": [ + "sastViolations": [ { "severity": "High", + "watch": "watch", + "issueId": "sast-violation-2", + "ruleId": "js-template-injection", + "cwe": [ + "73" + ], + "scannerShortDescription": "Scanner for js-template-injection", + "scannerDescription": "The Scanner checks for js-template-injection", "file": "server.js", "startLine": 26, "startColumn": 28, "endLine": 26, "endColumn": 37, "snippet": "req.query", - "finding": "Template Object Injection", - "scannerDescription": "\n### Overview\nTemplate Object Injection (TOI) is a vulnerability that can occur in\nweb applications that use template engines to render dynamic content.\nTemplate engines are commonly used to generate HTML pages, emails, or\nother types of documents that include variable data. TOI happens when\nuntrusted user input is included as part of the template rendering\nprocess, and the template engine evaluates the input as a code\nexpression, leading to potential code injection or data tampering\nattacks. To prevent TOI vulnerabilities, it's important to sanitize and\nvalidate all user input that is used as part of the template rendering\nprocess.\n\n### Query operation\nIn this query we look for user inputs that flow directly to a\nrequest render.\n\n### Vulnerable example\n```javascript\nvar app = require('express')();\napp.set('view engine', 'hbs');\n\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n res.render('template', bodyParameter);\n});\n```\nIn this example, a user-provided data is injected directly into the\n`render` command, leading to potential code injection or data\ntampering attacks.\n\n### Remediation\n```diff\n+ const sanitizeHtml = require('sanitize-html');\nvar app = require('express')();\napp.set('view engine', 'hbs');\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n\n- res.render('template', bodyParameter);\n+ res.render('template', sanitizeHtml(bodyParameter));\n});\nUsing `sanitize-html`, the user-provided data is sanitized, before\nrendering to the response.\n```\n", + "finding": "Vulnerability js-template-injection were found", "codeFlow": [ [ { "file": "server.js", - "startLine": 21, - "startColumn": 23, - "endLine": 21, - "endColumn": 26, - "snippet": "req" - }, - { - "file": "server.js", - "startLine": 26, + "startLine": 27, "startColumn": 28, "endLine": 26, "endColumn": 31, @@ -1439,78 +583,30 @@ }, { "severity": "Low", - "file": "server.js", - "startLine": 8, - "startColumn": 11, - "endLine": 8, - "endColumn": 20, - "snippet": "express()", - "finding": "Express Not Using Helmet", - "scannerDescription": "\n### Overview\nHelmet library should be used when using Express in order to properly configure\nHTTP header settings to mitigate a range of well-known vulnerabilities.\n\n### Remediation\n```javascript\nconst helmet = require(\"helmet\");\nconst app = express()\n\napp.use(helmet())\n```\n\n### References\n[Best practices for Express](https://expressjs.com/en/advanced/best-practice-security.html)\n" - }, - { - "severity": "Low", - "file": "public/js/bootstrap.js", + "watch": "watch", + "issueId": "sast-violation-1", + "ruleId": "js-insecure-random", + "cwe": [ + "338" + ], + "scannerShortDescription": "Scanner for js-insecure-random", + "scannerDescription": "The Scanner checks for js-insecure-random", + "file": "public/js/bootstrap.bundle.js", "startLine": 136, "startColumn": 22, "endLine": 136, "endColumn": 35, "snippet": "Math.random()", - "finding": "Use of Insecure Random", - "scannerDescription": "\n### Overview\nA use of insecure random vulnerability is a type of security flaw that is\ncaused by the use of inadequate or predictable random numbers in a program\nor system. Random numbers are used in many security-related applications,\nsuch as generating cryptographic keys and if the numbers are not truly\nrandom, an attacker may be able to predict or recreate them, potentially\ncompromising the security of the system.\n\n### Vulnerable example\n```javascript\nvar randomNum = Math.random();\n```\n`Math.random` is not secured, as it creates predictable random numbers.\n\n### Remediation\n```diff\nvar randomNum = crypto.randomInt(0, 100)\n```\n`crypto.randomInt` is secured, and creates much less predictable random\nnumbers.\n" - }, - { - "severity": "Low", - "file": "public/js/bootstrap.bundle.js", - "startLine": 135, - "startColumn": 22, - "endLine": 135, - "endColumn": 35, - "snippet": "Math.random()", - "finding": "Use of Insecure Random", - "scannerDescription": "\n### Overview\nA use of insecure random vulnerability is a type of security flaw that is\ncaused by the use of inadequate or predictable random numbers in a program\nor system. Random numbers are used in many security-related applications,\nsuch as generating cryptographic keys and if the numbers are not truly\nrandom, an attacker may be able to predict or recreate them, potentially\ncompromising the security of the system.\n\n### Vulnerable example\n```javascript\nvar randomNum = Math.random();\n```\n`Math.random` is not secured, as it creates predictable random numbers.\n\n### Remediation\n```diff\nvar randomNum = crypto.randomInt(0, 100)\n```\n`crypto.randomInt` is secured, and creates much less predictable random\nnumbers.\n" - } - ], - "sastViolations": [ - { - "severity": "High", - "file": "server.js", - "startLine": 26, - "startColumn": 28, - "endLine": 26, - "endColumn": 37, - "snippet": "req.query", - "finding": "Template Object Injection", - "scannerDescription": "\n### Overview\nTemplate Object Injection (TOI) is a vulnerability that can occur in\nweb applications that use template engines to render dynamic content.\nTemplate engines are commonly used to generate HTML pages, emails, or\nother types of documents that include variable data. TOI happens when\nuntrusted user input is included as part of the template rendering\nprocess, and the template engine evaluates the input as a code\nexpression, leading to potential code injection or data tampering\nattacks. To prevent TOI vulnerabilities, it's important to sanitize and\nvalidate all user input that is used as part of the template rendering\nprocess.\n\n### Query operation\nIn this query we look for user inputs that flow directly to a\nrequest render.\n\n### Vulnerable example\n```javascript\nvar app = require('express')();\napp.set('view engine', 'hbs');\n\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n res.render('template', bodyParameter);\n});\n```\nIn this example, a user-provided data is injected directly into the\n`render` command, leading to potential code injection or data\ntampering attacks.\n\n### Remediation\n```diff\n+ const sanitizeHtml = require('sanitize-html');\nvar app = require('express')();\napp.set('view engine', 'hbs');\napp.use(require('body-parser').json());\napp.use(require('body-parser').urlencoded({ extended: false }));\napp.post('/path', function(req, res) {\n var bodyParameter = req.body.bodyParameter;\n var queryParameter = req.query.queryParameter;\n\n- res.render('template', bodyParameter);\n+ res.render('template', sanitizeHtml(bodyParameter));\n});\nUsing `sanitize-html`, the user-provided data is sanitized, before\nrendering to the response.\n```\n", - "codeFlow": [ - [ - { - "file": "server.js", - "startLine": 21, - "startColumn": 23, - "endLine": 21, - "endColumn": 26, - "snippet": "req" - }, - { - "file": "server.js", - "startLine": 26, - "startColumn": 28, - "endLine": 26, - "endColumn": 31, - "snippet": "req" - }, - { - "file": "server.js", - "startLine": 26, - "startColumn": 28, - "endLine": 26, - "endColumn": 37, - "snippet": "req.query" - } - ] - ] + "finding": "Vulnerability js-insecure-random were found" } ], - "errors": null -} + "errors": null, + "scansStatus": { + "scaScanStatusCode": 0, + "sastScanStatusCode": 0, + "iacScanStatusCode": 0, + "secretsScanStatusCode": 0, + "ContextualAnalysisScanStatusCode": 0 + }, + "multiScanId": "7d5e4733-3f93-11ef-8147-e610d09d7daa" +} \ No newline at end of file diff --git a/tests/testdata/output/audit/audit_summary.json b/tests/testdata/output/audit/audit_summary.json index 3d667461..69baab23 100644 --- a/tests/testdata/output/audit/audit_summary.json +++ b/tests/testdata/output/audit/audit_summary.json @@ -1,74 +1,75 @@ { - "scans": [ - { - "target": "/Users/user/ejs-frog-demo", - "vulnerabilities": { - "sca": { - "scan_ids": [ - "711851ce-68c4-4dfd-7afb-c29737ebcb96" - ], - "security": { - "Critical": { - "Applicable": 1, - "Not Applicable": 2 - }, - "High": { - "Not Applicable": 2 - }, - "Medium": { - "Not Applicable": 3, - "Not Covered": 3 - }, - "Unknown": { - "Not Covered": 1 - } - } - }, - "iac": {}, - "secrets": { - "Medium": { - "": 3 - } - }, - "sast": { - "High": { - "": 1 - }, - "Low": { - "": 3 - } - } + "scans": [ + { + "target": "/Users/user/project-with-issues", + "vulnerabilities": { + "sca": { + "scan_ids": [ + "711851ce-68c4-4dfd-7afb-c29737ebcb96" + ], + "security": { + "High": { + "Undetermined": 1 }, - "violations": { - "watches": [ - "Security_watch_1" - ], - "sca": { - "scan_ids": [ - "711851ce-68c4-4dfd-7afb-c29737ebcb96" - ], - "security": { - "Critical": { - "Applicable": 1, - "Not Applicable": 2 - }, - "High": { - "Not Applicable": 2 - } - } - }, - "iac": {}, - "secrets": { - "Medium": { - "": 1 - } - }, - "sast": { - "High": { - "": 1 - } - } + "Medium": { + "Applicable": 1, + "Undetermined": 1 + }, + "Unknown": { + "Applicable": 1 + } + } + }, + "iac": { + "High": { + "": 1 + } + }, + "secrets": { + "Medium": { + "": 2 + } + }, + "sast": {} + }, + "violations": { + "watches": [ + "security-watch", + "license-watch" + ], + "sca": { + "scan_ids": [ + "711851ce-68c4-4dfd-7afb-c29737ebcb96" + ], + "security": { + "Medium": { + "Undetermined": 1 + }, + "Unknown": { + "Applicable": 1 + } + }, + "license": { + "High": { + "": 1 } + } + }, + "iac": {}, + "secrets": { + "Medium": { + "": 2 + } + }, + "sast": { + "High": { + "": 1 + }, + "Low": { + "": 1 + } } - ] + } + } + ] } \ No newline at end of file diff --git a/tests/testdata/output/dockerscan/docker_results.json b/tests/testdata/output/dockerscan/docker_results.json deleted file mode 100644 index 822d7670..00000000 --- a/tests/testdata/output/dockerscan/docker_results.json +++ /dev/null @@ -1,1124 +0,0 @@ -{ - "xray_version": "3.104.8", - "jas_entitled": true, - "command_type": "docker_image", - "targets": [ - { - "target": "/var/folders/xv/th4cksxn7jv9wjrdnn1h4tj00000gq/T/jfrog.cli.temp.-1726210535-1985298017/image.tar", - "name": "platform.jfrog.io/swamp-docker/swamp:latest", - "technology": "oci", - "sca_scans": { - "xray_scan": [ - { - "scan_id": "27da9106-88ea-416b-799b-bc7d15783473", - "vulnerabilities": [ - { - "cves": [ - { - "cve": "CVE-2024-6119" - } - ], - "summary": "Issue summary: Applications performing certificate name checks (e.g., TLS\nclients checking server certificates) may attempt to read an invalid memory\naddress resulting in abnormal termination of the application process.\n\nImpact summary: Abnormal termination of an application can a cause a denial of\nservice.\n\nApplications performing certificate name checks (e.g., TLS clients checking\nserver certificates) may attempt to read an invalid memory address when\ncomparing the expected name with an `otherName` subject alternative name of an\nX.509 certificate. This may result in an exception that terminates the\napplication program.\n\nNote that basic certificate chain validation (signatures, dates, ...) is not\naffected, the denial of service can occur only when the application also\nspecifies an expected DNS name, Email address or IP address.\n\nTLS servers rarely solicit client certificates, and even when they do, they\ngenerally don't perform a name check against a reference identifier (expected\nidentity), but rather extract the presented identity after checking the\ncertificate chain. So TLS servers are generally not affected and the severity\nof the issue is Moderate.\n\nThe FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.", - "severity": "Unknown", - "components": { - "deb://debian:bookworm:libssl3:3.0.13-1~deb12u1": { - "impact_paths": [ - [ - { - "component_id": "docker://platform.jfrog.io/swamp-docker/swamp:latest" - }, - { - "component_id": "generic://sha256:f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595/sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar", - "full_path": "sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar" - }, - { - "component_id": "deb://debian:bookworm:libssl3:3.0.13-1~deb12u1", - "full_path": "libssl3:3.0.13-1~deb12u1" - } - ] - ] - }, - "deb://debian:bookworm:openssl:3.0.13-1~deb12u1": { - "fixed_versions": [ - "[3.0.14-1~deb12u2]" - ], - "impact_paths": [ - [ - { - "component_id": "docker://platform.jfrog.io/swamp-docker/swamp:latest" - }, - { - "component_id": "generic://sha256:f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595/sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar", - "full_path": "sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar" - }, - { - "component_id": "deb://debian:bookworm:openssl:3.0.13-1~deb12u1", - "full_path": "openssl:3.0.13-1~deb12u1" - } - ] - ] - } - }, - "issue_id": "XRAY-632747", - "references": [ - "https://openssl-library.org/news/secadv/20240903.txt", - "https://github.com/openssl/openssl/commit/621f3729831b05ee828a3203eddb621d014ff2b2", - "https://github.com/openssl/openssl/commit/05f360d9e849a1b277db628f1f13083a7f8dd04f", - "https://security-tracker.debian.org/tracker/CVE-2024-6119", - "https://github.com/openssl/openssl/commit/7dfcee2cd2a63b2c64b9b4b0850be64cb695b0a0", - "https://github.com/openssl/openssl/commit/06d1dc3fa96a2ba5a3e22735a033012aadc9f0d6" - ], - "extended_information": { - "short_description": "Out of bounds read in OpenSSL clients can lead to denial of service when using non-default TLS verification options and connecting to malicious TLS servers", - "jfrog_research_severity": "Medium", - "jfrog_research_severity_reasons": [ - { - "name": "The issue has an exploit published", - "description": "The fix commit contains PoC certificates that trigger the denial of service issue" - }, - { - "name": "The prerequisites for exploiting the issue are extremely unlikely", - "description": "The attacker must make the victim client connect to their malicious TLS server, in order to serve the malformed TLS certificate. The victim client must use OpenSSL and must enable non-default certificate verification options, either -\n\n* DNS verification - by using `X509_VERIFY_PARAM_set1_host` or `X509_check_host`\n* Email verification - by using ` X509_VERIFY_PARAM_set1_email` or `X509_check_email`", - "is_positive": true - }, - { - "name": "The issue cannot result in a severe impact (such as remote code execution)", - "description": "Denial of service of a TLS clients only. This out of bounds read cannot lead to data disclosure.", - "is_positive": true - } - ] - } - }, - { - "cves": [ - { - "cve": "CVE-2024-38428", - "cvss_v3_score": "9.1", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N", - "cwe": [ - "CWE-436" - ], - "cwe_details": { - "CWE-436": { - "name": "Interpretation Conflict", - "description": "Product A handles inputs or steps differently than Product B, which causes A to perform incorrect actions based on its perception of B's state." - } - } - } - ], - "summary": "url.c in GNU Wget through 1.24.5 mishandles semicolons in the userinfo subcomponent of a URI, and thus there may be insecure behavior in which data that was supposed to be in the userinfo subcomponent is misinterpreted to be part of the host subcomponent.", - "severity": "Critical", - "components": { - "deb://debian:bookworm:wget:1.21.3-1+b1": { - "impact_paths": [ - [ - { - "component_id": "docker://platform.jfrog.io/swamp-docker/swamp:latest" - }, - { - "component_id": "generic://sha256:f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595/sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar", - "full_path": "sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar" - }, - { - "component_id": "deb://debian:bookworm:wget:1.21.3-1+b1", - "full_path": "wget:1.21.3-1+b1" - } - ] - ] - } - }, - "issue_id": "XRAY-606103", - "references": [ - "https://git.savannah.gnu.org/cgit/wget.git/commit/?id=ed0c7c7e0e8f7298352646b2fd6e06a11e242ace", - "https://lists.gnu.org/archive/html/bug-wget/2024-06/msg00005.html", - "https://security-tracker.debian.org/tracker/CVE-2024-38428" - ] - }, - { - "summary": "Malicious package cors.js for Node.js", - "severity": "Critical", - "components": { - "npm://cors.js:0.0.1-security": { - "impact_paths": [ - [ - { - "component_id": "docker://platform.jfrog.io/swamp-docker/swamp:latest" - }, - { - "component_id": "generic://sha256:ab1c0a95b2970fb44e2a4046c5c00f37a5b061e74d72b254a8975beb7d09f74f/sha256__ab1c0a95b2970fb44e2a4046c5c00f37a5b061e74d72b254a8975beb7d09f74f.tar", - "full_path": "sha256__ab1c0a95b2970fb44e2a4046c5c00f37a5b061e74d72b254a8975beb7d09f74f.tar" - }, - { - "component_id": "npm://cors.js:0.0.1-security", - "full_path": "usr/src/app/node_modules/cors.js/package.json" - } - ] - ] - } - }, - "issue_id": "XRAY-264729", - "references": [ - "https://registry.npmjs.com" - ], - "extended_information": { - "short_description": "Malicious package cors.js for Node.js", - "full_description": "The package cors.js for Node.js contains malicious code that installs a persistent connectback shell. The package is typosquatting the popular `cors` package. When installed, the package opens a connectback shell to the hardcoded host `107.175.32.229` on TCP port 56173. The malicious payload achieves persistency by installing a cron job that repeats every 10 seconds - `*/10 * * * * *`", - "jfrog_research_severity": "Critical", - "remediation": "As with any malware, the malicious package must be completely removed, and steps must be taken care to remediate the damage that was done by the malicious package -\n\n##### Removing the malicious package\n\nRun `npm uninstall cors.js`\n\n##### Refreshing stolen credentials\n\nMany malicious packages steal stored user credentials, focusing on the following -\n\n* [Browser autocomplete](https://jfrog.com/blog/malicious-pypi-packages-stealing-credit-cards-injecting-code/) data, such as saved passwords and credit cards\n* [Environment variables](https://jfrog.com/blog/malicious-npm-packages-are-after-your-discord-tokens-17-new-packages-disclosed/) passed to the malicious code\n* [Stored Discord tokens](https://jfrog.com/blog/malicious-npm-packages-are-after-your-discord-tokens-17-new-packages-disclosed/)\n* AWS / GitHub credentials stored in cleartext files\n\nIt is highly recommended to change or revoke data that is stored in the infected machine at those locations\n\n##### Stopping malicious processes\n\nMany malicious packages start malicious processes such as [connectback shells](https://jfrog.com/blog/jfrog-discloses-3-remote-access-trojans-in-pypi/) or crypto-miners. Search for any unfamiliar processes that consume a large amount of CPU or a large amount of network traffic, and stop them. On Windows, this can be facilitated with [Sysinternals Process Explorer](https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer).\n\n##### Removing installed backdoors\n\nMany malicious packages install themselves as a [persistent backdoor](https://jfrog.com/blog/npm-supply-chain-attack-targets-german-based-companies/), in order to guarantee the malicious code survives a reboot. Search for any unfamiliar binaries set to be run on startup, and remove them. On Windows, this can be facilitated with [Sysinternals Autoruns](https://docs.microsoft.com/en-us/sysinternals/downloads/autoruns).\n\n##### Defining an Xray policy that blocks downloads of Artifacts with malicious packages\n\nIt is possible to [create an Xray policy](https://www.jfrog.com/confluence/display/JFROG/Creating+Xray+Policies+and+Rules) that will not allow artifacts with identified malicious packages to be downloaded from Artifactory. To create such a policy, add a new `Security` policy and set `Minimal Severity` to `Critical`. Under `Automatic Actions` check the `Block Download` action.\n\n##### Contacting the JFrog Security Research team for additional information\n\nOptionally, if you are unsure of the full impact of the malicious package and wish to get more details, the JFrog Security Research team can help you assess the potential damage from the installed malicious package.\n\nPlease contact us at research@jfrog.com with details of the affected artifact and the name of the identified malicious package." - } - }, - { - "cves": [ - { - "cve": "CVE-2024-45490", - "cvss_v3_score": "9.8", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", - "cwe": [ - "CWE-611" - ], - "cwe_details": { - "CWE-611": { - "name": "Improper Restriction of XML External Entity Reference", - "description": "The product processes an XML document that can contain XML entities with URIs that resolve to documents outside of the intended sphere of control, causing the product to embed incorrect documents into its output." - } - } - } - ], - "summary": "An issue was discovered in libexpat before 2.6.3. xmlparse.c does not reject a negative length for XML_ParseBuffer.", - "severity": "Critical", - "components": { - "deb://debian:bookworm:libexpat1:2.5.0-1": { - "impact_paths": [ - [ - { - "component_id": "docker://platform.jfrog.io/swamp-docker/swamp:latest" - }, - { - "component_id": "generic://sha256:20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1/sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar", - "full_path": "sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar" - }, - { - "component_id": "deb://debian:bookworm:libexpat1:2.5.0-1", - "full_path": "libexpat1:2.5.0-1" - } - ] - ] - } - }, - "issue_id": "XRAY-632613", - "references": [ - "https://github.com/libexpat/libexpat/issues/887", - "https://security-tracker.debian.org/tracker/CVE-2024-45490", - "https://github.com/libexpat/libexpat/pull/890" - ] - }, - { - "cves": [ - { - "cve": "CVE-2024-45492", - "cvss_v3_score": "9.8", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", - "cwe": [ - "CWE-190" - ], - "cwe_details": { - "CWE-190": { - "name": "Integer Overflow or Wraparound", - "description": "The product performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control.", - "categories": [ - { - "category": "2023 CWE Top 25", - "rank": "14" - } - ] - } - } - } - ], - "summary": "An issue was discovered in libexpat before 2.6.3. nextScaffoldPart in xmlparse.c can have an integer overflow for m_groupSize on 32-bit platforms (where UINT_MAX equals SIZE_MAX).", - "severity": "Critical", - "components": { - "deb://debian:bookworm:libexpat1:2.5.0-1": { - "impact_paths": [ - [ - { - "component_id": "docker://platform.jfrog.io/swamp-docker/swamp:latest" - }, - { - "component_id": "generic://sha256:20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1/sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar", - "full_path": "sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar" - }, - { - "component_id": "deb://debian:bookworm:libexpat1:2.5.0-1", - "full_path": "libexpat1:2.5.0-1" - } - ] - ] - } - }, - "issue_id": "XRAY-632612", - "references": [ - "https://github.com/libexpat/libexpat/issues/889", - "https://security-tracker.debian.org/tracker/CVE-2024-45492", - "https://github.com/libexpat/libexpat/pull/892" - ] - }, - { - "cves": [ - { - "cve": "CVE-2023-51767", - "cvss_v3_score": "7.0", - "cvss_v3_vector": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H", - "cwe": [ - "NVD-CWE-Other" - ] - } - ], - "summary": "OpenSSH through 9.6, when common types of DRAM are used, might allow row hammer attacks (for authentication bypass) because the integer value of authenticated in mm_answer_authpassword does not resist flips of a single bit. NOTE: this is applicable to a certain threat model of attacker-victim co-location in which the attacker has user privileges.", - "severity": "Low", - "components": { - "deb://debian:bookworm:openssh-client:1:9.2p1-2+deb12u3": { - "impact_paths": [ - [ - { - "component_id": "docker://platform.jfrog.io/swamp-docker/swamp:latest" - }, - { - "component_id": "generic://sha256:20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1/sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar", - "full_path": "sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar" - }, - { - "component_id": "deb://debian:bookworm:openssh-client:1:9.2p1-2+deb12u3", - "full_path": "openssh-client:1:9.2p1-2+deb12u3" - } - ] - ] - } - }, - "issue_id": "XRAY-585612", - "references": [ - "https://arxiv.org/abs/2309.02545", - "https://github.com/openssh/openssh-portable/blob/8241b9c0529228b4b86d88b1a6076fb9f97e4a99/monitor.c#L878", - "https://github.com/openssh/openssh-portable/blob/8241b9c0529228b4b86d88b1a6076fb9f97e4a99/auth-passwd.c#L77", - "https://bugzilla.redhat.com/show_bug.cgi?id=2255850", - "https://security-tracker.debian.org/tracker/CVE-2023-51767", - "https://ubuntu.com/security/CVE-2023-51767", - "https://security.netapp.com/advisory/ntap-20240125-0006/", - "https://access.redhat.com/security/cve/CVE-2023-51767" - ], - "extended_information": { - "short_description": "The RowHammer fault injection attack can theoretically lead to local authentication bypass in OpenSSH.", - "full_description": "[OpenSSH](https://www.openssh.com/) is a popular open-source implementation of the SSH (Secure Shell) protocol, providing encrypted communication over a network.\nIt was discovered that the OpenSSH authentication logic can be susceptible in some cases to a side-channel fault injection attack. The attack can theoretically be carried out by a local attacker which eventually bypass OpenSSH authentication mechanism.\n\nThis vulnerability currently lacks widely known published exploits, and its exploitation is considered highly complex. The intricacies of the attack, combined with the absence of well-documented exploits, contribute to the difficulty in achieving successful exploitation. Furthermore, it's essential to note that the susceptibility to this vulnerability is hardware-dependent, and the success of an attack relies on probabilities associated with the specific hardware configuration. \n\nThe vulnerability is theoretically exploitable by several different ways, the only two published ways are:\n\nIn the OpenSSH function `mm_answer_authpassword()`, a stack variable `authenticated`, is assigned to the value of the function `auth_password()` which returns 1/0 and then returned. If the value of `authenticated` is 1, the SSH connection will be established. Since `authenticated` is stored on the stack, therefore in DRAM, a local attacker could flip this 32-bit integer least significant bit, thus, bypass authentication.\n\nAnother possible exploit is the `result` stack variable in `auth_password()` function. It is initialized to 0 and set to 1 if the password is correct. \nSimilarly to the previous method, this attack requires a single bit flip of the `result` variable in order for the function to return 1 and bypass the authentication.\n\nAttackers can trigger the vulnerability via a RowHammer fault injection. The Rowhammer bug is a hardware reliability issue in which an attacker repeatedly accesses (hammers) DRAM cells to cause unauthorized changes in physically adjacent memory locations.\nSimply put:\n\n* A specific register value(`authenticated`/`result` value) is pushed onto the stack during program execution. \n* The stack, where the register value is stored, is identified to be located in a memory row susceptible to bit flips (flippable row) due to the RowHammer vulnerability in DRAM.\n* The attacker performs a series of rapid and repeated memory accesses to the adjacent rows of the flippable row in the DRAM. This repeated access exploits the RowHammer vulnerability, inducing bit flips in the targeted flippable row.\n* Due to the RowHammer effect, bit flips occur in the flippable row, potentially corrupting the data stored there.\n* After inducing bit flips in the flippable row, the attacker manipulates the program's control flow to pop the corrupted value from the stack into a register.\n* The register now holds a value that has been corrupted through the RowHammer attack. Now the `authenticated`/`result` variables hold this corrupted value thus it can lead to authentication bypass, as it may impact the control flow in a way advantageous to the attacker.", - "jfrog_research_severity": "Low", - "jfrog_research_severity_reasons": [ - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "The vulnerability depends on the OS and hardware. It was only evaluated in one test environment, therefore results for other conditions might differ. The attacker must be extremely familiar with the details of the exploited system (ex. know the exact hardware which is running the OS).", - "is_positive": true - }, - { - "name": "The issue can only be exploited by an attacker that can execute code on the vulnerable machine (excluding exceedingly rare circumstances)", - "is_positive": true - }, - { - "name": "No high-impact exploit or technical writeup were published, and exploitation of the issue with high impact is either non-trivial or completely unproven", - "description": "Exploitation is extremely non-trivial (even theoretically), no public exploits have been published.", - "is_positive": true - }, - { - "name": "The reported CVSS was either wrongly calculated, downgraded by other vendors, or does not reflect the vulnerability's impact", - "description": "The vulnerability's attack complexity is significantly higher than what the CVSS represents.", - "is_positive": true - } - ] - } - }, - { - "cves": [ - { - "cve": "CVE-2011-3374", - "cvss_v2_score": "4.3", - "cvss_v2_vector": "CVSS:2.0/AV:N/AC:M/Au:N/C:N/I:P/A:N", - "cvss_v3_score": "3.7", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N", - "cwe": [ - "CWE-347" - ], - "cwe_details": { - "CWE-347": { - "name": "Improper Verification of Cryptographic Signature", - "description": "The product does not verify, or incorrectly verifies, the cryptographic signature for data." - } - } - } - ], - "summary": "It was found that apt-key in apt, all versions, do not correctly validate gpg keys with the master keyring, leading to a potential man-in-the-middle attack.", - "severity": "Low", - "components": { - "deb://debian:bookworm:apt:2.6.1": { - "impact_paths": [ - [ - { - "component_id": "docker://platform.jfrog.io/swamp-docker/swamp:latest" - }, - { - "component_id": "generic://sha256:cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e/sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar", - "full_path": "sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar" - }, - { - "component_id": "deb://debian:bookworm:apt:2.6.1", - "full_path": "apt:2.6.1" - } - ] - ] - }, - "deb://debian:bookworm:libapt-pkg6.0:2.6.1": { - "impact_paths": [ - [ - { - "component_id": "docker://platform.jfrog.io/swamp-docker/swamp:latest" - }, - { - "component_id": "generic://sha256:cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e/sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar", - "full_path": "sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar" - }, - { - "component_id": "deb://debian:bookworm:libapt-pkg6.0:2.6.1", - "full_path": "libapt-pkg6.0:2.6.1" - } - ] - ] - } - }, - "issue_id": "XRAY-34417", - "references": [ - "https://people.canonical.com/~ubuntu-security/cve/2011/CVE-2011-3374.html", - "https://seclists.org/fulldisclosure/2011/Sep/221", - "https://ubuntu.com/security/CVE-2011-3374", - "https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=642480", - "https://access.redhat.com/security/cve/cve-2011-3374", - "https://snyk.io/vuln/SNYK-LINUX-APT-116518", - "https://security-tracker.debian.org/tracker/CVE-2011-3374" - ], - "extended_information": { - "short_description": "Improper signature validation in apt-key may enable Man-in-the-Middle attacks and result in code execution.", - "full_description": "`apt-key` is [`apt`](https://github.com/Debian/apt)'s key management utility, and is used to manage the keys that are used by `apt` to authenticate packages.\n\nA vulnerability in `apt-key`'s `net-update` function exists, in which [`GPG`](https://www.gnupg.org/) keys, that are used for signing packages and validating their authenticity, aren't validated correctly. The `net-update` function pulls the signing keys that should be added from an insecure location (`http://...`), exposing it to a Man-in-the-Middle attack in which malicious signing keys could be added to the system's keyring. This issue happens due to a vulnerability in the `add_keys_with_veirfy_against_master_keyring()` function, which allows adding signing keys without proper signature validation. \n\nThis vulnerability then potentially allows a malicious actor to perform a Man-in-the-Middle attack on a target, by making it validate malicious packages that were signed with the `GPG` signing key used by the attacker. Effectively, this means that `apt` can be duped to install malicious services and daemons with root privileges.\n\nThe conditions for this vulnerability to be applicable:\n \n1. A valid URI should be configured in `ARCHIVE_KEYRING_URI` variable in the file `/usr/bin/apt-key`. This is the URI that an attacker would need to target in a Man In The Middle attack.\n2. The command `apt-key net-update` should be executed on the affected system, or alternatively `apt.auth.net_update()` function from [python-apt](https://pypi.org/project/python-apt/) Python module should be called. This is for the malicious keys download.\n3. After the execution of `apt-key net-update`, APT packages should be installed or updated on the machine.\n\nDo note that `apt-key` is **deprecated** and shouldn't be used, and in most Debian versions `ARCHIVE_KEYRING_URI` is not defined, making this vulnerability unexploitable in most Debian systems.", - "jfrog_research_severity": "High", - "jfrog_research_severity_reasons": [ - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "The conditions for this vulnerability to be applicable:\n \n1. A valid URI should be configured in `ARCHIVE_KEYRING_URI` variable in the file `/usr/bin/apt-key`. This is the URI that an attacker would need to target in a Man-in-the-Middle attack.\n2. The command `apt-key net-update` should be executed on the affected system, or alternatively `apt.auth.net_update()` function from the python-apt Python module should be called. This is for the malicious keys download.\n3. After the execution of `apt-key net-update`, APT packages should be installed or updated on the machine.", - "is_positive": true - }, - { - "name": "The issue can be exploited by attackers over the network", - "description": "This vulnerability is remotely exploitable when the applicability conditions apply." - }, - { - "name": "The issue results in a severe impact (such as remote code execution)", - "description": "Remote code execution is possible when the applicability conditions apply." - }, - { - "name": "The issue has an exploit published", - "description": "The reporter of this issue has provided a GPG key that can be used for an actual attack, as well as a simple PoC example." - } - ], - "remediation": "##### Deployment mitigations\n\n* Dot not execute `apt-key` command, as it is deprecated.\n* Remove the URI configured in `ARCHIVE_KEYRING_URI` variable in the file `/usr/bin/apt-key`." - } - }, - { - "cves": [ - { - "cve": "CVE-2024-4741" - } - ], - "summary": "CVE-2024-4741", - "severity": "Unknown", - "components": { - "deb://debian:bookworm:libssl3:3.0.13-1~deb12u1": { - "impact_paths": [ - [ - { - "component_id": "docker://platform.jfrog.io/swamp-docker/swamp:latest" - }, - { - "component_id": "generic://sha256:f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595/sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar", - "full_path": "sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar" - }, - { - "component_id": "deb://debian:bookworm:libssl3:3.0.13-1~deb12u1", - "full_path": "libssl3:3.0.13-1~deb12u1" - } - ] - ] - }, - "deb://debian:bookworm:openssl:3.0.13-1~deb12u1": { - "fixed_versions": [ - "[3.0.14-1~deb12u1]" - ], - "impact_paths": [ - [ - { - "component_id": "docker://platform.jfrog.io/swamp-docker/swamp:latest" - }, - { - "component_id": "generic://sha256:f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595/sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar", - "full_path": "sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar" - }, - { - "component_id": "deb://debian:bookworm:openssl:3.0.13-1~deb12u1", - "full_path": "openssl:3.0.13-1~deb12u1" - } - ] - ] - } - }, - "issue_id": "XRAY-603657", - "references": [ - "https://security-tracker.debian.org/tracker/CVE-2024-4741" - ] - } - ], - "violations": [ - { - "cves": [ - { - "cve": "CVE-2024-38428", - "cvss_v3_score": "9.1", - "cvss_v3_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N", - "cwe": [ - "CWE-436" - ], - "cwe_details": { - "CWE-436": { - "name": "Interpretation Conflict", - "description": "Product A handles inputs or steps differently than Product B, which causes A to perform incorrect actions based on its perception of B's state." - } - } - } - ], - "summary": "url.c in GNU Wget through 1.24.5 mishandles semicolons in the userinfo subcomponent of a URI, and thus there may be insecure behavior in which data that was supposed to be in the userinfo subcomponent is misinterpreted to be part of the host subcomponent.", - "severity": "Critical", - "watch_name": "Security_watch_2", - "type": "security", - "components": { - "deb://debian:bookworm:wget:1.21.3-1+b1": { - "impact_paths": [ - [ - { - "component_id": "docker://platform.jfrog.io/swamp-docker/swamp:latest" - }, - { - "component_id": "generic://sha256:f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595/sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar", - "full_path": "sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar" - }, - { - "component_id": "deb://debian:bookworm:wget:1.21.3-1+b1", - "full_path": "wget:1.21.3-1+b1" - } - ] - ] - } - }, - "issue_id": "XRAY-606103", - "references": [ - "https://git.savannah.gnu.org/cgit/wget.git/commit/?id=ed0c7c7e0e8f7298352646b2fd6e06a11e242ace", - "https://lists.gnu.org/archive/html/bug-wget/2024-06/msg00005.html", - "https://security-tracker.debian.org/tracker/CVE-2024-38428" - ] - } - ], - "component_id": "docker://platform.jfrog.io/swamp-docker/swamp:latest", - "package_type": "oci", - "status": "completed" - } - ] - }, - "jas_scans": { - "contextual_analysis": [ - { - "tool": { - "driver": { - "informationUri": "https://jfrog.com/help/r/jfrog-security-documentation/jfrog-advanced-security", - "name": "JFrog Applicability Scanner", - "rules": [ - { - "id": "applic_CVE-2024-6119", - "name": "CVE-2024-6119", - "shortDescription": { - "text": "Scanner for CVE-2024-6119" - }, - "fullDescription": { - "text": "The scanner checks whether any of the following vulnerable functions are called:\n\n- `X509_VERIFY_PARAM_set1_email`\n\n- `X509_check_email`\n\n- `X509_VERIFY_PARAM_set1_host`\n\n- `X509_check_host`", - "markdown": "The scanner checks whether any of the following vulnerable functions are called:\n\n- `X509_VERIFY_PARAM_set1_email`\n\n- `X509_check_email`\n\n- `X509_VERIFY_PARAM_set1_host`\n\n- `X509_check_host`" - }, - "properties": { - "applicability": "applicable", - "conclusion": "negative", - "security-severity": "6.9" - } - }, - { - "id": "applic_CVE-2024-45490", - "name": "CVE-2024-45490", - "shortDescription": { - "text": "Scanner for CVE-2024-45490" - }, - "fullDescription": { - "text": "The scanner checks whether any of the following vulnerable functions are called:\n\n- `XML_Parse()`\n- `XML_ParseBuffer()`\n\nAn additional condition, which the scanner currently does not check, is that the `len` parameter which is passed to those functions is user-controlled.", - "markdown": "The scanner checks whether any of the following vulnerable functions are called:\n\n- `XML_Parse()`\n- `XML_ParseBuffer()`\n\nAn additional condition, which the scanner currently does not check, is that the `len` parameter which is passed to those functions is user-controlled." - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive", - "security-severity": "6.9" - } - }, - { - "id": "applic_CVE-2024-38428", - "name": "CVE-2024-38428", - "shortDescription": { - "text": "Scanner for CVE-2024-38428" - }, - "fullDescription": { - "text": "", - "markdown": "" - }, - "properties": { - "applicability": "undetermined", - "conclusion": "private" - } - }, - { - "id": "applic_CVE-2024-45492", - "name": "CVE-2024-45492", - "shortDescription": { - "text": "Scanner for CVE-2024-45492" - }, - "fullDescription": { - "text": "The scanner checks whether the current binary was compiled with 32-bit architecture and if any of the vulnerable functions are called:\n\n- `XML_ParseBuffer()`\n- `XML_Parse()`\n\nNote - the vulnerability occurs when certain inputs are passed to those functions.", - "markdown": "The scanner checks whether the current binary was compiled with 32-bit architecture and if any of the vulnerable functions are called:\n\n- `XML_ParseBuffer()`\n- `XML_Parse()`\n\nNote - the vulnerability occurs when certain inputs are passed to those functions." - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive", - "security-severity": "6.9" - } - }, - { - "id": "applic_CVE-2023-51767", - "name": "CVE-2023-51767", - "shortDescription": { - "text": "Scanner for CVE-2023-51767" - }, - "fullDescription": { - "text": "The CVE is always applicable.\n\nNote - The vulnerability is hardware-dependent.", - "markdown": "The CVE is always applicable.\n\nNote - The vulnerability is hardware-dependent." - }, - "properties": { - "applicability": "applicable", - "conclusion": "negative" - } - }, - { - "id": "applic_CVE-2011-3374", - "name": "CVE-2011-3374", - "shortDescription": { - "text": "Scanner for CVE-2011-3374" - }, - "fullDescription": { - "text": "The scanner checks if the vulnerable variable `ARCHIVE_KEYRING_URI` in `/usr/bin/apt-key` is not empty and not commented out. This is the URI that an attacker would need to target in a Man-in-the-Middle attack.\n\nThe below prerequisites are also crucial for exploitability but are not checked in the scanner:\n\n1. The command apt-key net-update should be executed on the affected system, or alternatively `apt.auth.net_update()` function from the `python-apt` Python module should be called. This is for the malicious keys download.\n\n2. After the execution of `apt-key net-update`, APT packages should be installed or updated on the machine.", - "markdown": "The scanner checks if the vulnerable variable `ARCHIVE_KEYRING_URI` in `/usr/bin/apt-key` is not empty and not commented out. This is the URI that an attacker would need to target in a Man-in-the-Middle attack.\n\nThe below prerequisites are also crucial for exploitability but are not checked in the scanner:\n\n1. The command apt-key net-update should be executed on the affected system, or alternatively `apt.auth.net_update()` function from the `python-apt` Python module should be called. This is for the malicious keys download.\n\n2. After the execution of `apt-key net-update`, APT packages should be installed or updated on the machine." - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive", - "security-severity": "6.9" - } - }, - { - "id": "applic_CVE-2024-4741", - "name": "CVE-2024-4741", - "shortDescription": { - "text": "Scanner for CVE-2024-4741" - }, - "fullDescription": { - "text": "The scanner checks whether the vulnerable function `SSL_free_buffers` is called.", - "markdown": "The scanner checks whether the vulnerable function `SSL_free_buffers` is called." - }, - "properties": { - "applicability": "applicable", - "conclusion": "negative", - "security-severity": "6.9" - } - } - ], - "version": "1.0" - } - }, - "invocations": [ - { - "arguments": [ - "/Users/user/.jfrog/dependencies/analyzerManager/jas_scanner/jas_scanner", - "scan", - "/var/folders/xv/th4cksxn7jv9wjrdnn1h4tj00000gq/T/jfrog.cli.temp.-1726210780-681556384/Applicability_1726210780/config.yaml" - ], - "executionSuccessful": true, - "workingDirectory": { - "uri": "/var/folders/xv/th4cksxn7jv9wjrdnn1h4tj00000gq/T/jfrog.cli.temp.-1726210535-1985298017" - } - } - ], - "results": [ - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "applic_CVE-2024-4741", - "message": { - "text": "References to the vulnerable functions were found" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///usr/local/bin/node" - }, - "region": { - "snippet": { - "text": "" - } - } - } - } - ] - }, - { - "ruleId": "applic_CVE-2024-45490", - "kind": "pass", - "message": { - "text": "The scanner checks whether any of the following vulnerable functions are called:\n\n- `XML_Parse()`\n- `XML_ParseBuffer()`\n\nAn additional condition, which the scanner currently does not check, is that the `len` parameter which is passed to those functions is user-controlled." - } - }, - { - "ruleId": "applic_CVE-2011-3374", - "kind": "pass", - "message": { - "text": "The scanner checks if the vulnerable variable `ARCHIVE_KEYRING_URI` in `/usr/bin/apt-key` is not empty and not commented out. This is the URI that an attacker would need to target in a Man-in-the-Middle attack.\n\nThe below prerequisites are also crucial for exploitability but are not checked in the scanner:\n\n1. The command apt-key net-update should be executed on the affected system, or alternatively `apt.auth.net_update()` function from the `python-apt` Python module should be called. This is for the malicious keys download.\n\n2. After the execution of `apt-key net-update`, APT packages should be installed or updated on the machine." - } - }, - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "applic_CVE-2024-6119", - "message": { - "text": "References to the vulnerable functions were found" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///usr/local/bin/node" - }, - "region": { - "snippet": { - "text": "" - } - } - } - } - ] - }, - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "applic_CVE-2024-6119", - "message": { - "text": "References to the vulnerable functions were found" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///usr/local/bin/node" - }, - "region": { - "snippet": { - "text": "" - } - } - } - } - ] - }, - { - "ruleId": "applic_CVE-2024-45492", - "kind": "pass", - "message": { - "text": "The scanner checks whether the current binary was compiled with 32-bit architecture and if any of the vulnerable functions are called:\n\n- `XML_ParseBuffer()`\n- `XML_Parse()`\n\nNote - the vulnerability occurs when certain inputs are passed to those functions." - } - } - ] - } - ], - "jas_vulnerabilities": { - "secrets": [ - { - "tool": { - "driver": { - "informationUri": "https://jfrog.com/help/r/jfrog-security-documentation/jfrog-advanced-security", - "name": "JFrog Secrets scanner", - "rules": [ - { - "id": "REQ.SECRET.GENERIC.TEXT", - "name": "REQ.SECRET.GENERIC.TEXT", - "shortDescription": { - "text": "Scanner for REQ.SECRET.GENERIC.TEXT" - }, - "fullDescription": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive" - } - }, - { - "id": "REQ.SECRET.GENERIC.CODE", - "name": "REQ.SECRET.GENERIC.CODE", - "shortDescription": { - "text": "Scanner for REQ.SECRET.GENERIC.CODE" - }, - "fullDescription": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - "properties": { - "applicability": "applicable", - "conclusion": "negative", - "security-severity": "6.9" - } - }, - { - "id": "REQ.SECRET.KEYS", - "name": "REQ.SECRET.KEYS", - "shortDescription": { - "text": "Scanner for REQ.SECRET.KEYS" - }, - "fullDescription": { - "text": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops\u0026tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n", - "markdown": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops\u0026tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n" - }, - "properties": { - "applicability": "applicable", - "conclusion": "negative", - "security-severity": "6.9" - } - }, - { - "id": "REQ.CRED.PUBLIC-ONLY", - "name": "REQ.CRED.PUBLIC-ONLY", - "shortDescription": { - "text": "Scanner for REQ.CRED.PUBLIC-ONLY" - }, - "fullDescription": { - "text": "", - "markdown": "" - }, - "properties": { - "applicability": "undetermined", - "conclusion": "private" - } - }, - { - "id": "REQ.SECRET.GENERIC.URL", - "name": "REQ.SECRET.GENERIC.URL", - "shortDescription": { - "text": "Scanner for REQ.SECRET.GENERIC.URL" - }, - "fullDescription": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - "properties": { - "applicability": "applicable", - "conclusion": "negative", - "security-severity": "6.9" - } - } - ], - "version": "1.0" - } - }, - "invocations": [ - { - "arguments": [ - "/Users/user/.jfrog/dependencies/analyzerManager/jas_scanner/jas_scanner", - "scan", - "/var/folders/xv/th4cksxn7jv9wjrdnn1h4tj00000gq/T/jfrog.cli.temp.-1726210780-681556384/Secrets_1726210839/config.yaml" - ], - "executionSuccessful": true, - "workingDirectory": { - "uri": "/var/folders/xv/th4cksxn7jv9wjrdnn1h4tj00000gq/T/jfrog.cli.temp.-1726210535-1985298017" - } - } - ], - "results": [ - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "REQ.SECRET.GENERIC.CODE", - "message": { - "text": "Hardcoded secrets were found" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///private/var/folders/xv/th4cksxn7jv9wjrdnn1h4tj00000gq/T/tmpsfyn_3d1/unpacked/filesystem/blobs/sha256/9e88ea9de1b44baba5e96a79e33e4af64334b2bf129e838e12f6dae71b5c86f0/usr/src/app/server/index.js" - }, - "region": { - "startLine": 5, - "startColumn": 7, - "endLine": 5, - "endColumn": 57, - "snippet": { - "text": "tok************" - } - } - } - } - ] - }, - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "REQ.SECRET.KEYS", - "message": { - "text": "Secret keys were found" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///private/var/folders/xv/th4cksxn7jv9wjrdnn1h4tj00000gq/T/tmpsfyn_3d1/unpacked/filesystem/blobs/sha256/9e88ea9de1b44baba5e96a79e33e4af64334b2bf129e838e12f6dae71b5c86f0/usr/src/app/server/index.js" - }, - "region": { - "startLine": 6, - "startColumn": 14, - "endLine": 6, - "endColumn": 24, - "snippet": { - "text": "eyJ************" - } - } - } - } - ] - }, - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "REQ.SECRET.GENERIC.URL", - "message": { - "text": "Hardcoded secrets were found" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///usr/src/app/server/scripts/__pycache__/fetch_github_repo.cpython-311.pyc" - }, - "region": { - "snippet": { - "text": "htt************" - } - } - } - } - ] - } - ] - } - ] - }, - "jas_violations": { - "secrets": [ - { - "tool": { - "driver": { - "informationUri": "https://jfrog.com/help/r/jfrog-security-documentation/jfrog-advanced-security", - "name": "JFrog Secrets scanner", - "rules": [ - { - "id": "REQ.SECRET.GENERIC.TEXT", - "name": "REQ.SECRET.GENERIC.TEXT", - "shortDescription": { - "text": "Scanner for REQ.SECRET.GENERIC.TEXT" - }, - "fullDescription": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive" - } - }, - { - "id": "REQ.SECRET.GENERIC.CODE", - "name": "REQ.SECRET.GENERIC.CODE", - "shortDescription": { - "text": "Scanner for REQ.SECRET.GENERIC.CODE" - }, - "fullDescription": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - "properties": { - "applicability": "applicable", - "conclusion": "negative", - "security-severity": "6.9" - } - }, - { - "id": "REQ.SECRET.KEYS", - "name": "REQ.SECRET.KEYS", - "shortDescription": { - "text": "Scanner for REQ.SECRET.KEYS" - }, - "fullDescription": { - "text": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops\u0026tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n", - "markdown": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops\u0026tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n" - }, - "properties": { - "applicability": "applicable", - "conclusion": "negative", - "security-severity": "6.9" - } - }, - { - "id": "REQ.CRED.PUBLIC-ONLY", - "name": "REQ.CRED.PUBLIC-ONLY", - "shortDescription": { - "text": "Scanner for REQ.CRED.PUBLIC-ONLY" - }, - "fullDescription": { - "text": "", - "markdown": "" - }, - "properties": { - "applicability": "undetermined", - "conclusion": "private" - } - }, - { - "id": "REQ.SECRET.GENERIC.URL", - "name": "REQ.SECRET.GENERIC.URL", - "shortDescription": { - "text": "Scanner for REQ.SECRET.GENERIC.URL" - }, - "fullDescription": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - "properties": { - "applicability": "applicable", - "conclusion": "negative", - "security-severity": "6.9" - } - } - ], - "version": "1.0" - } - }, - "invocations": [ - { - "arguments": [ - "/Users/user/.jfrog/dependencies/analyzerManager/jas_scanner/jas_scanner", - "scan", - "/var/folders/xv/th4cksxn7jv9wjrdnn1h4tj00000gq/T/jfrog.cli.temp.-1726210780-681556384/Secrets_1726210839/config.yaml" - ], - "executionSuccessful": true, - "workingDirectory": { - "uri": "/var/folders/xv/th4cksxn7jv9wjrdnn1h4tj00000gq/T/jfrog.cli.temp.-1726210535-1985298017" - } - } - ], - "results": [ - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "REQ.SECRET.GENERIC.CODE", - "message": { - "text": "Hardcoded secrets were found" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///private/var/folders/xv/th4cksxn7jv9wjrdnn1h4tj00000gq/T/tmpsfyn_3d1/unpacked/filesystem/blobs/sha256/9e88ea9de1b44baba5e96a79e33e4af64334b2bf129e838e12f6dae71b5c86f0/usr/src/app/server/index.js" - }, - "region": { - "startLine": 5, - "startColumn": 7, - "endLine": 5, - "endColumn": 57, - "snippet": { - "text": "tok************" - } - } - } - } - ] - }, - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "REQ.SECRET.KEYS", - "message": { - "text": "Secret keys were found" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "file:///private/var/folders/xv/th4cksxn7jv9wjrdnn1h4tj00000gq/T/tmpsfyn_3d1/unpacked/filesystem/blobs/sha256/9e88ea9de1b44baba5e96a79e33e4af64334b2bf129e838e12f6dae71b5c86f0/usr/src/app/server/index.js" - }, - "region": { - "startLine": 6, - "startColumn": 14, - "endLine": 6, - "endColumn": 24, - "snippet": { - "text": "eyJ************" - } - } - } - } - ] - } - ] - } - ] - } - } - } - ] -} \ No newline at end of file diff --git a/tests/testdata/output/dockerscan/docker_sarif.json b/tests/testdata/output/dockerscan/docker_sarif.json index 7d50c474..f93f030d 100644 --- a/tests/testdata/output/dockerscan/docker_sarif.json +++ b/tests/testdata/output/dockerscan/docker_sarif.json @@ -2,240 +2,6 @@ "version": "2.1.0", "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json", "runs": [ - { - "tool": { - "driver": { - "informationUri": "https://jfrog.com/help/r/jfrog-security-documentation/jfrog-advanced-security", - "name": "JFrog Binary Secrets Scanner", - "rules": [ - { - "id": "REQ.SECRET.GENERIC.TEXT", - "name": "REQ.SECRET.GENERIC.TEXT", - "shortDescription": { - "text": "[Secret in Binary found] Scanner for REQ.SECRET.GENERIC.TEXT" - }, - "fullDescription": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - "help": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - "properties": { - "applicability": "not_applicable", - "conclusion": "positive" - } - }, - { - "id": "REQ.SECRET.GENERIC.CODE", - "name": "REQ.SECRET.GENERIC.CODE", - "shortDescription": { - "text": "[Secret in Binary found] Scanner for REQ.SECRET.GENERIC.CODE" - }, - "fullDescription": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - "help": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - "properties": { - "applicability": "applicable", - "conclusion": "negative", - "security-severity": "6.9" - } - }, - { - "id": "REQ.SECRET.KEYS", - "name": "REQ.SECRET.KEYS", - "shortDescription": { - "text": "[Secret in Binary found] Scanner for REQ.SECRET.KEYS" - }, - "fullDescription": { - "text": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n", - "markdown": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n" - }, - "help": { - "text": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n", - "markdown": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n" - }, - "properties": { - "applicability": "applicable", - "conclusion": "negative", - "security-severity": "6.9" - } - }, - { - "id": "REQ.CRED.PUBLIC-ONLY", - "name": "REQ.CRED.PUBLIC-ONLY", - "shortDescription": { - "text": "[Secret in Binary found] Scanner for REQ.CRED.PUBLIC-ONLY" - }, - "fullDescription": { - "text": "", - "markdown": "" - }, - "help": { - "text": "", - "markdown": "" - }, - "properties": { - "applicability": "undetermined", - "conclusion": "private" - } - }, - { - "id": "REQ.SECRET.GENERIC.URL", - "name": "REQ.SECRET.GENERIC.URL", - "shortDescription": { - "text": "[Secret in Binary found] Scanner for REQ.SECRET.GENERIC.URL" - }, - "fullDescription": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - "help": { - "text": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n", - "markdown": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - "properties": { - "applicability": "applicable", - "conclusion": "negative", - "security-severity": "6.9" - } - } - ], - "version": "1.0" - } - }, - "invocations": [ - { - "arguments": [ - "/Users/user/.jfrog/dependencies/analyzerManager/jas_scanner/jas_scanner", - "scan", - "/var/folders/xv/th4cksxn7jv9wjrdnn1h4tj00000gq/T/jfrog.cli.temp.-1726210780-681556384/Secrets_1726210839/config.yaml" - ], - "executionSuccessful": true, - "workingDirectory": { - "uri": "/var/folders/xv/th4cksxn7jv9wjrdnn1h4tj00000gq/T/jfrog.cli.temp.-1726210535-1985298017" - } - } - ], - "results": [ - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "REQ.SECRET.GENERIC.CODE", - "message": { - "text": "Hardcoded secrets were found", - "markdown": "🔒 Found Secrets in Binary docker scanning:\nImage: platform.jfrog.io/swamp-docker/swamp:latest\nLayer (sha256): 9e88ea9de1b44baba5e96a79e33e4af64334b2bf129e838e12f6dae71b5c86f0\nFilepath: usr/src/app/server/index.js\nEvidence: tok************" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "usr/src/app/server/index.js" - }, - "region": { - "startLine": 5, - "startColumn": 7, - "endLine": 5, - "endColumn": 57, - "snippet": { - "text": "tok************" - } - } - }, - "logicalLocations": [ - { - "name": "9e88ea9de1b44baba5e96a79e33e4af64334b2bf129e838e12f6dae71b5c86f0", - "kind": "layer", - "properties": { - "algorithm": "sha256" - } - } - ] - } - ], - "fingerprints": { - "jfrogFingerprintHash": "00436fac1d19ea36302f14e892926efb" - } - }, - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "REQ.SECRET.KEYS", - "message": { - "text": "Secret keys were found", - "markdown": "🔒 Found Secrets in Binary docker scanning:\nImage: platform.jfrog.io/swamp-docker/swamp:latest\nLayer (sha256): 9e88ea9de1b44baba5e96a79e33e4af64334b2bf129e838e12f6dae71b5c86f0\nFilepath: usr/src/app/server/index.js\nEvidence: eyJ************" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "usr/src/app/server/index.js" - }, - "region": { - "startLine": 6, - "startColumn": 14, - "endLine": 6, - "endColumn": 24, - "snippet": { - "text": "eyJ************" - } - } - }, - "logicalLocations": [ - { - "name": "9e88ea9de1b44baba5e96a79e33e4af64334b2bf129e838e12f6dae71b5c86f0", - "kind": "layer", - "properties": { - "algorithm": "sha256" - } - } - ] - } - ], - "fingerprints": { - "jfrogFingerprintHash": "2550dbdb124696ae8fcc5cfd6f2b65b8" - } - }, - { - "properties": { - "metadata": "", - "tokenValidation": "" - }, - "ruleId": "REQ.SECRET.GENERIC.URL", - "message": { - "text": "Hardcoded secrets were found", - "markdown": "🔒 Found Secrets in Binary docker scanning:\nImage: platform.jfrog.io/swamp-docker/swamp:latest\nFilepath: usr/src/app/server/scripts/__pycache__/fetch_github_repo.cpython-311.pyc\nEvidence: htt************" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "usr/src/app/server/scripts/__pycache__/fetch_github_repo.cpython-311.pyc" - }, - "region": { - "snippet": { - "text": "htt************" - } - } - } - } - ], - "fingerprints": { - "jfrogFingerprintHash": "9164423e88bbec9d1216bc5600eb7f9b" - } - } - ] - }, { "tool": { "driver": { @@ -243,116 +9,25 @@ "name": "JFrog Xray Scanner", "rules": [ { - "id": "CVE-2024-45490_debian:bookworm:libexpat1_2.5.0-1", - "shortDescription": { - "text": "[CVE-2024-45490] debian:bookworm:libexpat1 2.5.0-1" - }, - "help": { - "text": "An issue was discovered in libexpat before 2.6.3. xmlparse.c does not reject a negative length for XML_ParseBuffer.", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 9.8 | Not Applicable | `sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar ` | No fix available |" - }, - "properties": { - "security-severity": "9.8" - } - }, - { - "id": "CVE-2011-3374_debian:bookworm:apt_2.6.1", - "shortDescription": { - "text": "[CVE-2011-3374] debian:bookworm:apt 2.6.1" - }, - "help": { - "text": "It was found that apt-key in apt, all versions, do not correctly validate gpg keys with the master keyring, leading to a potential man-in-the-middle attack.", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 3.7 | Not Applicable | `sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar ` | No fix available |" - }, - "properties": { - "security-severity": "3.7" - } - }, - { - "id": "CVE-2024-38428_debian:bookworm:wget_1.21.3-1+b1", - "shortDescription": { - "text": "[CVE-2024-38428] debian:bookworm:wget 1.21.3-1+b1" - }, - "help": { - "text": "url.c in GNU Wget through 1.24.5 mishandles semicolons in the userinfo subcomponent of a URI, and thus there may be insecure behavior in which data that was supposed to be in the userinfo subcomponent is misinterpreted to be part of the host subcomponent.", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 9.1 | Undetermined | `sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar ` | No fix available |" - }, - "properties": { - "security-severity": "9.1" - } - }, - { - "id": "XRAY-264729_cors.js_0.0.1-security", + "id": "CVE-2024-38428_debian:bookworm:openssl_3.0.13-1~deb12u1", "shortDescription": { - "text": "[XRAY-264729] cors.js 0.0.1-security" + "text": "[CVE-2024-38428] debian:bookworm:openssl 3.0.13-1~deb12u1" }, "help": { - "text": "Malicious package cors.js for Node.js", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 10.0 | Not Covered | `sha256__ab1c0a95b2970fb44e2a4046c5c00f37a5b061e74d72b254a8975beb7d09f74f.tar ` | No fix available |" + "text": "Interpretation Conflict", + "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 10.0 | Undetermined | `sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar ` | [3.0.14-1~deb12u2] |" }, "properties": { "security-severity": "10.0" } }, - { - "id": "CVE-2024-45492_debian:bookworm:libexpat1_2.5.0-1", - "shortDescription": { - "text": "[CVE-2024-45492] debian:bookworm:libexpat1 2.5.0-1" - }, - "help": { - "text": "An issue was discovered in libexpat before 2.6.3. nextScaffoldPart in xmlparse.c can have an integer overflow for m_groupSize on 32-bit platforms (where UINT_MAX equals SIZE_MAX).", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 9.8 | Not Applicable | `sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar ` | No fix available |" - }, - "properties": { - "security-severity": "9.8" - } - }, - { - "id": "CVE-2023-51767_debian:bookworm:openssh-client:1_9.2p1-2+deb12u3", - "shortDescription": { - "text": "[CVE-2023-51767] debian:bookworm:openssh-client:1 9.2p1-2+deb12u3" - }, - "help": { - "text": "OpenSSH through 9.6, when common types of DRAM are used, might allow row hammer attacks (for authentication bypass) because the integer value of authenticated in mm_answer_authpassword does not resist flips of a single bit. NOTE: this is applicable to a certain threat model of attacker-victim co-location in which the attacker has user privileges.", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 7.0 | Applicable | `sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar ` | No fix available |" - }, - "properties": { - "security-severity": "7.0" - } - }, - { - "id": "CVE-2011-3374_debian:bookworm:libapt-pkg6.0_2.6.1", - "shortDescription": { - "text": "[CVE-2011-3374] debian:bookworm:libapt-pkg6.0 2.6.1" - }, - "help": { - "text": "It was found that apt-key in apt, all versions, do not correctly validate gpg keys with the master keyring, leading to a potential man-in-the-middle attack.", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 3.7 | Not Applicable | `sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar ` | No fix available |" - }, - "properties": { - "security-severity": "3.7" - } - }, - { - "id": "CVE-2024-4741_debian:bookworm:openssl_3.0.13-1~deb12u1", - "shortDescription": { - "text": "[CVE-2024-4741] debian:bookworm:openssl 3.0.13-1~deb12u1" - }, - "help": { - "text": "CVE-2024-4741", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 0.0 | Applicable | `sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar ` | [3.0.14-1~deb12u1] |" - }, - "properties": { - "security-severity": "0.0" - } - }, { "id": "CVE-2024-6119_debian:bookworm:libssl3_3.0.13-1~deb12u1", "shortDescription": { "text": "[CVE-2024-6119] debian:bookworm:libssl3 3.0.13-1~deb12u1" }, "help": { - "text": "Issue summary: Applications performing certificate name checks (e.g., TLS\nclients checking server certificates) may attempt to read an invalid memory\naddress resulting in abnormal termination of the application process.\n\nImpact summary: Abnormal termination of an application can a cause a denial of\nservice.\n\nApplications performing certificate name checks (e.g., TLS clients checking\nserver certificates) may attempt to read an invalid memory address when\ncomparing the expected name with an `otherName` subject alternative name of an\nX.509 certificate. This may result in an exception that terminates the\napplication program.\n\nNote that basic certificate chain validation (signatures, dates, ...) is not\naffected, the denial of service can occur only when the application also\nspecifies an expected DNS name, Email address or IP address.\n\nTLS servers rarely solicit client certificates, and even when they do, they\ngenerally don't perform a name check against a reference identifier (expected\nidentity), but rather extract the presented identity after checking the\ncertificate chain. So TLS servers are generally not affected and the severity\nof the issue is Moderate.\n\nThe FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.", + "text": "Issue summary", "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 0.0 | Applicable | `sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar ` | No fix available |" }, "properties": { @@ -360,40 +35,27 @@ } }, { - "id": "CVE-2024-6119_debian:bookworm:openssl_3.0.13-1~deb12u1", - "shortDescription": { - "text": "[CVE-2024-6119] debian:bookworm:openssl 3.0.13-1~deb12u1" - }, - "help": { - "text": "Issue summary: Applications performing certificate name checks (e.g., TLS\nclients checking server certificates) may attempt to read an invalid memory\naddress resulting in abnormal termination of the application process.\n\nImpact summary: Abnormal termination of an application can a cause a denial of\nservice.\n\nApplications performing certificate name checks (e.g., TLS clients checking\nserver certificates) may attempt to read an invalid memory address when\ncomparing the expected name with an `otherName` subject alternative name of an\nX.509 certificate. This may result in an exception that terminates the\napplication program.\n\nNote that basic certificate chain validation (signatures, dates, ...) is not\naffected, the denial of service can occur only when the application also\nspecifies an expected DNS name, Email address or IP address.\n\nTLS servers rarely solicit client certificates, and even when they do, they\ngenerally don't perform a name check against a reference identifier (expected\nidentity), but rather extract the presented identity after checking the\ncertificate chain. So TLS servers are generally not affected and the severity\nof the issue is Moderate.\n\nThe FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 0.0 | Applicable | `sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar ` | [3.0.14-1~deb12u2] |" - }, - "properties": { - "security-severity": "0.0" - } - }, - { - "id": "CVE-2024-4741_debian:bookworm:libssl3_3.0.13-1~deb12u1", + "id": "CVE-2024-38428_debian:bookworm:libssl3_3.0.13-1~deb12u1", "shortDescription": { - "text": "[CVE-2024-4741] debian:bookworm:libssl3 3.0.13-1~deb12u1" + "text": "[CVE-2024-38428] debian:bookworm:libssl3 3.0.13-1~deb12u1" }, "help": { - "text": "CVE-2024-4741", - "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 0.0 | Applicable | `sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar ` | No fix available |" + "text": "Interpretation Conflict", + "markdown": "| Severity Score | Contextual Analysis | Direct Dependencies | Fixed Versions |\n| :---: | :---: | :---: | :---: |\n| 10.0 | Undetermined | `sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar ` | No fix available |" }, "properties": { - "security-severity": "0.0" + "security-severity": "10.0" } } ], - "version": "3.104.8" + "version": "3.107.13" } }, "invocations": [ { "executionSuccessful": true, "workingDirectory": { - "uri": "/var/folders/xv/th4cksxn7jv9wjrdnn1h4tj00000gq/T/jfrog.cli.temp.-1726210535-1985298017" + "uri": "temp/folders/T/jfrog.cli.temp.-11-11" } } ], @@ -404,7 +66,7 @@ "fixedVersion": "No fix available" }, "ruleId": "CVE-2024-6119_debian:bookworm:libssl3_3.0.13-1~deb12u1", - "ruleIndex": 8, + "ruleIndex": 1, "level": "none", "message": { "text": "[CVE-2024-6119] sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar ", @@ -432,46 +94,12 @@ "jfrogFingerprintHash": "5b5d2ba57a2eddf58f4579b7ebe42599" } }, - { - "properties": { - "applicability": "Applicable", - "fixedVersion": "[3.0.14-1~deb12u2]" - }, - "ruleId": "CVE-2024-6119_debian:bookworm:openssl_3.0.13-1~deb12u1", - "ruleIndex": 9, - "level": "none", - "message": { - "text": "[CVE-2024-6119] sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar ", - "markdown": "[CVE-2024-6119] sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar \nImage: platform.jfrog.io/swamp-docker/swamp:latest\nLayer (sha256): f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar" - } - }, - "logicalLocations": [ - { - "name": "f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595", - "kind": "layer", - "properties": { - "algorithm": "sha256" - } - } - ] - } - ], - "fingerprints": { - "jfrogFingerprintHash": "bd5908946de9c082f96e15217590eebc" - } - }, { "properties": { "applicability": "Undetermined", "fixedVersion": "No fix available" }, - "ruleId": "CVE-2024-38428_debian:bookworm:wget_1.21.3-1+b1", + "ruleId": "CVE-2024-38428_debian:bookworm:libssl3_3.0.13-1~deb12u1", "ruleIndex": 2, "level": "error", "message": { @@ -497,65 +125,31 @@ } ], "fingerprints": { - "jfrogFingerprintHash": "db89861310f80a270a0a81f48d7dc974" - } - }, - { - "properties": { - "applicability": "Not Covered", - "fixedVersion": "No fix available" - }, - "ruleId": "XRAY-264729_cors.js_0.0.1-security", - "ruleIndex": 3, - "level": "error", - "message": { - "text": "[XRAY-264729] sha256__ab1c0a95b2970fb44e2a4046c5c00f37a5b061e74d72b254a8975beb7d09f74f.tar ", - "markdown": "[XRAY-264729] sha256__ab1c0a95b2970fb44e2a4046c5c00f37a5b061e74d72b254a8975beb7d09f74f.tar \nImage: platform.jfrog.io/swamp-docker/swamp:latest\nLayer (sha256): ab1c0a95b2970fb44e2a4046c5c00f37a5b061e74d72b254a8975beb7d09f74f" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "sha256__ab1c0a95b2970fb44e2a4046c5c00f37a5b061e74d72b254a8975beb7d09f74f.tar" - } - }, - "logicalLocations": [ - { - "name": "ab1c0a95b2970fb44e2a4046c5c00f37a5b061e74d72b254a8975beb7d09f74f", - "kind": "layer", - "properties": { - "algorithm": "sha256" - } - } - ] - } - ], - "fingerprints": { - "jfrogFingerprintHash": "d653c414ef56560432b122358961104a" + "jfrogFingerprintHash": "e4ad8f8a303959f43d395a9967290329" } }, { "properties": { - "applicability": "Not Applicable", - "fixedVersion": "No fix available" + "applicability": "Undetermined", + "fixedVersion": "[3.0.14-1~deb12u2]" }, - "ruleId": "CVE-2024-45490_debian:bookworm:libexpat1_2.5.0-1", + "ruleId": "CVE-2024-38428_debian:bookworm:openssl_3.0.13-1~deb12u1", "ruleIndex": 0, "level": "error", "message": { - "text": "[CVE-2024-45490] sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar ", - "markdown": "[CVE-2024-45490] sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar \nImage: platform.jfrog.io/swamp-docker/swamp:latest\nLayer (sha256): 20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1" + "text": "[CVE-2024-38428] sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar ", + "markdown": "[CVE-2024-38428] sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar \nImage: platform.jfrog.io/swamp-docker/swamp:latest\nLayer (sha256): f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar" + "uri": "sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar" } }, "logicalLocations": [ { - "name": "20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1", + "name": "f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595", "kind": "layer", "properties": { "algorithm": "sha256" @@ -565,167 +159,73 @@ } ], "fingerprints": { - "jfrogFingerprintHash": "61be5170151428187e85ff7b27fd65b4" + "jfrogFingerprintHash": "fde53f1fba5bffb4d79b03735c86ee2d" } - }, - { - "properties": { - "applicability": "Not Applicable", - "fixedVersion": "No fix available" - }, - "ruleId": "CVE-2024-45492_debian:bookworm:libexpat1_2.5.0-1", - "ruleIndex": 4, - "level": "error", - "message": { - "text": "[CVE-2024-45492] sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar ", - "markdown": "[CVE-2024-45492] sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar \nImage: platform.jfrog.io/swamp-docker/swamp:latest\nLayer (sha256): 20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1" - }, - "locations": [ + } + ] + }, + { + "tool": { + "driver": { + "name": "JFrog Binary Secrets Scanner", + "rules": [ { - "physicalLocation": { - "artifactLocation": { - "uri": "sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar" - } + "id": "REQ.SECRET.GENERIC.CODE", + "shortDescription": { + "text": "[Secret in Binary found] Scanner for REQ.SECRET.GENERIC.CODE", + "markdown": "Scanner for REQ.SECRET.GENERIC.CODE" }, - "logicalLocations": [ - { - "name": "20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1", - "kind": "layer", - "properties": { - "algorithm": "sha256" - } - } - ] - } - ], - "fingerprints": { - "jfrogFingerprintHash": "e47bb0a94451ed5111fabcf0ccaaeee6" - } - }, - { - "properties": { - "applicability": "Applicable", - "fixedVersion": "No fix available" - }, - "ruleId": "CVE-2023-51767_debian:bookworm:openssh-client:1_9.2p1-2+deb12u3", - "ruleIndex": 5, - "level": "note", - "message": { - "text": "[CVE-2023-51767] sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar ", - "markdown": "[CVE-2023-51767] sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar \nImage: platform.jfrog.io/swamp-docker/swamp:latest\nLayer (sha256): 20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar" - } + "fullDescription": { + "text": "The Scanner checks for REQ.SECRET.GENERIC.CODE", + "markdown": "The Scanner checks for REQ.SECRET.GENERIC.CODE" }, - "logicalLocations": [ - { - "name": "20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1", - "kind": "layer", - "properties": { - "algorithm": "sha256" - } - } - ] + "help": { + "text": "The Scanner checks for REQ.SECRET.GENERIC.CODE", + "markdown": "The Scanner checks for REQ.SECRET.GENERIC.CODE" + } } - ], - "fingerprints": { - "jfrogFingerprintHash": "fe7c1c90b3e7d340890027344468b42d" - } - }, + ] + } + }, + "invocations": [ { - "properties": { - "applicability": "Not Applicable", - "fixedVersion": "No fix available" - }, - "ruleId": "CVE-2011-3374_debian:bookworm:apt_2.6.1", - "ruleIndex": 1, - "level": "note", - "message": { - "text": "[CVE-2011-3374] sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar ", - "markdown": "[CVE-2011-3374] sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar \nImage: platform.jfrog.io/swamp-docker/swamp:latest\nLayer (sha256): cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar" - } - }, - "logicalLocations": [ - { - "name": "cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e", - "kind": "layer", - "properties": { - "algorithm": "sha256" - } - } - ] - } - ], - "fingerprints": { - "jfrogFingerprintHash": "81f98a6fd77d17d7647c0ae81410b506" + "executionSuccessful": null, + "workingDirectory": { + "uri": "temp/folders/T/jfrog.cli.temp.-11-11" } - }, + } + ], + "results": [ { "properties": { - "applicability": "Not Applicable", - "fixedVersion": "No fix available" + "metadata": "expired", + "tokenValidation": "Inactive" }, - "ruleId": "CVE-2011-3374_debian:bookworm:libapt-pkg6.0_2.6.1", - "ruleIndex": 6, - "level": "note", + "ruleId": "REQ.SECRET.GENERIC.CODE", + "level": "info", "message": { - "text": "[CVE-2011-3374] sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar ", - "markdown": "[CVE-2011-3374] sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar \nImage: platform.jfrog.io/swamp-docker/swamp:latest\nLayer (sha256): cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e" + "text": "Secret REQ.SECRET.GENERIC.CODE were found", + "markdown": "🔒 Found Secrets in Binary docker scanning:\nImage: platform.jfrog.io/swamp-docker/swamp:latest\nLayer (sha256): 9e88ea9de1b44baba5e96a79e33e4af64334b2bf129e838e12f6dae71b5c86f0\nFilepath: usr/src/app/server/index.js\nEvidence: tok************\nToken Validation Inactive" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar" - } - }, - "logicalLocations": [ - { - "name": "cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e", - "kind": "layer", - "properties": { - "algorithm": "sha256" + "uri": "usr/src/app/server/index.js" + }, + "region": { + "startLine": 5, + "startColumn": 7, + "endLine": 5, + "endColumn": 57, + "snippet": { + "text": "tok************" } } - ] - } - ], - "fingerprints": { - "jfrogFingerprintHash": "7933bf1c7b4635012e7571e82e619db6" - } - }, - { - "properties": { - "applicability": "Applicable", - "fixedVersion": "[3.0.14-1~deb12u1]" - }, - "ruleId": "CVE-2024-4741_debian:bookworm:openssl_3.0.13-1~deb12u1", - "ruleIndex": 7, - "level": "none", - "message": { - "text": "[CVE-2024-4741] sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar ", - "markdown": "[CVE-2024-4741] sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar \nImage: platform.jfrog.io/swamp-docker/swamp:latest\nLayer (sha256): f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595" - }, - "locations": [ - { - "physicalLocation": { - "artifactLocation": { - "uri": "sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar" - } }, "logicalLocations": [ { - "name": "f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595", + "name": "9e88ea9de1b44baba5e96a79e33e4af64334b2bf129e838e12f6dae71b5c86f0", "kind": "layer", "properties": { "algorithm": "sha256" @@ -735,31 +235,45 @@ } ], "fingerprints": { - "jfrogFingerprintHash": "a374e04992f42ee827634927edd7e8d4" + "jfrogFingerprintHash": "6b99fa4445061b0eea53dc99803c8eca" } }, { "properties": { - "applicability": "Applicable", - "fixedVersion": "No fix available" + "issueId": "sec-violation-1", + "metadata": "expired", + "policies": [ + "policy" + ], + "tokenValidation": "Inactive", + "watch": "watch" }, - "ruleId": "CVE-2024-4741_debian:bookworm:libssl3_3.0.13-1~deb12u1", - "ruleIndex": 10, - "level": "none", + "ruleId": "REQ.SECRET.GENERIC.CODE", + "ruleIndex": 0, + "level": "info", "message": { - "text": "[CVE-2024-4741] sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar ", - "markdown": "[CVE-2024-4741] sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar \nImage: platform.jfrog.io/swamp-docker/swamp:latest\nLayer (sha256): f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595" + "text": "Secret REQ.SECRET.GENERIC.CODE were found", + "markdown": "Security violation 🔒 Found Secrets in Binary docker scanning:\nImage: platform.jfrog.io/swamp-docker/swamp:latest\nLayer (sha256): 9e88ea9de1b44baba5e96a79e33e4af64334b2bf129e838e12f6dae71b5c86f0\nFilepath: usr/src/app/server/index.js\nEvidence: tok************\nToken Validation Inactive" }, "locations": [ { "physicalLocation": { "artifactLocation": { - "uri": "sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar" + "uri": "usr/src/app/server/index.js" + }, + "region": { + "startLine": 5, + "startColumn": 7, + "endLine": 5, + "endColumn": 57, + "snippet": { + "text": "tok************" + } } }, "logicalLocations": [ { - "name": "f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595", + "name": "9e88ea9de1b44baba5e96a79e33e4af64334b2bf129e838e12f6dae71b5c86f0", "kind": "layer", "properties": { "algorithm": "sha256" @@ -769,10 +283,10 @@ } ], "fingerprints": { - "jfrogFingerprintHash": "2c34553d9c75460bf14243ff13ba84c8" + "jfrogFingerprintHash": "7d0f57f0cc66fc6f3373fe1965297533" } } ] } ] -} +} \ No newline at end of file diff --git a/tests/testdata/output/dockerscan/docker_simple_json.json b/tests/testdata/output/dockerscan/docker_simple_json.json index 0fbd8a5a..acf41b3c 100644 --- a/tests/testdata/output/dockerscan/docker_simple_json.json +++ b/tests/testdata/output/dockerscan/docker_simple_json.json @@ -2,202 +2,6 @@ "vulnerabilities": [ { "severity": "Critical", - "impactedPackageName": "debian:bookworm:wget", - "impactedPackageVersion": "1.21.3-1+b1", - "impactedPackageType": "Debian", - "components": [ - { - "name": "sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar", - "version": "", - "location": { - "file": "sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar" - } - } - ], - "summary": "url.c in GNU Wget through 1.24.5 mishandles semicolons in the userinfo subcomponent of a URI, and thus there may be insecure behavior in which data that was supposed to be in the userinfo subcomponent is misinterpreted to be part of the host subcomponent.", - "applicable": "Undetermined", - "fixedVersions": null, - "cves": [ - { - "id": "CVE-2024-38428", - "cvssV2": "", - "cvssV3": "9.1", - "applicability": { - "status": "Undetermined" - } - } - ], - "issueId": "XRAY-606103", - "references": [ - "https://git.savannah.gnu.org/cgit/wget.git/commit/?id=ed0c7c7e0e8f7298352646b2fd6e06a11e242ace", - "https://lists.gnu.org/archive/html/bug-wget/2024-06/msg00005.html", - "https://security-tracker.debian.org/tracker/CVE-2024-38428" - ], - "impactPaths": [ - [ - { - "name": "platform.jfrog.io/swamp-docker/swamp", - "version": "latest" - }, - { - "name": "sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar", - "version": "", - "location": { - "file": "sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar" - } - }, - { - "name": "debian:bookworm:wget", - "version": "1.21.3-1+b1", - "location": { - "file": "wget:1.21.3-1+b1" - } - } - ] - ], - "jfrogResearchInformation": null - }, - { - "severity": "Critical", - "impactedPackageName": "cors.js", - "impactedPackageVersion": "0.0.1-security", - "impactedPackageType": "npm", - "components": [ - { - "name": "sha256__ab1c0a95b2970fb44e2a4046c5c00f37a5b061e74d72b254a8975beb7d09f74f.tar", - "version": "", - "location": { - "file": "sha256__ab1c0a95b2970fb44e2a4046c5c00f37a5b061e74d72b254a8975beb7d09f74f.tar" - } - } - ], - "summary": "Malicious package cors.js for Node.js", - "applicable": "Not Covered", - "fixedVersions": null, - "cves": null, - "issueId": "XRAY-264729", - "references": [ - "https://registry.npmjs.com" - ], - "impactPaths": [ - [ - { - "name": "platform.jfrog.io/swamp-docker/swamp", - "version": "latest" - }, - { - "name": "sha256__ab1c0a95b2970fb44e2a4046c5c00f37a5b061e74d72b254a8975beb7d09f74f.tar", - "version": "", - "location": { - "file": "sha256__ab1c0a95b2970fb44e2a4046c5c00f37a5b061e74d72b254a8975beb7d09f74f.tar" - } - }, - { - "name": "cors.js", - "version": "0.0.1-security", - "location": { - "file": "usr/src/app/node_modules/cors.js/package.json" - } - } - ] - ], - "jfrogResearchInformation": { - "severity": "Critical", - "summary": "Malicious package cors.js for Node.js", - "details": "The package cors.js for Node.js contains malicious code that installs a persistent connectback shell. The package is typosquatting the popular `cors` package. When installed, the package opens a connectback shell to the hardcoded host `107.175.32.229` on TCP port 56173. The malicious payload achieves persistency by installing a cron job that repeats every 10 seconds - `*/10 * * * * *`", - "remediation": "As with any malware, the malicious package must be completely removed, and steps must be taken care to remediate the damage that was done by the malicious package -\n\n##### Removing the malicious package\n\nRun `npm uninstall cors.js`\n\n##### Refreshing stolen credentials\n\nMany malicious packages steal stored user credentials, focusing on the following -\n\n* [Browser autocomplete](https://jfrog.com/blog/malicious-pypi-packages-stealing-credit-cards-injecting-code/) data, such as saved passwords and credit cards\n* [Environment variables](https://jfrog.com/blog/malicious-npm-packages-are-after-your-discord-tokens-17-new-packages-disclosed/) passed to the malicious code\n* [Stored Discord tokens](https://jfrog.com/blog/malicious-npm-packages-are-after-your-discord-tokens-17-new-packages-disclosed/)\n* AWS / GitHub credentials stored in cleartext files\n\nIt is highly recommended to change or revoke data that is stored in the infected machine at those locations\n\n##### Stopping malicious processes\n\nMany malicious packages start malicious processes such as [connectback shells](https://jfrog.com/blog/jfrog-discloses-3-remote-access-trojans-in-pypi/) or crypto-miners. Search for any unfamiliar processes that consume a large amount of CPU or a large amount of network traffic, and stop them. On Windows, this can be facilitated with [Sysinternals Process Explorer](https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer).\n\n##### Removing installed backdoors\n\nMany malicious packages install themselves as a [persistent backdoor](https://jfrog.com/blog/npm-supply-chain-attack-targets-german-based-companies/), in order to guarantee the malicious code survives a reboot. Search for any unfamiliar binaries set to be run on startup, and remove them. On Windows, this can be facilitated with [Sysinternals Autoruns](https://docs.microsoft.com/en-us/sysinternals/downloads/autoruns).\n\n##### Defining an Xray policy that blocks downloads of Artifacts with malicious packages\n\nIt is possible to [create an Xray policy](https://www.jfrog.com/confluence/display/JFROG/Creating+Xray+Policies+and+Rules) that will not allow artifacts with identified malicious packages to be downloaded from Artifactory. To create such a policy, add a new `Security` policy and set `Minimal Severity` to `Critical`. Under `Automatic Actions` check the `Block Download` action.\n\n##### Contacting the JFrog Security Research team for additional information\n\nOptionally, if you are unsure of the full impact of the malicious package and wish to get more details, the JFrog Security Research team can help you assess the potential damage from the installed malicious package.\n\nPlease contact us at research@jfrog.com with details of the affected artifact and the name of the identified malicious package." - } - }, - { - "severity": "Low", - "impactedPackageName": "debian:bookworm:openssh-client:1", - "impactedPackageVersion": "9.2p1-2+deb12u3", - "impactedPackageType": "Debian", - "components": [ - { - "name": "sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar", - "version": "", - "location": { - "file": "sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar" - } - } - ], - "summary": "OpenSSH through 9.6, when common types of DRAM are used, might allow row hammer attacks (for authentication bypass) because the integer value of authenticated in mm_answer_authpassword does not resist flips of a single bit. NOTE: this is applicable to a certain threat model of attacker-victim co-location in which the attacker has user privileges.", - "applicable": "Applicable", - "fixedVersions": null, - "cves": [ - { - "id": "CVE-2023-51767", - "cvssV2": "", - "cvssV3": "7.0", - "applicability": { - "status": "Applicable", - "scannerDescription": "The CVE is always applicable.\n\nNote - The vulnerability is hardware-dependent." - } - } - ], - "issueId": "XRAY-585612", - "references": [ - "https://arxiv.org/abs/2309.02545", - "https://github.com/openssh/openssh-portable/blob/8241b9c0529228b4b86d88b1a6076fb9f97e4a99/monitor.c#L878", - "https://github.com/openssh/openssh-portable/blob/8241b9c0529228b4b86d88b1a6076fb9f97e4a99/auth-passwd.c#L77", - "https://bugzilla.redhat.com/show_bug.cgi?id=2255850", - "https://security-tracker.debian.org/tracker/CVE-2023-51767", - "https://ubuntu.com/security/CVE-2023-51767", - "https://security.netapp.com/advisory/ntap-20240125-0006/", - "https://access.redhat.com/security/cve/CVE-2023-51767" - ], - "impactPaths": [ - [ - { - "name": "platform.jfrog.io/swamp-docker/swamp", - "version": "latest" - }, - { - "name": "sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar", - "version": "", - "location": { - "file": "sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar" - } - }, - { - "name": "debian:bookworm:openssh-client:1", - "version": "9.2p1-2+deb12u3", - "location": { - "file": "openssh-client:1:9.2p1-2+deb12u3" - } - } - ] - ], - "jfrogResearchInformation": { - "severity": "Low", - "summary": "The RowHammer fault injection attack can theoretically lead to local authentication bypass in OpenSSH.", - "details": "[OpenSSH](https://www.openssh.com/) is a popular open-source implementation of the SSH (Secure Shell) protocol, providing encrypted communication over a network.\nIt was discovered that the OpenSSH authentication logic can be susceptible in some cases to a side-channel fault injection attack. The attack can theoretically be carried out by a local attacker which eventually bypass OpenSSH authentication mechanism.\n\nThis vulnerability currently lacks widely known published exploits, and its exploitation is considered highly complex. The intricacies of the attack, combined with the absence of well-documented exploits, contribute to the difficulty in achieving successful exploitation. Furthermore, it's essential to note that the susceptibility to this vulnerability is hardware-dependent, and the success of an attack relies on probabilities associated with the specific hardware configuration. \n\nThe vulnerability is theoretically exploitable by several different ways, the only two published ways are:\n\nIn the OpenSSH function `mm_answer_authpassword()`, a stack variable `authenticated`, is assigned to the value of the function `auth_password()` which returns 1/0 and then returned. If the value of `authenticated` is 1, the SSH connection will be established. Since `authenticated` is stored on the stack, therefore in DRAM, a local attacker could flip this 32-bit integer least significant bit, thus, bypass authentication.\n\nAnother possible exploit is the `result` stack variable in `auth_password()` function. It is initialized to 0 and set to 1 if the password is correct. \nSimilarly to the previous method, this attack requires a single bit flip of the `result` variable in order for the function to return 1 and bypass the authentication.\n\nAttackers can trigger the vulnerability via a RowHammer fault injection. The Rowhammer bug is a hardware reliability issue in which an attacker repeatedly accesses (hammers) DRAM cells to cause unauthorized changes in physically adjacent memory locations.\nSimply put:\n\n* A specific register value(`authenticated`/`result` value) is pushed onto the stack during program execution. \n* The stack, where the register value is stored, is identified to be located in a memory row susceptible to bit flips (flippable row) due to the RowHammer vulnerability in DRAM.\n* The attacker performs a series of rapid and repeated memory accesses to the adjacent rows of the flippable row in the DRAM. This repeated access exploits the RowHammer vulnerability, inducing bit flips in the targeted flippable row.\n* Due to the RowHammer effect, bit flips occur in the flippable row, potentially corrupting the data stored there.\n* After inducing bit flips in the flippable row, the attacker manipulates the program's control flow to pop the corrupted value from the stack into a register.\n* The register now holds a value that has been corrupted through the RowHammer attack. Now the `authenticated`/`result` variables hold this corrupted value thus it can lead to authentication bypass, as it may impact the control flow in a way advantageous to the attacker.", - "severityReasons": [ - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "The vulnerability depends on the OS and hardware. It was only evaluated in one test environment, therefore results for other conditions might differ. The attacker must be extremely familiar with the details of the exploited system (ex. know the exact hardware which is running the OS).", - "isPositive": true - }, - { - "name": "The issue can only be exploited by an attacker that can execute code on the vulnerable machine (excluding exceedingly rare circumstances)", - "isPositive": true - }, - { - "name": "No high-impact exploit or technical writeup were published, and exploitation of the issue with high impact is either non-trivial or completely unproven", - "description": "Exploitation is extremely non-trivial (even theoretically), no public exploits have been published.", - "isPositive": true - }, - { - "name": "The reported CVSS was either wrongly calculated, downgraded by other vendors, or does not reflect the vulnerability's impact", - "description": "The vulnerability's attack complexity is significantly higher than what the CVSS represents.", - "isPositive": true - } - ] - } - }, - { - "severity": "Unknown", "impactedPackageName": "debian:bookworm:libssl3", "impactedPackageVersion": "3.0.13-1~deb12u1", "impactedPackageType": "Debian", @@ -210,30 +14,22 @@ } } ], - "summary": "CVE-2024-4741", - "applicable": "Applicable", + "summary": "Interpretation Conflict", + "applicable": "Undetermined", "fixedVersions": null, "cves": [ { - "id": "CVE-2024-4741", + "id": "CVE-2024-38428", "cvssV2": "", "cvssV3": "", "applicability": { - "status": "Applicable", - "scannerDescription": "The scanner checks whether the vulnerable function `SSL_free_buffers` is called.", - "evidence": [ - { - "file": "usr/local/bin/node", - "reason": "References to the vulnerable functions were found" - } - ] + "status": "Undetermined", + "scannerDescription": "The Scanner checks for CVE-2024-38428" } } ], - "issueId": "XRAY-603657", - "references": [ - "https://security-tracker.debian.org/tracker/CVE-2024-4741" - ], + "issueId": "XRAY-606103", + "references": null, "impactPaths": [ [ { @@ -256,10 +52,12 @@ } ] ], - "jfrogResearchInformation": null + "jfrogResearchInformation": { + "severity": "Critical" + } }, { - "severity": "Unknown", + "severity": "Critical", "impactedPackageName": "debian:bookworm:openssl", "impactedPackageVersion": "3.0.13-1~deb12u1", "impactedPackageType": "Debian", @@ -272,32 +70,24 @@ } } ], - "summary": "CVE-2024-4741", - "applicable": "Applicable", + "summary": "Interpretation Conflict", + "applicable": "Undetermined", "fixedVersions": [ - "[3.0.14-1~deb12u1]" + "[3.0.14-1~deb12u2]" ], "cves": [ { - "id": "CVE-2024-4741", + "id": "CVE-2024-38428", "cvssV2": "", "cvssV3": "", "applicability": { - "status": "Applicable", - "scannerDescription": "The scanner checks whether the vulnerable function `SSL_free_buffers` is called.", - "evidence": [ - { - "file": "usr/local/bin/node", - "reason": "References to the vulnerable functions were found" - } - ] + "status": "Undetermined", + "scannerDescription": "The Scanner checks for CVE-2024-38428" } } ], - "issueId": "XRAY-603657", - "references": [ - "https://security-tracker.debian.org/tracker/CVE-2024-4741" - ], + "issueId": "XRAY-606103", + "references": null, "impactPaths": [ [ { @@ -320,7 +110,9 @@ } ] ], - "jfrogResearchInformation": null + "jfrogResearchInformation": { + "severity": "Critical" + } }, { "severity": "Unknown", @@ -336,7 +128,7 @@ } } ], - "summary": "Issue summary: Applications performing certificate name checks (e.g., TLS\nclients checking server certificates) may attempt to read an invalid memory\naddress resulting in abnormal termination of the application process.\n\nImpact summary: Abnormal termination of an application can a cause a denial of\nservice.\n\nApplications performing certificate name checks (e.g., TLS clients checking\nserver certificates) may attempt to read an invalid memory address when\ncomparing the expected name with an `otherName` subject alternative name of an\nX.509 certificate. This may result in an exception that terminates the\napplication program.\n\nNote that basic certificate chain validation (signatures, dates, ...) is not\naffected, the denial of service can occur only when the application also\nspecifies an expected DNS name, Email address or IP address.\n\nTLS servers rarely solicit client certificates, and even when they do, they\ngenerally don't perform a name check against a reference identifier (expected\nidentity), but rather extract the presented identity after checking the\ncertificate chain. So TLS servers are generally not affected and the severity\nof the issue is Moderate.\n\nThe FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.", + "summary": "Issue summary", "applicable": "Applicable", "fixedVersions": null, "cves": [ @@ -346,25 +138,18 @@ "cvssV3": "", "applicability": { "status": "Applicable", - "scannerDescription": "The scanner checks whether any of the following vulnerable functions are called:\n\n- `X509_VERIFY_PARAM_set1_email`\n\n- `X509_check_email`\n\n- `X509_VERIFY_PARAM_set1_host`\n\n- `X509_check_host`", + "scannerDescription": "The Scanner checks for CVE-2024-6119", "evidence": [ { "file": "usr/local/bin/node", - "reason": "References to the vulnerable functions were found" + "reason": "ca msg" } ] } } ], "issueId": "XRAY-632747", - "references": [ - "https://openssl-library.org/news/secadv/20240903.txt", - "https://github.com/openssl/openssl/commit/621f3729831b05ee828a3203eddb621d014ff2b2", - "https://github.com/openssl/openssl/commit/05f360d9e849a1b277db628f1f13083a7f8dd04f", - "https://security-tracker.debian.org/tracker/CVE-2024-6119", - "https://github.com/openssl/openssl/commit/7dfcee2cd2a63b2c64b9b4b0850be64cb695b0a0", - "https://github.com/openssl/openssl/commit/06d1dc3fa96a2ba5a3e22735a033012aadc9f0d6" - ], + "references": null, "impactPaths": [ [ { @@ -388,29 +173,14 @@ ] ], "jfrogResearchInformation": { - "severity": "Medium", - "summary": "Out of bounds read in OpenSSL clients can lead to denial of service when using non-default TLS verification options and connecting to malicious TLS servers", - "severityReasons": [ - { - "name": "The issue has an exploit published", - "description": "The fix commit contains PoC certificates that trigger the denial of service issue" - }, - { - "name": "The prerequisites for exploiting the issue are extremely unlikely", - "description": "The attacker must make the victim client connect to their malicious TLS server, in order to serve the malformed TLS certificate. The victim client must use OpenSSL and must enable non-default certificate verification options, either -\n\n* DNS verification - by using `X509_VERIFY_PARAM_set1_host` or `X509_check_host`\n* Email verification - by using ` X509_VERIFY_PARAM_set1_email` or `X509_check_email`", - "isPositive": true - }, - { - "name": "The issue cannot result in a severe impact (such as remote code execution)", - "description": "Denial of service of a TLS clients only. This out of bounds read cannot lead to data disclosure.", - "isPositive": true - } - ] + "severity": "Medium" } - }, + } + ], + "securityViolations": [ { "severity": "Unknown", - "impactedPackageName": "debian:bookworm:openssl", + "impactedPackageName": "debian:bookworm:libssl3", "impactedPackageVersion": "3.0.13-1~deb12u1", "impactedPackageType": "Debian", "components": [ @@ -422,11 +192,13 @@ } } ], - "summary": "Issue summary: Applications performing certificate name checks (e.g., TLS\nclients checking server certificates) may attempt to read an invalid memory\naddress resulting in abnormal termination of the application process.\n\nImpact summary: Abnormal termination of an application can a cause a denial of\nservice.\n\nApplications performing certificate name checks (e.g., TLS clients checking\nserver certificates) may attempt to read an invalid memory address when\ncomparing the expected name with an `otherName` subject alternative name of an\nX.509 certificate. This may result in an exception that terminates the\napplication program.\n\nNote that basic certificate chain validation (signatures, dates, ...) is not\naffected, the denial of service can occur only when the application also\nspecifies an expected DNS name, Email address or IP address.\n\nTLS servers rarely solicit client certificates, and even when they do, they\ngenerally don't perform a name check against a reference identifier (expected\nidentity), but rather extract the presented identity after checking the\ncertificate chain. So TLS servers are generally not affected and the severity\nof the issue is Moderate.\n\nThe FIPS modules in 3.3, 3.2, 3.1 and 3.0 are not affected by this issue.", - "applicable": "Applicable", - "fixedVersions": [ - "[3.0.14-1~deb12u2]" + "watch": "security-watch", + "policies": [ + "debian-security" ], + "summary": "Issue summary", + "applicable": "Applicable", + "fixedVersions": null, "cves": [ { "id": "CVE-2024-6119", @@ -434,25 +206,18 @@ "cvssV3": "", "applicability": { "status": "Applicable", - "scannerDescription": "The scanner checks whether any of the following vulnerable functions are called:\n\n- `X509_VERIFY_PARAM_set1_email`\n\n- `X509_check_email`\n\n- `X509_VERIFY_PARAM_set1_host`\n\n- `X509_check_host`", + "scannerDescription": "The Scanner checks for CVE-2024-6119", "evidence": [ { "file": "usr/local/bin/node", - "reason": "References to the vulnerable functions were found" + "reason": "ca msg" } ] } } ], "issueId": "XRAY-632747", - "references": [ - "https://openssl-library.org/news/secadv/20240903.txt", - "https://github.com/openssl/openssl/commit/621f3729831b05ee828a3203eddb621d014ff2b2", - "https://github.com/openssl/openssl/commit/05f360d9e849a1b277db628f1f13083a7f8dd04f", - "https://security-tracker.debian.org/tracker/CVE-2024-6119", - "https://github.com/openssl/openssl/commit/7dfcee2cd2a63b2c64b9b4b0850be64cb695b0a0", - "https://github.com/openssl/openssl/commit/06d1dc3fa96a2ba5a3e22735a033012aadc9f0d6" - ], + "references": null, "impactPaths": [ [ { @@ -467,360 +232,71 @@ } }, { - "name": "debian:bookworm:openssl", + "name": "debian:bookworm:libssl3", "version": "3.0.13-1~deb12u1", "location": { - "file": "openssl:3.0.13-1~deb12u1" - } - } - ] - ], - "jfrogResearchInformation": { - "severity": "Medium", - "summary": "Out of bounds read in OpenSSL clients can lead to denial of service when using non-default TLS verification options and connecting to malicious TLS servers", - "severityReasons": [ - { - "name": "The issue has an exploit published", - "description": "The fix commit contains PoC certificates that trigger the denial of service issue" - }, - { - "name": "The prerequisites for exploiting the issue are extremely unlikely", - "description": "The attacker must make the victim client connect to their malicious TLS server, in order to serve the malformed TLS certificate. The victim client must use OpenSSL and must enable non-default certificate verification options, either -\n\n* DNS verification - by using `X509_VERIFY_PARAM_set1_host` or `X509_check_host`\n* Email verification - by using ` X509_VERIFY_PARAM_set1_email` or `X509_check_email`", - "isPositive": true - }, - { - "name": "The issue cannot result in a severe impact (such as remote code execution)", - "description": "Denial of service of a TLS clients only. This out of bounds read cannot lead to data disclosure.", - "isPositive": true - } - ] - } - }, - { - "severity": "Critical", - "impactedPackageName": "debian:bookworm:libexpat1", - "impactedPackageVersion": "2.5.0-1", - "impactedPackageType": "Debian", - "components": [ - { - "name": "sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar", - "version": "", - "location": { - "file": "sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar" - } - } - ], - "summary": "An issue was discovered in libexpat before 2.6.3. xmlparse.c does not reject a negative length for XML_ParseBuffer.", - "applicable": "Not Applicable", - "fixedVersions": null, - "cves": [ - { - "id": "CVE-2024-45490", - "cvssV2": "", - "cvssV3": "9.8", - "applicability": { - "status": "Not Applicable", - "scannerDescription": "The scanner checks whether any of the following vulnerable functions are called:\n\n- `XML_Parse()`\n- `XML_ParseBuffer()`\n\nAn additional condition, which the scanner currently does not check, is that the `len` parameter which is passed to those functions is user-controlled." - } - } - ], - "issueId": "XRAY-632613", - "references": [ - "https://github.com/libexpat/libexpat/issues/887", - "https://security-tracker.debian.org/tracker/CVE-2024-45490", - "https://github.com/libexpat/libexpat/pull/890" - ], - "impactPaths": [ - [ - { - "name": "platform.jfrog.io/swamp-docker/swamp", - "version": "latest" - }, - { - "name": "sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar", - "version": "", - "location": { - "file": "sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar" - } - }, - { - "name": "debian:bookworm:libexpat1", - "version": "2.5.0-1", - "location": { - "file": "libexpat1:2.5.0-1" - } - } - ] - ], - "jfrogResearchInformation": null - }, - { - "severity": "Critical", - "impactedPackageName": "debian:bookworm:libexpat1", - "impactedPackageVersion": "2.5.0-1", - "impactedPackageType": "Debian", - "components": [ - { - "name": "sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar", - "version": "", - "location": { - "file": "sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar" - } - } - ], - "summary": "An issue was discovered in libexpat before 2.6.3. nextScaffoldPart in xmlparse.c can have an integer overflow for m_groupSize on 32-bit platforms (where UINT_MAX equals SIZE_MAX).", - "applicable": "Not Applicable", - "fixedVersions": null, - "cves": [ - { - "id": "CVE-2024-45492", - "cvssV2": "", - "cvssV3": "9.8", - "applicability": { - "status": "Not Applicable", - "scannerDescription": "The scanner checks whether the current binary was compiled with 32-bit architecture and if any of the vulnerable functions are called:\n\n- `XML_ParseBuffer()`\n- `XML_Parse()`\n\nNote - the vulnerability occurs when certain inputs are passed to those functions." - } - } - ], - "issueId": "XRAY-632612", - "references": [ - "https://github.com/libexpat/libexpat/issues/889", - "https://security-tracker.debian.org/tracker/CVE-2024-45492", - "https://github.com/libexpat/libexpat/pull/892" - ], - "impactPaths": [ - [ - { - "name": "platform.jfrog.io/swamp-docker/swamp", - "version": "latest" - }, - { - "name": "sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar", - "version": "", - "location": { - "file": "sha256__20f026ae0a91ba4668a54b46f39853dd4c114a84cfedb4144ff24521d3e6dcb1.tar" - } - }, - { - "name": "debian:bookworm:libexpat1", - "version": "2.5.0-1", - "location": { - "file": "libexpat1:2.5.0-1" - } - } - ] - ], - "jfrogResearchInformation": null - }, - { - "severity": "Low", - "impactedPackageName": "debian:bookworm:apt", - "impactedPackageVersion": "2.6.1", - "impactedPackageType": "Debian", - "components": [ - { - "name": "sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar", - "version": "", - "location": { - "file": "sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar" - } - } - ], - "summary": "It was found that apt-key in apt, all versions, do not correctly validate gpg keys with the master keyring, leading to a potential man-in-the-middle attack.", - "applicable": "Not Applicable", - "fixedVersions": null, - "cves": [ - { - "id": "CVE-2011-3374", - "cvssV2": "4.3", - "cvssV3": "3.7", - "applicability": { - "status": "Not Applicable", - "scannerDescription": "The scanner checks if the vulnerable variable `ARCHIVE_KEYRING_URI` in `/usr/bin/apt-key` is not empty and not commented out. This is the URI that an attacker would need to target in a Man-in-the-Middle attack.\n\nThe below prerequisites are also crucial for exploitability but are not checked in the scanner:\n\n1. The command apt-key net-update should be executed on the affected system, or alternatively `apt.auth.net_update()` function from the `python-apt` Python module should be called. This is for the malicious keys download.\n\n2. After the execution of `apt-key net-update`, APT packages should be installed or updated on the machine." - } - } - ], - "issueId": "XRAY-34417", - "references": [ - "https://people.canonical.com/~ubuntu-security/cve/2011/CVE-2011-3374.html", - "https://seclists.org/fulldisclosure/2011/Sep/221", - "https://ubuntu.com/security/CVE-2011-3374", - "https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=642480", - "https://access.redhat.com/security/cve/cve-2011-3374", - "https://snyk.io/vuln/SNYK-LINUX-APT-116518", - "https://security-tracker.debian.org/tracker/CVE-2011-3374" - ], - "impactPaths": [ - [ - { - "name": "platform.jfrog.io/swamp-docker/swamp", - "version": "latest" - }, - { - "name": "sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar", - "version": "", - "location": { - "file": "sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar" - } - }, - { - "name": "debian:bookworm:apt", - "version": "2.6.1", - "location": { - "file": "apt:2.6.1" - } - } - ] - ], - "jfrogResearchInformation": { - "severity": "High", - "summary": "Improper signature validation in apt-key may enable Man-in-the-Middle attacks and result in code execution.", - "details": "`apt-key` is [`apt`](https://github.com/Debian/apt)'s key management utility, and is used to manage the keys that are used by `apt` to authenticate packages.\n\nA vulnerability in `apt-key`'s `net-update` function exists, in which [`GPG`](https://www.gnupg.org/) keys, that are used for signing packages and validating their authenticity, aren't validated correctly. The `net-update` function pulls the signing keys that should be added from an insecure location (`http://...`), exposing it to a Man-in-the-Middle attack in which malicious signing keys could be added to the system's keyring. This issue happens due to a vulnerability in the `add_keys_with_veirfy_against_master_keyring()` function, which allows adding signing keys without proper signature validation. \n\nThis vulnerability then potentially allows a malicious actor to perform a Man-in-the-Middle attack on a target, by making it validate malicious packages that were signed with the `GPG` signing key used by the attacker. Effectively, this means that `apt` can be duped to install malicious services and daemons with root privileges.\n\nThe conditions for this vulnerability to be applicable:\n \n1. A valid URI should be configured in `ARCHIVE_KEYRING_URI` variable in the file `/usr/bin/apt-key`. This is the URI that an attacker would need to target in a Man In The Middle attack.\n2. The command `apt-key net-update` should be executed on the affected system, or alternatively `apt.auth.net_update()` function from [python-apt](https://pypi.org/project/python-apt/) Python module should be called. This is for the malicious keys download.\n3. After the execution of `apt-key net-update`, APT packages should be installed or updated on the machine.\n\nDo note that `apt-key` is **deprecated** and shouldn't be used, and in most Debian versions `ARCHIVE_KEYRING_URI` is not defined, making this vulnerability unexploitable in most Debian systems.", - "severityReasons": [ - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "The conditions for this vulnerability to be applicable:\n \n1. A valid URI should be configured in `ARCHIVE_KEYRING_URI` variable in the file `/usr/bin/apt-key`. This is the URI that an attacker would need to target in a Man-in-the-Middle attack.\n2. The command `apt-key net-update` should be executed on the affected system, or alternatively `apt.auth.net_update()` function from the python-apt Python module should be called. This is for the malicious keys download.\n3. After the execution of `apt-key net-update`, APT packages should be installed or updated on the machine.", - "isPositive": true - }, - { - "name": "The issue can be exploited by attackers over the network", - "description": "This vulnerability is remotely exploitable when the applicability conditions apply." - }, - { - "name": "The issue results in a severe impact (such as remote code execution)", - "description": "Remote code execution is possible when the applicability conditions apply." - }, - { - "name": "The issue has an exploit published", - "description": "The reporter of this issue has provided a GPG key that can be used for an actual attack, as well as a simple PoC example." - } - ], - "remediation": "##### Deployment mitigations\n\n* Dot not execute `apt-key` command, as it is deprecated.\n* Remove the URI configured in `ARCHIVE_KEYRING_URI` variable in the file `/usr/bin/apt-key`." - } - }, - { - "severity": "Low", - "impactedPackageName": "debian:bookworm:libapt-pkg6.0", - "impactedPackageVersion": "2.6.1", - "impactedPackageType": "Debian", - "components": [ - { - "name": "sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar", - "version": "", - "location": { - "file": "sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar" - } - } - ], - "summary": "It was found that apt-key in apt, all versions, do not correctly validate gpg keys with the master keyring, leading to a potential man-in-the-middle attack.", - "applicable": "Not Applicable", - "fixedVersions": null, - "cves": [ - { - "id": "CVE-2011-3374", - "cvssV2": "4.3", - "cvssV3": "3.7", - "applicability": { - "status": "Not Applicable", - "scannerDescription": "The scanner checks if the vulnerable variable `ARCHIVE_KEYRING_URI` in `/usr/bin/apt-key` is not empty and not commented out. This is the URI that an attacker would need to target in a Man-in-the-Middle attack.\n\nThe below prerequisites are also crucial for exploitability but are not checked in the scanner:\n\n1. The command apt-key net-update should be executed on the affected system, or alternatively `apt.auth.net_update()` function from the `python-apt` Python module should be called. This is for the malicious keys download.\n\n2. After the execution of `apt-key net-update`, APT packages should be installed or updated on the machine." - } - } - ], - "issueId": "XRAY-34417", - "references": [ - "https://people.canonical.com/~ubuntu-security/cve/2011/CVE-2011-3374.html", - "https://seclists.org/fulldisclosure/2011/Sep/221", - "https://ubuntu.com/security/CVE-2011-3374", - "https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=642480", - "https://access.redhat.com/security/cve/cve-2011-3374", - "https://snyk.io/vuln/SNYK-LINUX-APT-116518", - "https://security-tracker.debian.org/tracker/CVE-2011-3374" - ], - "impactPaths": [ - [ - { - "name": "platform.jfrog.io/swamp-docker/swamp", - "version": "latest" - }, - { - "name": "sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar", - "version": "", - "location": { - "file": "sha256__cedb364ef937c7e51179d8e514bdd98644bac5fdc82a45d784ef91afe4bc647e.tar" - } - }, - { - "name": "debian:bookworm:libapt-pkg6.0", - "version": "2.6.1", - "location": { - "file": "libapt-pkg6.0:2.6.1" + "file": "libssl3:3.0.13-1~deb12u1" } } ] ], "jfrogResearchInformation": { - "severity": "High", - "summary": "Improper signature validation in apt-key may enable Man-in-the-Middle attacks and result in code execution.", - "details": "`apt-key` is [`apt`](https://github.com/Debian/apt)'s key management utility, and is used to manage the keys that are used by `apt` to authenticate packages.\n\nA vulnerability in `apt-key`'s `net-update` function exists, in which [`GPG`](https://www.gnupg.org/) keys, that are used for signing packages and validating their authenticity, aren't validated correctly. The `net-update` function pulls the signing keys that should be added from an insecure location (`http://...`), exposing it to a Man-in-the-Middle attack in which malicious signing keys could be added to the system's keyring. This issue happens due to a vulnerability in the `add_keys_with_veirfy_against_master_keyring()` function, which allows adding signing keys without proper signature validation. \n\nThis vulnerability then potentially allows a malicious actor to perform a Man-in-the-Middle attack on a target, by making it validate malicious packages that were signed with the `GPG` signing key used by the attacker. Effectively, this means that `apt` can be duped to install malicious services and daemons with root privileges.\n\nThe conditions for this vulnerability to be applicable:\n \n1. A valid URI should be configured in `ARCHIVE_KEYRING_URI` variable in the file `/usr/bin/apt-key`. This is the URI that an attacker would need to target in a Man In The Middle attack.\n2. The command `apt-key net-update` should be executed on the affected system, or alternatively `apt.auth.net_update()` function from [python-apt](https://pypi.org/project/python-apt/) Python module should be called. This is for the malicious keys download.\n3. After the execution of `apt-key net-update`, APT packages should be installed or updated on the machine.\n\nDo note that `apt-key` is **deprecated** and shouldn't be used, and in most Debian versions `ARCHIVE_KEYRING_URI` is not defined, making this vulnerability unexploitable in most Debian systems.", - "severityReasons": [ - { - "name": "Exploitation of the issue is only possible when the vulnerable component is used in a specific manner. The attacker has to perform per-target research to determine the vulnerable attack vector", - "description": "The conditions for this vulnerability to be applicable:\n \n1. A valid URI should be configured in `ARCHIVE_KEYRING_URI` variable in the file `/usr/bin/apt-key`. This is the URI that an attacker would need to target in a Man-in-the-Middle attack.\n2. The command `apt-key net-update` should be executed on the affected system, or alternatively `apt.auth.net_update()` function from the python-apt Python module should be called. This is for the malicious keys download.\n3. After the execution of `apt-key net-update`, APT packages should be installed or updated on the machine.", - "isPositive": true - }, - { - "name": "The issue can be exploited by attackers over the network", - "description": "This vulnerability is remotely exploitable when the applicability conditions apply." - }, - { - "name": "The issue results in a severe impact (such as remote code execution)", - "description": "Remote code execution is possible when the applicability conditions apply." - }, - { - "name": "The issue has an exploit published", - "description": "The reporter of this issue has provided a GPG key that can be used for an actual attack, as well as a simple PoC example." - } - ], - "remediation": "##### Deployment mitigations\n\n* Dot not execute `apt-key` command, as it is deprecated.\n* Remove the URI configured in `ARCHIVE_KEYRING_URI` variable in the file `/usr/bin/apt-key`." + "severity": "Medium" } } ], - "securityViolations": null, "licensesViolations": null, "licenses": null, "operationalRiskViolations": null, "secrets": [ { "severity": "Medium", - "file": "usr/src/app/server/scripts/__pycache__/fetch_github_repo.cpython-311.pyc", - "snippet": "htt************", - "finding": "Hardcoded secrets were found", - "scannerDescription": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, - { - "severity": "Medium", - "file": "private/var/folders/xv/th4cksxn7jv9wjrdnn1h4tj00000gq/T/tmpsfyn_3d1/unpacked/filesystem/blobs/sha256/9e88ea9de1b44baba5e96a79e33e4af64334b2bf129e838e12f6dae71b5c86f0/usr/src/app/server/index.js", + "ruleId": "REQ.SECRET.GENERIC.CODE", + "scannerShortDescription": "Scanner for REQ.SECRET.GENERIC.CODE", + "scannerDescription": "The Scanner checks for REQ.SECRET.GENERIC.CODE", + "file": "temp/folders/T/tmpsfyn_3d1/unpacked/sha256/9e88ea9de1b44baba5e96a79e33e4af64334b2bf129e838e12f6dae71b5c86f0/usr/src/app/server/index.js", "startLine": 5, "startColumn": 7, "endLine": 5, "endColumn": 57, "snippet": "tok************", - "finding": "Hardcoded secrets were found", - "scannerDescription": "Storing hardcoded secrets in your source code or binary artifact could lead to several risks.\n\nIf the secret is associated with a wide scope of privileges, attackers could extract it from the source code or binary artifact and use it maliciously to attack many targets. For example, if the hardcoded password gives high-privilege access to an AWS account, the attackers may be able to query/modify company-wide sensitive data without per-user authentication.\n\n## Best practices\n\nUse safe storage when storing high-privilege secrets such as passwords and tokens, for example -\n\n* ### Environment Variables\n\nEnvironment variables are set outside of the application code, and can be dynamically passed to the application only when needed, for example -\n`SECRET_VAR=MySecret ./my_application`\nThis way, `MySecret` does not have to be hardcoded into `my_application`.\n\nNote that if your entire binary artifact is published (ex. a Docker container published to Docker Hub), the value for the environment variable must not be stored in the artifact itself (ex. inside the `Dockerfile` or one of the container's files) but rather must be passed dynamically, for example in the `docker run` call as an argument.\n\n* ### Secret management services\n\nExternal vendors offer cloud-based secret management services, that provide proper access control to each secret. The given access to each secret can be dynamically modified or even revoked. Some examples include -\n\n* [Hashicorp Vault](https://www.vaultproject.io)\n* [AWS KMS](https://aws.amazon.com/kms) (Key Management Service)\n* [Google Cloud KMS](https://cloud.google.com/security-key-management)\n\n## Least-privilege principle\n\nStoring a secret in a hardcoded manner can be made safer, by making sure the secret grants the least amount of privilege as needed by the application.\nFor example - if the application needs to read a specific table from a specific database, and the secret grants access to perform this operation **only** (meaning - no access to other tables, no write access at all) then the damage from any secret leaks is mitigated.\nThat being said, it is still not recommended to store secrets in a hardcoded manner, since this type of storage does not offer any way to revoke or moderate the usage of the secret.\n" - }, + "finding": "Secret REQ.SECRET.GENERIC.CODE were found", + "applicability": { + "status": "Inactive", + "scannerDescription": "expired" + } + } + ], + "iac": null, + "sast": null, + "secretsViolations": [ { "severity": "Medium", - "file": "private/var/folders/xv/th4cksxn7jv9wjrdnn1h4tj00000gq/T/tmpsfyn_3d1/unpacked/filesystem/blobs/sha256/9e88ea9de1b44baba5e96a79e33e4af64334b2bf129e838e12f6dae71b5c86f0/usr/src/app/server/index.js", - "startLine": 6, - "startColumn": 14, - "endLine": 6, - "endColumn": 24, - "snippet": "eyJ************", - "finding": "Secret keys were found", - "scannerDescription": "\nStoring an API key in the image could lead to several risks.\n\nIf the key is associated with a wide scope of privileges, attackers could extract it from a single image or firmware and use it maliciously to attack many targets. For example, if the embedded key allows querying/modifying data for all cloud user accounts, without per-user authentication, the attackers who extract it would gain access to system-wide data.\n\nIf the cloud/SaaS provider bills by key usage - for example, every million queries cost the key's owner a fixed sum of money - attackers could use the keys for their own purposes (or just as a form of vandalism), incurring a large cost to the legitimate user or operator.\n\n## Best practices\n\nUse narrow scopes for stored API keys. As much as possible, API keys should be unique per host and require additional authentication with the user's individual credentials for any sensitive actions.\n\nAvoid placing keys whose use incurs costs directly in the image. Store the key with any software or hardware protection available on the host for key storage (such as operating system key-stores, hardware cryptographic storage mechanisms or cloud-managed secure storage services such as [AWS KMS](https://aws.amazon.com/kms/)).\n\nTokens that were detected as exposed should be revoked and replaced -\n\n* [AWS Key Revocation](https://aws.amazon.com/premiumsupport/knowledge-center/delete-access-key/#:~:text=If%20you%20see%20a%20warning,the%20confirmation%20box%2C%20choose%20Deactivate.)\n* [GCP Key Revocation](https://www.trendmicro.com/cloudoneconformity/knowledge-base/gcp/CloudIAM/delete-api-keys.html)\n* [Azure Key Revocation](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows#revoke-a-pat)\n* [GitHub Key Revocation](https://docs.github.com/en/rest/apps/oauth-applications#delete-an-app-authorization)\n" + "watch": "watch", + "issueId": "sec-violation-1", + "ruleId": "REQ.SECRET.GENERIC.CODE", + "scannerShortDescription": "Scanner for REQ.SECRET.GENERIC.CODE", + "scannerDescription": "The Scanner checks for REQ.SECRET.GENERIC.CODE", + "file": "temp/folders/T/tmpsfyn_3d1/unpacked/sha256/9e88ea9de1b44baba5e96a79e33e4af64334b2bf129e838e12f6dae71b5c86f0/usr/src/app/server/index.js", + "startLine": 5, + "startColumn": 7, + "endLine": 5, + "endColumn": 57, + "snippet": "tok************", + "finding": "Secret REQ.SECRET.GENERIC.CODE were found", + "applicability": { + "status": "Inactive", + "scannerDescription": "expired" + } } ], "iacViolations": null, "sastViolations": null, - "errors": null -} + "errors": null, + "scansStatus": { + "scaScanStatusCode": 0, + "secretsScanStatusCode": 0, + "ContextualAnalysisScanStatusCode": 0 + }, + "multiScanId": "7d5e4733-3f93-11ef-8147-e610d09d7daa" +} \ No newline at end of file diff --git a/tests/testdata/output/dockerscan/docker_summary.json b/tests/testdata/output/dockerscan/docker_summary.json index 68145da6..2d56aca9 100644 --- a/tests/testdata/output/dockerscan/docker_summary.json +++ b/tests/testdata/output/dockerscan/docker_summary.json @@ -1,56 +1,44 @@ { - "scans": [ - { - "target": "/var/folders/xv/th4cksxn7jv9wjrdnn1h4tj00000gq/T/jfrog.cli.temp.-1726210535-1985298017/image.tar", - "name": "platform.jfrog.io/swamp-docker/swamp:latest", - "vulnerabilities": { - "sca": { - "scan_ids": [ - "27da9106-88ea-416b-799b-bc7d15783473" - ], - "security": { - "Critical": { - "Not Applicable": 2, - "Not Covered": 1, - "Undetermined": 1 - }, - "Low": { - "Applicable": 1, - "Not Applicable": 1 - }, - "Unknown": { - "Applicable": 2 - } - } - }, - "iac": {}, - "secrets": { - "Medium": { - "": 3 - } - }, - "sast": {} - }, - "violations": { - "watches": [ - "Security_watch_2" + "scans": [ + { + "target": "temp/folders/T/jfrog.cli.temp.-11-11/image.tar", + "name": "platform.jfrog.io/swamp-docker/swamp:latest", + "vulnerabilities": { + "sca": { + "scan_ids": [ + "27da9106-88ea-416b-799b-bc7d15783473" ], - "sca": { - "scan_ids": [ - "27da9106-88ea-416b-799b-bc7d15783473" - ], - "security": { - "Critical": { - "Undetermined": 1 - } - } - }, - "secrets": { - "Medium": { - "": 2 + "security": { + "Critical": { + "Undetermined": 1 + }, + "Unknown": { + "Applicable": 1 } } + }, + "secrets": { + "Medium": { + "Inactive": 1 + } + } + }, + "violations": { + "watches": [ + "security-watch", + "watch" + ], + "sca": { + "scan_ids": [ + "27da9106-88ea-416b-799b-bc7d15783473" + ] + }, + "secrets": { + "Medium": { + "Inactive": 1 + } } } - ] - } \ No newline at end of file + } + ] +} \ No newline at end of file diff --git a/utils/formats/sarifutils/sarifutils.go b/utils/formats/sarifutils/sarifutils.go index 56dd67bd..937e895e 100644 --- a/utils/formats/sarifutils/sarifutils.go +++ b/utils/formats/sarifutils/sarifutils.go @@ -98,7 +98,7 @@ func GetToolVersion(run *sarif.Run) string { func CopyRun(run *sarif.Run) *sarif.Run { copy := CopyRunMetadata(run) - if copy.Tool.Driver != nil { + if run.Tool.Driver != nil { copy.Tool.Driver.Rules = CopyRules(run.Tool.Driver.Rules...) } for _, result := range run.Results { diff --git a/utils/results/conversion/convertor_test.go b/utils/results/conversion/convertor_test.go index 53bbb77f..1826c32d 100644 --- a/utils/results/conversion/convertor_test.go +++ b/utils/results/conversion/convertor_test.go @@ -2,6 +2,7 @@ package conversion import ( "fmt" + // "os" "path/filepath" "testing" @@ -33,35 +34,175 @@ const ( type conversionFormat string -func getAuditValidationParams() validations.ValidationParams { - return validations.ValidationParams{ - ExactResultsMatch: true, - - Total: &validations.TotalCount{Vulnerabilities: 19, Violations: 7}, +func TestConvertResults(t *testing.T) { + // auditInputResults := testUtils.ReadCmdScanResults(t, filepath.Join(testDataDir, "audit", "audit_results.json")) + // dockerScanInputResults := testUtils.ReadCmdScanResults(t, filepath.Join(testDataDir, "dockerscan", "docker_results.json")) - Vulnerabilities: &validations.VulnerabilityCount{ - ValidateScan: &validations.ScanCount{Sca: 12, Sast: 4, Secrets: 3}, - ValidateApplicabilityStatus: &validations.ApplicabilityStatusCount{Applicable: 1, NotApplicable: 7, NotCovered: 4}, + testCases := []struct { + cmdType utils.CommandType + contentFormat conversionFormat + // inputResults *results.SecurityCommandResults + expectedContentPath string + }{ + { + cmdType: utils.SourceCode, + contentFormat: SimpleJson, + // inputResults: auditInputResults, + expectedContentPath: filepath.Join(testDataDir, "audit", "audit_simple_json.json"), }, - - Violations: &validations.ViolationCount{ - ValidateScan: &validations.ScanCount{Sca: 5, Sast: 1, Secrets: 1}, - ValidateApplicabilityStatus: &validations.ApplicabilityStatusCount{Applicable: 1, NotApplicable: 4}, + { + cmdType: utils.SourceCode, + contentFormat: Sarif, + // inputResults: auditInputResults, + expectedContentPath: filepath.Join(testDataDir, "audit", "audit_sarif.json"), + }, + { + cmdType: utils.SourceCode, + contentFormat: Summary, + // inputResults: auditInputResults, + expectedContentPath: filepath.Join(testDataDir, "audit", "audit_summary.json"), + }, + { + cmdType: utils.DockerImage, + contentFormat: SimpleJson, + // inputResults: dockerScanInputResults, + expectedContentPath: filepath.Join(testDataDir, "dockerscan", "docker_simple_json.json"), + }, + { + cmdType: utils.DockerImage, + contentFormat: Sarif, + // inputResults: dockerScanInputResults, + expectedContentPath: filepath.Join(testDataDir, "dockerscan", "docker_sarif.json"), + }, + { + cmdType: utils.DockerImage, + contentFormat: Summary, + // inputResults: dockerScanInputResults, + expectedContentPath: filepath.Join(testDataDir, "dockerscan", "docker_summary.json"), }, } + + for _, testCase := range testCases { + t.Run(fmt.Sprintf("%s convert to %s", testCase.cmdType, testCase.contentFormat), func(t *testing.T) { + var validationParams validations.ValidationParams + var inputResults *results.SecurityCommandResults + switch testCase.cmdType { + case utils.SourceCode: + inputResults, validationParams = getAuditTestResults(testCase.contentFormat == Summary) + case utils.DockerImage: + inputResults, validationParams = getDockerScanTestResults(testCase.contentFormat == Summary) + default: + t.Fatalf("Unsupported command type: %s", testCase.cmdType) + } + pretty := false + if testCase.contentFormat == Sarif { + pretty = true + } + convertor := NewCommandResultsConvertor(ResultConvertParams{IncludeVulnerabilities: true, HasViolationContext: true, IncludeLicenses: true, Pretty: pretty}) + + switch testCase.contentFormat { + case SimpleJson: + validateSimpleJsonConversion(t, testUtils.ReadSimpleJsonResults(t, testCase.expectedContentPath), inputResults, convertor, validationParams) + case Sarif: + validateSarifConversion(t, testUtils.ReadSarifResults(t, testCase.expectedContentPath), inputResults, convertor, validationParams) + case Summary: + validateSummaryConversion(t, testUtils.ReadSummaryResults(t, testCase.expectedContentPath), inputResults, convertor, validationParams) + } + }) + } +} + +func validateSimpleJsonConversion(t *testing.T, expectedResults formats.SimpleJsonResults, inputResults *results.SecurityCommandResults, convertor *CommandResultsConvertor, validationParams validations.ValidationParams) { + validationParams.Expected = expectedResults + + actualResults, err := convertor.ConvertToSimpleJson(inputResults) + if !assert.NoError(t, err) { + return + } + validationParams.Actual = actualResults + + // content, err := utils.GetAsJsonBytes(actualResults, true, true) + // assert.NoError(t, err) + // os.WriteFile("/Users/assafa/Documents/code/jfrog-projects/jfrog-cli-security/tests/testdata/output/dockerscan/docker_simple_json.json", content, 0644) + + validations.ValidateCommandSimpleJsonOutput(t, validationParams) +} + +func validateSarifConversion(t *testing.T, expectedResults *sarif.Report, inputResults *results.SecurityCommandResults, convertor *CommandResultsConvertor, validationParams validations.ValidationParams) { + validationParams.Expected = expectedResults + + actualResults, err := convertor.ConvertToSarif(inputResults) + if !assert.NoError(t, err) { + return + } + validationParams.Actual = actualResults + + // content, err := utils.GetAsJsonBytes(actualResults, true, true) + // assert.NoError(t, err) + // os.WriteFile("/Users/assafa/Documents/code/jfrog-projects/jfrog-cli-security/tests/testdata/output/dockerscan/docker_sarif.json", content, 0644) + + validations.ValidateSarifIssuesCount(t, validationParams, actualResults) } -// 3 Vuln -// 5 SCA vuln (1 applic, 3 not applic, 1 not covered) -// 0 IAC vuln -// 0 SAST vuln -// 0 Secrets vuln -// 2 vio -// 2 SCA vio (1 applic, 1 not covered) -// 0 IAC vio -// 0 SAST vio -// 0 Secrets vio -func getAuditTestResults() *results.SecurityCommandResults { +func validateSummaryConversion(t *testing.T, expectedResults formats.ResultsSummary, inputResults *results.SecurityCommandResults, convertor *CommandResultsConvertor, validationParams validations.ValidationParams) { + validationParams.Expected = expectedResults + + actualResults, err := convertor.ConvertToSummary(inputResults) + if !assert.NoError(t, err) { + return + } + validationParams.Actual = actualResults + + // content, err := utils.GetAsJsonBytes(actualResults, true, true) + // assert.NoError(t, err) + // os.WriteFile("/Users/assafa/Documents/code/jfrog-projects/jfrog-cli-security/tests/testdata/output/dockerscan/docker_summary.json", content, 0644) + + validations.ValidateCommandSummaryOutput(t, validationParams) +} + +// func getAuditValidationParams() validations.ValidationParams { +// return validations.ValidationParams{ +// ExactResultsMatch: true, + +// Total: &validations.TotalCount{Vulnerabilities: 19, Violations: 7}, + +// Vulnerabilities: &validations.VulnerabilityCount{ +// ValidateScan: &validations.ScanCount{Sca: 12, Sast: 4, Secrets: 3}, +// ValidateApplicabilityStatus: &validations.ApplicabilityStatusCount{Applicable: 1, NotApplicable: 7, NotCovered: 4}, +// }, + +// Violations: &validations.ViolationCount{ +// ValidateScan: &validations.ScanCount{Sca: 5, Sast: 1, Secrets: 1}, +// ValidateApplicabilityStatus: &validations.ApplicabilityStatusCount{Applicable: 1, NotApplicable: 4}, +// }, +// } +// } + +func getAuditTestResults(unique bool) (*results.SecurityCommandResults, validations.ValidationParams) { + expected := validations.ValidationParams{ + ExactResultsMatch: true, + Total: &validations.TotalCount{Violations: 7, Licenses: 1}, + Violations: &validations.ViolationCount{ + ValidateScan: &validations.ScanCount{Sca: 3, Sast: 2, Secrets: 2}, + ValidateApplicabilityStatus: &validations.ApplicabilityStatusCount{Applicable: 1, NotCovered: 1}, + }, + } + if unique { + // Only count CVE findings, not impacted components + expected.Total.Vulnerabilities = 7 + expected.Vulnerabilities = &validations.VulnerabilityCount{ + ValidateScan: &validations.ScanCount{Sca: 4, Iac: 1, Secrets: 2}, + ValidateApplicabilityStatus: &validations.ApplicabilityStatusCount{Applicable: 1, NotApplicable: 2, NotCovered: 1}, + } + } else { + // Count all findings (pair of issueId+impactedComponent) + expected.Total.Vulnerabilities = 8 + expected.Vulnerabilities = &validations.VulnerabilityCount{ + ValidateScan: &validations.ScanCount{Sca: 5, Iac: 1, Secrets: 2}, + ValidateApplicabilityStatus: &validations.ApplicabilityStatusCount{Applicable: 1, NotApplicable: 3, NotCovered: 1}, + } + } + // Create basic command results to be converted to different formats cmdResults := results.NewCommandResults(utils.SourceCode) cmdResults.SetEntitledForJas(true).SetXrayVersion("3.107.13").SetXscVersion("1.12.5").SetMultiScanId("7d5e4733-3f93-11ef-8147-e610d09d7daa") npmTargetResults := cmdResults.NewScanResults(results.ScanTarget{Target: "/Users/user/project-with-issues", Technology: techutils.Npm}).SetDescriptors("/Users/user/project-with-issues/package.json") @@ -85,11 +226,20 @@ func getAuditTestResults() *results.SecurityCommandResults { }, }, IssueId: "XRAY-609848", - ExtendedInformation: &services.ExtendedInformation{JfrogResearchSeverity: "Low"}, + ExtendedInformation: &services.ExtendedInformation{ + ShortDescription: "ReDoS in Async may lead to denial of service while parsing", + JfrogResearchSeverity: "Low", + JfrogResearchSeverityReasons: []services.JfrogResearchSeverityReason{ + {Name: "The reported CVSS was either wrongly calculated", Description: "The reported CVSS does not reflect the severity of the vulnerability", IsPositive: true}, + }, + }, + References: []string{"https://github.com/zunak/CVE-2024-39249", "https://nvd.nist.gov/vuln/detail/CVE-2024-39249"}, }, { Cves: []services.Cve{{ Id: "CVE-2020-8203", + CvssV2Score: "5.8", + CvssV3Score: "7.4", }}, Summary: "Code Injection", Severity: severityutils.High.String(), @@ -108,7 +258,7 @@ func getAuditTestResults() *results.SecurityCommandResults { {ComponentId: "npm://ejs:3.1.6"}, }}, FixedVersions: []string{"[3.1.7]"}, - }, + }, }, IssueId: "XRAY-114089", ExtendedInformation: &services.ExtendedInformation{JfrogResearchSeverity: "Low"}, @@ -146,11 +296,12 @@ func getAuditTestResults() *results.SecurityCommandResults { FixedVersions: []string{"[4.17.5]"}, }, }, - IssueId: "XRAY-72918", + IssueId: "XRAY-72918", }, }, - Violations: []services.Violation{ + Violations: []services.Violation{ { + ViolationType: utils.ViolationTypeSecurity.String(), Cves: []services.Cve{{ Id: "CVE-2024-39249", }}, @@ -165,12 +316,13 @@ func getAuditTestResults() *results.SecurityCommandResults { }}, }, }, - WatchName: "security-watch", - Policies: []services.Policy{{Policy: "npm-security"}}, + WatchName: "security-watch", + Policies: []services.Policy{{Policy: "npm-security"}}, IssueId: "XRAY-609848", ExtendedInformation: &services.ExtendedInformation{JfrogResearchSeverity: "Low"}, }, { + ViolationType: utils.ViolationTypeSecurity.String(), Cves: []services.Cve{{ Id: "CVE-2018-3721", }}, @@ -186,8 +338,39 @@ func getAuditTestResults() *results.SecurityCommandResults { }, }, WatchName: "security-watch", - Policies: []services.Policy{{Policy: "npm-security"}}, - IssueId: "XRAY-72918", + Policies: []services.Policy{{Policy: "npm-security"}}, + IssueId: "XRAY-72918", + }, + { + ViolationType: utils.ViolationTypeLicense.String(), + LicenseKey: "MIT", + LicenseName: "MIT full name", + Severity: severityutils.High.String(), + Components: map[string]services.Component{ + "npm://lodash:4.17.0": { + ImpactPaths: [][]services.ImpactPathNode{{ + {ComponentId: "npm://froghome:1.0.0"}, + {ComponentId: "npm://lodash:4.17.0"}, + }}, + }, + }, + WatchName: "license-watch", + Policies: []services.Policy{{Policy: "npm-license"}}, + IssueId: "MIT", + }, + }, + Licenses: []services.License{ + { + Key: "MIT", + Name: "MIT full name", + Components: map[string]services.Component{ + "npm://lodash:4.17.0": { + ImpactPaths: [][]services.ImpactPathNode{{ + {ComponentId: "npm://froghome:1.0.0"}, + {ComponentId: "npm://lodash:4.17.0"}, + }}, + }, + }, }, }, ScannedStatus: "completed", @@ -197,217 +380,260 @@ func getAuditTestResults() *results.SecurityCommandResults { &sarif.Run{ Tool: sarif.Tool{ Driver: sarifutils.CreateDummyDriver(validations.ContextualAnalysisToolName, - createDummyApplicabilityRule("CVE-2024-39249", jasutils.Applicable), - createDummyApplicabilityRule("CVE-2018-16487", jasutils.NotApplicable), - createDummyApplicabilityRule("CVE-2020-8203", jasutils.NotApplicable), - createDummyApplicabilityRule("CVE-2018-3721", jasutils.NotCovered), + validations.CreateDummyApplicabilityRule("CVE-2024-39249", "applicable"), + validations.CreateDummyApplicabilityRule("CVE-2018-16487", "not_applicable"), + validations.CreateDummyApplicabilityRule("CVE-2020-8203", "not_applicable"), + validations.CreateDummyApplicabilityRule("CVE-2018-3721", "not_covered"), ), }, Invocations: []*sarif.Invocation{sarif.NewInvocation().WithWorkingDirectory(sarif.NewSimpleArtifactLocation("/Users/user/project-with-issues"))}, Results: []*sarif.Result{ - createDummyApplicableResults("CVE-2024-39249", formats.Location{File: "/Users/user/project-with-issues/file-A", StartLine: 1, StartColumn: 2, EndLine: 3, EndColumn: 4, Snippet: "snippet"}), - createDummyApplicableResults("CVE-2024-39249", formats.Location{File: "/Users/user/project-with-issues/file-B", StartLine: 1, StartColumn: 2, EndLine: 3, EndColumn: 4, Snippet: "snippet2"}), + validations.CreateDummyApplicableResults("CVE-2024-39249", formats.Location{File: "/Users/user/project-with-issues/file-A", StartLine: 1, StartColumn: 2, EndLine: 3, EndColumn: 4, Snippet: "snippet"}), + validations.CreateDummyApplicableResults("CVE-2024-39249", formats.Location{File: "/Users/user/project-with-issues/file-B", StartLine: 1, StartColumn: 2, EndLine: 3, EndColumn: 4, Snippet: "snippet2"}), // Not Applicable result = remediation location, not a finding add for test confirmation - createDummyApplicableResults("CVE-2018-16487", formats.Location{File: "/Users/user/project-with-issues/file-C", StartLine: 1, StartColumn: 2, EndLine: 3, EndColumn: 4, Snippet: "snippet3"}), + validations.CreateDummyApplicableResults("CVE-2018-16487", formats.Location{File: "/Users/user/project-with-issues/file-C", StartLine: 1, StartColumn: 2, EndLine: 3, EndColumn: 4, Snippet: "snippet3"}), }, }, ) - // Secrets scan results - npmTargetResults.JasResults.NewJasScanResults(jasutils.Secrets, + // Iac scan results + npmTargetResults.JasResults.NewJasScanResults(jasutils.IaC, []*sarif.Run{{ - Tool: sarif.Tool{ - Driver: sarifutils.CreateDummyDriver(validations.ContextualAnalysisToolName, - createDummyApplicabilityRule("CVE-2024-39249", jasutils.Applicable), - createDummyApplicabilityRule("CVE-2018-16487", jasutils.NotApplicable), - createDummyApplicabilityRule("CVE-2020-8203", jasutils.NotApplicable), - createDummyApplicabilityRule("CVE-2018-3721", jasutils.NotCovered), - ), + Tool: sarif.Tool{Driver: sarifutils.CreateDummyDriver(validations.IacToolName, validations.CreateDummyJasRule("aws_cloudfront_tls_only"))}, + Invocations: []*sarif.Invocation{sarif.NewInvocation().WithWorkingDirectory(sarif.NewSimpleArtifactLocation("/Users/user/project-with-issues"))}, + Results: []*sarif.Result{ + validations.CreateDummyJasResult("aws_cloudfront_tls_only", severityutils.LevelError, formats.Location{File: "/Users/user/project-with-issues/req_sw_terraform_aws_cloudfront_tls_only.tf", StartLine: 2, StartColumn: 1, EndLine: 21, EndColumn: 1, Snippet: "viewer_protocol_policy..."}), }, + }}, + // No Violations + []*sarif.Run{}, 0, + ) + // Secrets scan results + npmTargetResults.JasResults.NewJasScanResults(jasutils.Secrets, + []*sarif.Run{{ + Tool: sarif.Tool{Driver: sarifutils.CreateDummyDriver(validations.SecretsToolName, validations.CreateDummyJasRule("REQ.SECRET.KEYS"))}, Invocations: []*sarif.Invocation{sarif.NewInvocation().WithWorkingDirectory(sarif.NewSimpleArtifactLocation("/Users/user/project-with-issues"))}, Results: []*sarif.Result{ - createDummyApplicableResults("CVE-2024-39249", formats.Location{File: "/Users/user/project-with-issues/file-A", StartLine: 1, StartColumn: 2, EndLine: 3, EndColumn: 4, Snippet: "snippet"}), - createDummyApplicableResults("CVE-2024-39249", formats.Location{File: "/Users/user/project-with-issues/file-B", StartLine: 1, StartColumn: 2, EndLine: 3, EndColumn: 4, Snippet: "snippet2"}), - // Not Applicable result = remediation location, not a finding add for test confirmation - createDummyApplicableResults("CVE-2018-16487", formats.Location{File: "/Users/user/project-with-issues/file-C", StartLine: 1, StartColumn: 2, EndLine: 3, EndColumn: 4, Snippet: "snippet3"}), + validations.CreateDummySecretResult("REQ.SECRET.KEYS", jasutils.Active, "active token", formats.Location{File: "/Users/user/project-with-issues/fake-creds.txt", StartLine: 2, StartColumn: 1, EndLine: 2, EndColumn: 11, Snippet: "Sqc************"}), + validations.CreateDummySecretResult("REQ.SECRET.KEYS", jasutils.NotAToken, "", formats.Location{File: "/Users/user/project-with-issues/dir/server.js", StartLine: 3, StartColumn: 1, EndLine: 3, EndColumn: 11, Snippet: "gho************"}), }, }}, []*sarif.Run{{ - Tool: sarif.Tool{ - Driver: sarifutils.CreateDummyDriver(validations.ContextualAnalysisToolName, - createDummyApplicabilityRule("CVE-2024-39249", jasutils.Applicable), - createDummyApplicabilityRule("CVE-2018-16487", jasutils.NotApplicable), - createDummyApplicabilityRule("CVE-2020-8203", jasutils.NotApplicable), - createDummyApplicabilityRule("CVE-2018-3721", jasutils.NotCovered), - ), + Tool: sarif.Tool{Driver: sarifutils.CreateDummyDriver(validations.SecretsToolName, validations.CreateDummyJasRule("REQ.SECRET.KEYS"))}, + Invocations: []*sarif.Invocation{sarif.NewInvocation().WithWorkingDirectory(sarif.NewSimpleArtifactLocation("/Users/user/project-with-issues"))}, + Results: []*sarif.Result{ + validations.CreateDummySecretViolationResult("REQ.SECRET.KEYS", jasutils.Active, "active token", "watch", "sec-violation-1", []string{"policy"}, formats.Location{File: "/Users/user/project-with-issues/fake-creds.txt", StartLine: 2, StartColumn: 1, EndLine: 2, EndColumn: 11, Snippet: "Sqc************"}), + validations.CreateDummySecretViolationResult("REQ.SECRET.KEYS", jasutils.NotAToken, "", "watch", "sec-violation-2", []string{"policy"}, formats.Location{File: "/Users/user/project-with-issues/dir/server.js", StartLine: 3, StartColumn: 1, EndLine: 3, EndColumn: 11, Snippet: "gho************"}), }, + }}, 0, + ) + // Sast scan results + npmTargetResults.JasResults.NewJasScanResults(jasutils.Sast, + // No Vulnerabilities + []*sarif.Run{{ + Tool: sarif.Tool{Driver: sarifutils.CreateDummyDriver(validations.SastToolName, validations.CreateDummyJasRule("aws_cloudfront_tls_only"))}, + Invocations: []*sarif.Invocation{sarif.NewInvocation().WithWorkingDirectory(sarif.NewSimpleArtifactLocation("/Users/user/project-with-issues"))}, + }}, + []*sarif.Run{{ + Tool: sarif.Tool{Driver: sarifutils.CreateDummyDriver(validations.SastToolName, validations.CreateDummyJasRule("js-template-injection", "73"), validations.CreateDummyJasRule("js-insecure-random", "338"))}, Invocations: []*sarif.Invocation{sarif.NewInvocation().WithWorkingDirectory(sarif.NewSimpleArtifactLocation("/Users/user/project-with-issues"))}, Results: []*sarif.Result{ - createDummyApplicableResults("CVE-2024-39249", formats.Location{File: "/Users/user/project-with-issues/file-A", StartLine: 1, StartColumn: 2, EndLine: 3, EndColumn: 4, Snippet: "snippet"}), - createDummyApplicableResults("CVE-2024-39249", formats.Location{File: "/Users/user/project-with-issues/file-B", StartLine: 1, StartColumn: 2, EndLine: 3, EndColumn: 4, Snippet: "snippet2"}), - // Not Applicable result = remediation location, not a finding add for test confirmation - createDummyApplicableResults("CVE-2018-16487", formats.Location{File: "/Users/user/project-with-issues/file-C", StartLine: 1, StartColumn: 2, EndLine: 3, EndColumn: 4, Snippet: "snippet3"}), + validations.CreateDummySastViolationResult("js-insecure-random", severityutils.LevelNote, "watch", "sast-violation-1", []string{"policy", "policy2"}, formats.Location{File: "/Users/user/project-with-issues/public/js/bootstrap.bundle.js", StartLine: 136, StartColumn: 22, EndLine: 136, EndColumn: 35, Snippet: "Math.random()"}), + validations.CreateDummySastViolationResult("js-template-injection", severityutils.LevelError, "watch", "sast-violation-2", []string{"policy", "policy2"}, formats.Location{File: "/Users/user/project-with-issues/server.js", StartLine: 26, StartColumn: 28, EndLine: 26, EndColumn: 37, Snippet: "req.query"}, + []formats.Location{ + {File: "/Users/user/project-with-issues/server.js", StartLine: 27, StartColumn: 28, EndLine: 26, EndColumn: 31, Snippet: "req"}, + {File: "/Users/user/project-with-issues/server.js", StartLine: 26, StartColumn: 28, EndLine: 26, EndColumn: 37, Snippet: "req.query"}, + }, + ), }, }}, 0, ) - return cmdResults -} - -func createDummyApplicabilityRule(cve string, applicableStatus jasutils.ApplicabilityStatus) *sarif.ReportingDescriptor { - return &sarif.ReportingDescriptor{ - ID: fmt.Sprintf("applic_%s", cve), - Name: &cve, - ShortDescription: sarif.NewMultiformatMessageString(fmt.Sprintf("Scanner for %s", cve)), - FullDescription: sarif.NewMultiformatMessageString(fmt.Sprintf("The Scanner checks for %s", cve)), - Properties: map[string]interface{}{"applicability": applicableStatus.String()}, - } -} - -func createDummyApplicableResults(cve string, location formats.Location) *sarif.Result { - return &sarif.Result{ - Message: *sarif.NewTextMessage("ca msg"), - RuleID: utils.NewStrPtr(fmt.Sprintf("applic_%s", cve)), - Locations: []*sarif.Location{ - sarifutils.CreateLocation(location.File, location.StartLine, location.StartColumn, location.EndLine, location.EndColumn, location.Snippet), - }, - } + return cmdResults, expected } // For Summary we count unique CVE finding (issueId), for SARIF and SimpleJson we count all findings (pair of issueId+impactedComponent) // We have in the result 2 CVE with 2 impacted components each -func getDockerScanValidationParams(unique bool) validations.ValidationParams { - params := validations.ValidationParams{ +// func getDockerScanValidationParams(unique bool) validations.ValidationParams { +// params := validations.ValidationParams{ +// ExactResultsMatch: true, +// Total: &validations.TotalCount{Violations: 3}, +// Violations: &validations.ViolationCount{ +// ValidateScan: &validations.ScanCount{Sca: 1, Secrets: 2}, +// ValidateApplicabilityStatus: &validations.ApplicabilityStatusCount{Undetermined: 1}, +// }, +// } +// if unique { +// params.Total.Vulnerabilities = 11 +// params.Vulnerabilities = &validations.VulnerabilityCount{ +// ValidateScan: &validations.ScanCount{Sca: 8, Secrets: 3}, +// ValidateApplicabilityStatus: &validations.ApplicabilityStatusCount{Applicable: 3, NotApplicable: 3, NotCovered: 1, Undetermined: 1}, +// } +// } else { +// params.Total.Vulnerabilities = 14 +// params.Vulnerabilities = &validations.VulnerabilityCount{ +// ValidateScan: &validations.ScanCount{Sca: 11, Secrets: 3}, +// ValidateApplicabilityStatus: &validations.ApplicabilityStatusCount{Applicable: 5, NotApplicable: 4, NotCovered: 1, Undetermined: 1}, +// } +// } +// return params +// } + +func getDockerScanTestResults(unique bool) (*results.SecurityCommandResults, validations.ValidationParams) { + expected := validations.ValidationParams{ ExactResultsMatch: true, - Total: &validations.TotalCount{Violations: 3}, + Total: &validations.TotalCount{Violations: 2}, Violations: &validations.ViolationCount{ - ValidateScan: &validations.ScanCount{Sca: 1, Secrets: 2}, - ValidateApplicabilityStatus: &validations.ApplicabilityStatusCount{Undetermined: 1}, + ValidateScan: &validations.ScanCount{Sca: 1, Secrets: 1}, + ValidateApplicabilityStatus: &validations.ApplicabilityStatusCount{Applicable: 1, Inactive: 1}, }, } if unique { - params.Total.Vulnerabilities = 11 - params.Vulnerabilities = &validations.VulnerabilityCount{ - ValidateScan: &validations.ScanCount{Sca: 8, Secrets: 3}, - ValidateApplicabilityStatus: &validations.ApplicabilityStatusCount{Applicable: 3, NotApplicable: 3, NotCovered: 1, Undetermined: 1}, + // Only count CVE findings, not impacted components + expected.Total.Vulnerabilities = 3 + expected.Vulnerabilities = &validations.VulnerabilityCount{ + ValidateScan: &validations.ScanCount{Sca: 2, Secrets: 1}, + ValidateApplicabilityStatus: &validations.ApplicabilityStatusCount{Applicable: 1, Undetermined: 1, Inactive: 1}, } } else { - params.Total.Vulnerabilities = 14 - params.Vulnerabilities = &validations.VulnerabilityCount{ - ValidateScan: &validations.ScanCount{Sca: 11, Secrets: 3}, - ValidateApplicabilityStatus: &validations.ApplicabilityStatusCount{Applicable: 5, NotApplicable: 4, NotCovered: 1, Undetermined: 1}, + // Count all findings (pair of issueId+impactedComponent) + expected.Total.Vulnerabilities = 4 + expected.Vulnerabilities = &validations.VulnerabilityCount{ + ValidateScan: &validations.ScanCount{Sca: 3, Secrets: 1}, + ValidateApplicabilityStatus: &validations.ApplicabilityStatusCount{Applicable: 1, Undetermined: 2, Inactive: 1}, } } - return params -} - -func getDockerScanTestResults() *results.SecurityCommandResults { + // Create basic command results to be converted to different formats cmdResults := results.NewCommandResults(utils.DockerImage) - - return cmdResults -} - -func TestConvertResults(t *testing.T) { - auditInputResults := testUtils.ReadCmdScanResults(t, filepath.Join(testDataDir, "audit", "audit_results.json")) - dockerScanInputResults := testUtils.ReadCmdScanResults(t, filepath.Join(testDataDir, "dockerscan", "docker_results.json")) - - testCases := []struct { - contentFormat conversionFormat - inputResults *results.SecurityCommandResults - expectedContentPath string - }{ - { - contentFormat: SimpleJson, - inputResults: auditInputResults, - expectedContentPath: filepath.Join(testDataDir, "audit", "audit_simple_json.json"), - }, - { - contentFormat: Sarif, - inputResults: auditInputResults, - expectedContentPath: filepath.Join(testDataDir, "audit", "audit_sarif.json"), - }, - { - contentFormat: Summary, - inputResults: auditInputResults, - expectedContentPath: filepath.Join(testDataDir, "audit", "audit_summary.json"), - }, - { - contentFormat: SimpleJson, - inputResults: dockerScanInputResults, - expectedContentPath: filepath.Join(testDataDir, "dockerscan", "docker_simple_json.json"), + cmdResults.SetEntitledForJas(true).SetXrayVersion("3.107.13").SetXscVersion("1.12.5").SetMultiScanId("7d5e4733-3f93-11ef-8147-e610d09d7daa") + dockerImageTarget := cmdResults.NewScanResults(results.ScanTarget{Target: "temp/folders/T/jfrog.cli.temp.-11-11/image.tar", Name: "platform.jfrog.io/swamp-docker/swamp:latest", Technology: techutils.Oci}) + // SCA scan results + dockerImageTarget.NewScaScanResults(0, services.ScanResponse{ + ScanId: "27da9106-88ea-416b-799b-bc7d15783473", + Vulnerabilities: []services.Vulnerability{ + { + Cves: []services.Cve{{ + Id: "CVE-2024-6119", + }}, + Summary: "Issue summary", + Severity: severityutils.Unknown.String(), + Components: map[string]services.Component{ + "deb://debian:bookworm:libssl3:3.0.13-1~deb12u1": { + ImpactPaths: [][]services.ImpactPathNode{{ + {ComponentId: "docker://platform.jfrog.io/swamp-docker/swamp:latest"}, + { + ComponentId: "generic://sha256:f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595/sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar", + FullPath: "sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar", + }, + { + ComponentId: "deb://debian:bookworm:libssl3:3.0.13-1~deb12u1", + FullPath: "libssl3:3.0.13-1~deb12u1", + }, + }}, + }, + }, + IssueId: "XRAY-632747", + ExtendedInformation: &services.ExtendedInformation{JfrogResearchSeverity: "Medium"}, + }, + { + Cves: []services.Cve{{ + Id: "CVE-2024-38428", + }}, + Summary: "Interpretation Conflict", + Severity: severityutils.Critical.String(), + Components: map[string]services.Component{ + "deb://debian:bookworm:libssl3:3.0.13-1~deb12u1": { + ImpactPaths: [][]services.ImpactPathNode{{ + {ComponentId: "docker://platform.jfrog.io/swamp-docker/swamp:latest"}, + { + ComponentId: "generic://sha256:f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595/sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar", + FullPath: "sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar", + }, + { + ComponentId: "deb://debian:bookworm:libssl3:3.0.13-1~deb12u1", + FullPath: "libssl3:3.0.13-1~deb12u1", + }, + }}, + }, + "deb://debian:bookworm:openssl:3.0.13-1~deb12u1": { + ImpactPaths: [][]services.ImpactPathNode{{ + {ComponentId: "docker://platform.jfrog.io/swamp-docker/swamp:latest"}, + { + ComponentId: "generic://sha256:f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595/sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar", + FullPath: "sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar", + }, + { + ComponentId: "deb://debian:bookworm:openssl:3.0.13-1~deb12u1", + FullPath: "openssl:3.0.13-1~deb12u1", + }, + }}, + FixedVersions: []string{"[3.0.14-1~deb12u2]"}, + }, + }, + IssueId: "XRAY-606103", + ExtendedInformation: &services.ExtendedInformation{JfrogResearchSeverity: "Critical"}, + }, }, - { - contentFormat: Sarif, - inputResults: dockerScanInputResults, - expectedContentPath: filepath.Join(testDataDir, "dockerscan", "docker_sarif.json"), + Violations: []services.Violation{ + { + ViolationType: utils.ViolationTypeSecurity.String(), + Cves: []services.Cve{{ + Id: "CVE-2024-6119", + }}, + Summary: "Issue summary", + Severity: severityutils.Unknown.String(), + Components: map[string]services.Component{ + "deb://debian:bookworm:libssl3:3.0.13-1~deb12u1": { + ImpactPaths: [][]services.ImpactPathNode{{ + {ComponentId: "docker://platform.jfrog.io/swamp-docker/swamp:latest"}, + { + ComponentId: "generic://sha256:f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595/sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar", + FullPath: "sha256__f21c087a3964a446bce1aa4e3ec7cf82020dd77ad14f1cf4ea49cbb32eda1595.tar", + }, + { + ComponentId: "deb://debian:bookworm:libssl3:3.0.13-1~deb12u1", + FullPath: "libssl3:3.0.13-1~deb12u1", + }, + }}, + }, + }, + IssueId: "XRAY-632747", + ExtendedInformation: &services.ExtendedInformation{JfrogResearchSeverity: "Medium"}, + WatchName: "security-watch", + Policies: []services.Policy{{Policy: "debian-security"}}, + }, }, - { - contentFormat: Summary, - inputResults: dockerScanInputResults, - expectedContentPath: filepath.Join(testDataDir, "dockerscan", "docker_summary.json"), + ScannedStatus: "completed", + }) + // Contextual analysis scan results + dockerImageTarget.JasResults.NewApplicabilityScanResults(0, + &sarif.Run{ + Tool: sarif.Tool{ + Driver: sarifutils.CreateDummyDriver(validations.ContextualAnalysisToolName, + validations.CreateDummyApplicabilityRule("CVE-2024-6119", "applicable"), + validations.CreateDummyApplicabilityRule("CVE-2024-38428", "undetermined"), + ), + }, + Invocations: []*sarif.Invocation{sarif.NewInvocation().WithWorkingDirectory(sarif.NewSimpleArtifactLocation("temp/folders/T/jfrog.cli.temp.-11-11"))}, + Results: []*sarif.Result{validations.CreateDummyApplicableResults("CVE-2024-6119", formats.Location{File: "file:///usr/local/bin/node"})}, }, - } - - for _, testCase := range testCases { - t.Run(fmt.Sprintf("%s convert to %s", testCase.inputResults.CmdType, testCase.contentFormat), func(t *testing.T) { - var validationParams validations.ValidationParams - switch testCase.inputResults.CmdType { - case utils.SourceCode: - validationParams = getAuditValidationParams() - case utils.DockerImage: - validationParams = getDockerScanValidationParams(testCase.contentFormat == Summary) - default: - t.Fatalf("Unsupported command type: %s", testCase.inputResults.CmdType) - } - pretty := false - if testCase.contentFormat == Sarif { - pretty = true - } - convertor := NewCommandResultsConvertor(ResultConvertParams{IncludeVulnerabilities: true, HasViolationContext: true, Pretty: pretty}) - - switch testCase.contentFormat { - case SimpleJson: - validateSimpleJsonConversion(t, testUtils.ReadSimpleJsonResults(t, testCase.expectedContentPath), testCase.inputResults, convertor, validationParams) - case Sarif: - validateSarifConversion(t, testUtils.ReadSarifResults(t, testCase.expectedContentPath), testCase.inputResults, convertor, validationParams) - case Summary: - validateSummaryConversion(t, testUtils.ReadSummaryResults(t, testCase.expectedContentPath), testCase.inputResults, convertor, validationParams) - } - }) - } -} - -func validateSimpleJsonConversion(t *testing.T, expectedResults formats.SimpleJsonResults, inputResults *results.SecurityCommandResults, convertor *CommandResultsConvertor, validationParams validations.ValidationParams) { - validationParams.Expected = expectedResults - - actualResults, err := convertor.ConvertToSimpleJson(inputResults) - if !assert.NoError(t, err) { - return - } - validationParams.Actual = actualResults - - validations.ValidateCommandSimpleJsonOutput(t, validationParams) -} - -func validateSarifConversion(t *testing.T, expectedResults *sarif.Report, inputResults *results.SecurityCommandResults, convertor *CommandResultsConvertor, validationParams validations.ValidationParams) { - validationParams.Expected = expectedResults - - actualResults, err := convertor.ConvertToSarif(inputResults) - if !assert.NoError(t, err) { - return - } - validationParams.Actual = actualResults - - validations.ValidateCommandSarifOutput(t, validationParams) -} - -func validateSummaryConversion(t *testing.T, expectedResults formats.ResultsSummary, inputResults *results.SecurityCommandResults, convertor *CommandResultsConvertor, validationParams validations.ValidationParams) { - validationParams.Expected = expectedResults - - actualResults, err := convertor.ConvertToSummary(inputResults) - if !assert.NoError(t, err) { - return - } - validationParams.Actual = actualResults + ) + // Secrets scan results + dockerImageTarget.JasResults.NewJasScanResults(jasutils.Secrets, + []*sarif.Run{{ + Tool: sarif.Tool{Driver: sarifutils.CreateDummyDriver(validations.SecretsToolName, validations.CreateDummyJasRule("REQ.SECRET.GENERIC.CODE"))}, + Invocations: []*sarif.Invocation{sarif.NewInvocation().WithWorkingDirectory(sarif.NewSimpleArtifactLocation("temp/folders/T/jfrog.cli.temp.-11-11"))}, + Results: []*sarif.Result{ + validations.CreateDummySecretResult("REQ.SECRET.GENERIC.CODE", jasutils.Inactive, "expired", formats.Location{File: "temp/folders/T/tmpsfyn_3d1/unpacked/sha256/9e88ea9de1b44baba5e96a79e33e4af64334b2bf129e838e12f6dae71b5c86f0/usr/src/app/server/index.js", StartLine: 5, StartColumn: 7, EndLine: 5, EndColumn: 57, Snippet: "tok************"}), + }, + }}, + []*sarif.Run{{ + Tool: sarif.Tool{Driver: sarifutils.CreateDummyDriver(validations.SecretsToolName, validations.CreateDummyJasRule("REQ.SECRET.GENERIC.CODE"))}, + Invocations: []*sarif.Invocation{sarif.NewInvocation().WithWorkingDirectory(sarif.NewSimpleArtifactLocation("temp/folders/T/jfrog.cli.temp.-11-11"))}, + Results: []*sarif.Result{ + validations.CreateDummySecretViolationResult("REQ.SECRET.GENERIC.CODE", jasutils.Inactive, "expired", "watch", "sec-violation-1", []string{"policy"}, formats.Location{File: "temp/folders/T/tmpsfyn_3d1/unpacked/sha256/9e88ea9de1b44baba5e96a79e33e4af64334b2bf129e838e12f6dae71b5c86f0/usr/src/app/server/index.js", StartLine: 5, StartColumn: 7, EndLine: 5, EndColumn: 57, Snippet: "tok************"}), + }, + }}, 0, + ) - validations.ValidateCommandSummaryOutput(t, validationParams) + return cmdResults, expected } diff --git a/utils/results/conversion/sarifparser/sarifparser.go b/utils/results/conversion/sarifparser/sarifparser.go index 21ed48d8..f67f4e7f 100644 --- a/utils/results/conversion/sarifparser/sarifparser.go +++ b/utils/results/conversion/sarifparser/sarifparser.go @@ -70,7 +70,8 @@ type currentTargetState struct { type scaParseParams struct { CmdType utils.CommandType IssueId, Summary, MarkdownDescription, CveScore, ImpactedPackagesName, ImpactedPackagesVersion string - GenerateTitleFunc func(depName string, version string, issueId string) string + Watch string + GenerateTitleFunc func(depName string, version string, issueId string, watch string) string Cves []formats.CveRow Severity severityutils.Severity ApplicabilityStatus jasutils.ApplicabilityStatus @@ -351,6 +352,7 @@ func addSarifScaSecurityViolation(cmdType utils.CommandType, sarifResults *[]*sa currentResults, currentRule := parseScaToSarifFormat(scaParseParams{ CmdType: cmdType, IssueId: violation.IssueId, + Watch: violation.WatchName, Summary: violation.Summary, MarkdownDescription: markdownDescription, CveScore: maxCveScore, @@ -389,6 +391,7 @@ func addSarifScaLicenseViolation(cmdType utils.CommandType, sarifResults *[]*sar } currentResults, currentRule := parseScaToSarifFormat(scaParseParams{ CmdType: cmdType, + Watch: violation.WatchName, IssueId: violation.LicenseKey, Summary: getLicenseViolationSummary(impactedPackagesName, impactedPackagesVersion, violation.LicenseKey), MarkdownDescription: markdownDescription, @@ -424,7 +427,7 @@ func parseScaToSarifFormat(params scaParseParams) (sarifResults []*sarif.Result, // Add rule for the cve if not exists rule = getScaIssueSarifRule( cveImpactedComponentRuleId, - params.GenerateTitleFunc(params.ImpactedPackagesName, params.ImpactedPackagesVersion, issueId), + params.GenerateTitleFunc(params.ImpactedPackagesName, params.ImpactedPackagesVersion, issueId, params.Watch), params.CveScore, params.Summary, params.MarkdownDescription, @@ -432,7 +435,7 @@ func parseScaToSarifFormat(params scaParseParams) (sarifResults []*sarif.Result, for _, directDependency := range params.DirectComponents { // Create result for each direct dependency issueResult := sarif.NewRuleResult(cveImpactedComponentRuleId). - WithMessage(sarif.NewTextMessage(params.GenerateTitleFunc(directDependency.Name, directDependency.Version, issueId))). + WithMessage(sarif.NewTextMessage(params.GenerateTitleFunc(directDependency.Name, directDependency.Version, issueId, params.Watch))). WithLevel(level.String()) // Add properties resultsProperties := sarif.NewPropertyBag() @@ -525,16 +528,30 @@ func getDirectDependenciesFormatted(directDependencies []formats.ComponentRow) ( return strings.TrimSuffix(formattedDirectDependencies.String(), "
"), nil } -func getScaVulnerabilitySarifHeadline(depName, version, issueId string) string { - return fmt.Sprintf("[%s] %s %s", issueId, depName, version) +func getScaVulnerabilitySarifHeadline(depName, version, issueId, watch string) string { + headline := fmt.Sprintf("[%s] %s %s", issueId, depName, version) + if watch != "" { + headline = fmt.Sprintf("%s (%s)", headline, watch) + } + return headline } -func getScaSecurityViolationSarifHeadline(depName, version, key string) string { - return fmt.Sprintf("Security violation %s", getScaVulnerabilitySarifHeadline(depName, version, key)) +func getScaSecurityViolationSarifHeadline(depName, version, key, watch string) string { + headline := getScaVulnerabilitySarifHeadline(depName, version, key, watch) + if watch == "" { + return fmt.Sprintf("Security violation %s", headline) + } + return headline } -func getXrayLicenseSarifHeadline(depName, version, key string) string { - return fmt.Sprintf("License violation [%s] in %s %s", key, depName, version) +func getXrayLicenseSarifHeadline(depName, version, key, watch string) string { + headline := fmt.Sprintf("[%s] in %s %s", key, depName, version) + if watch != "" { + headline = fmt.Sprintf("%s (%s)", headline, watch) + } else { + headline = fmt.Sprintf("License violation %s", headline) + } + return headline } func getLicenseViolationSummary(depName, version, key string) string { diff --git a/utils/results/conversion/sarifparser/sarifparser_test.go b/utils/results/conversion/sarifparser/sarifparser_test.go index 5be62e07..780dadc8 100644 --- a/utils/results/conversion/sarifparser/sarifparser_test.go +++ b/utils/results/conversion/sarifparser/sarifparser_test.go @@ -65,18 +65,22 @@ func TestGetComponentSarifLocation(t *testing.T) { } func TestGetVulnerabilityOrViolationSarifHeadline(t *testing.T) { - assert.Equal(t, "[CVE-2022-1234] loadsh 1.4.1", getScaVulnerabilitySarifHeadline("loadsh", "1.4.1", "CVE-2022-1234")) - assert.NotEqual(t, "[CVE-2022-1234] comp 1.4.1", getScaVulnerabilitySarifHeadline("comp", "1.2.1", "CVE-2022-1234")) + assert.Equal(t, "[CVE-2022-1234] loadsh 1.4.1", getScaVulnerabilitySarifHeadline("loadsh", "1.4.1", "CVE-2022-1234", "")) + assert.NotEqual(t, "[CVE-2022-1234] comp 1.4.1", getScaVulnerabilitySarifHeadline("comp", "1.2.1", "CVE-2022-1234", "")) } func TestGetScaSecurityViolationSarifHeadline(t *testing.T) { - assert.Equal(t, "Security violation [CVE-2022-1234] loadsh 1.4.1", getScaSecurityViolationSarifHeadline("loadsh", "1.4.1", "CVE-2022-1234")) - assert.NotEqual(t, "[CVE-2022-1234] comp 1.2.1", getScaSecurityViolationSarifHeadline("comp", "1.2.1", "CVE-2022-1234")) + assert.Equal(t, "Security violation [CVE-2022-1234] loadsh 1.4.1", getScaSecurityViolationSarifHeadline("loadsh", "1.4.1", "CVE-2022-1234", "")) + assert.NotEqual(t, "[CVE-2022-1234] comp 1.2.1", getScaSecurityViolationSarifHeadline("comp", "1.2.1", "CVE-2022-1234", "")) + assert.Equal(t, "[CVE-2022-1234] loadsh 1.4.1 (watch)", getScaSecurityViolationSarifHeadline("loadsh", "1.4.1", "CVE-2022-1234", "watch")) + assert.NotEqual(t, "[CVE-2022-1234] comp 1.2.1", getScaSecurityViolationSarifHeadline("comp", "1.2.1", "CVE-2022-1234", "watch")) } func TestGetXrayLicenseSarifHeadline(t *testing.T) { - assert.Equal(t, "License violation [MIT] in loadsh 1.4.1", getXrayLicenseSarifHeadline("loadsh", "1.4.1", "MIT")) - assert.NotEqual(t, "License violation [] in comp 1.2.1", getXrayLicenseSarifHeadline("comp", "1.2.1", "MIT")) + assert.Equal(t, "License violation [MIT] in loadsh 1.4.1", getXrayLicenseSarifHeadline("loadsh", "1.4.1", "MIT", "")) + assert.NotEqual(t, "License violation [] in comp 1.2.1", getXrayLicenseSarifHeadline("comp", "1.2.1", "MIT", "")) + assert.Equal(t, "[MIT] in loadsh 1.4.1 (watch)", getXrayLicenseSarifHeadline("loadsh", "1.4.1", "MIT", "watch")) + assert.NotEqual(t, "License violation [] in comp 1.2.1", getXrayLicenseSarifHeadline("comp", "1.2.1", "MIT", "watch")) } func TestGetLicenseViolationSummary(t *testing.T) { diff --git a/utils/results/conversion/simplejsonparser/simplejsonparser.go b/utils/results/conversion/simplejsonparser/simplejsonparser.go index 19010170..c341edb5 100644 --- a/utils/results/conversion/simplejsonparser/simplejsonparser.go +++ b/utils/results/conversion/simplejsonparser/simplejsonparser.go @@ -65,16 +65,23 @@ func (sjc *CmdResultsSimpleJsonConverter) ParseNewTargetResults(target results.S return } +func shouldUpdateStatus(currentStatus, newStatus *int) bool { + if currentStatus == nil || (*currentStatus == 0 && newStatus != nil) { + return true + } + return false +} + func (sjc *CmdResultsSimpleJsonConverter) ParseScaIssues(target results.ScanTarget, violations bool, scaResponse results.ScanResult[services.ScanResponse], applicableScan ...results.ScanResult[[]*sarif.Run]) (err error) { if sjc.current == nil { return results.ErrResetConvertor } - if sjc.current.Statuses.ScaStatusCode == nil || *sjc.current.Statuses.ScaStatusCode == 0 { + if shouldUpdateStatus(sjc.current.Statuses.ScaStatusCode, &scaResponse.StatusCode) { sjc.current.Statuses.ScaStatusCode = &scaResponse.StatusCode } - for _, applicableScan := range applicableScan { - if sjc.current.Statuses.ApplicabilityStatusCode == nil || *sjc.current.Statuses.ApplicabilityStatusCode == 0 { - sjc.current.Statuses.ApplicabilityStatusCode = &applicableScan.StatusCode + for i := range applicableScan { + if shouldUpdateStatus(sjc.current.Statuses.ApplicabilityStatusCode, &applicableScan[i].StatusCode) { + sjc.current.Statuses.ApplicabilityStatusCode = &applicableScan[i].StatusCode } } if violations { @@ -133,9 +140,9 @@ func (sjc *CmdResultsSimpleJsonConverter) ParseSecrets(_ results.ScanTarget, isV if sjc.current == nil { return results.ErrResetConvertor } - for _, secretScan := range secrets { - if sjc.current.Statuses.SecretsStatusCode == nil || *sjc.current.Statuses.SecretsStatusCode == 0 { - sjc.current.Statuses.SecretsStatusCode = &secretScan.StatusCode + for i := range secrets { + if shouldUpdateStatus(sjc.current.Statuses.SecretsStatusCode, &secrets[i].StatusCode) { + sjc.current.Statuses.SecretsStatusCode = &secrets[i].StatusCode } } secretsSimpleJson, err := PrepareSimpleJsonJasIssues(sjc.entitledForJas, sjc.pretty, results.ScanResultsToRuns(secrets)...) @@ -157,9 +164,9 @@ func (sjc *CmdResultsSimpleJsonConverter) ParseIacs(_ results.ScanTarget, isViol if sjc.current == nil { return results.ErrResetConvertor } - for _, iacsScan := range iacs { - if sjc.current.Statuses.IacStatusCode == nil || *sjc.current.Statuses.IacStatusCode == 0 { - sjc.current.Statuses.IacStatusCode = &iacsScan.StatusCode + for i := range iacs { + if shouldUpdateStatus(sjc.current.Statuses.IacStatusCode, &iacs[i].StatusCode) { + sjc.current.Statuses.IacStatusCode = &iacs[i].StatusCode } } iacSimpleJson, err := PrepareSimpleJsonJasIssues(sjc.entitledForJas, sjc.pretty, results.ScanResultsToRuns(iacs)...) @@ -181,9 +188,9 @@ func (sjc *CmdResultsSimpleJsonConverter) ParseSast(_ results.ScanTarget, isViol if sjc.current == nil { return results.ErrResetConvertor } - for _, sastScan := range sast { - if sjc.current.Statuses.SastStatusCode == nil || *sjc.current.Statuses.SastStatusCode == 0 { - sjc.current.Statuses.SastStatusCode = &sastScan.StatusCode + for i := range sast { + if shouldUpdateStatus(sjc.current.Statuses.SastStatusCode, &sast[i].StatusCode) { + sjc.current.Statuses.SastStatusCode = &sast[i].StatusCode } } sastSimpleJson, err := PrepareSimpleJsonJasIssues(sjc.entitledForJas, sjc.pretty, results.ScanResultsToRuns(sast)...) diff --git a/utils/results/conversion/summaryparser/summaryparser.go b/utils/results/conversion/summaryparser/summaryparser.go index 1e7892a1..46aede6c 100644 --- a/utils/results/conversion/summaryparser/summaryparser.go +++ b/utils/results/conversion/summaryparser/summaryparser.go @@ -4,6 +4,7 @@ import ( "github.com/jfrog/gofrog/datastructures" "github.com/jfrog/jfrog-cli-security/utils" "github.com/jfrog/jfrog-cli-security/utils/formats" + "github.com/jfrog/jfrog-cli-security/utils/formats/sarifutils" "github.com/jfrog/jfrog-cli-security/utils/jasutils" "github.com/jfrog/jfrog-cli-security/utils/results" "github.com/jfrog/jfrog-cli-security/utils/severityutils" @@ -264,8 +265,11 @@ func (sc *CmdResultsSummaryConverter) ParseSecrets(_ results.ScanTarget, isViola if !isViolationsResults && sc.currentScan.Vulnerabilities.SecretsResults == nil { sc.currentScan.Vulnerabilities.SecretsResults = &formats.ResultSummary{} } - if isViolationsResults && sc.currentScan.Violations.SecretsResults == nil { - sc.currentScan.Violations.SecretsResults = &formats.ResultSummary{} + if isViolationsResults { + if sc.currentScan.Violations.SecretsResults == nil { + sc.currentScan.Violations.SecretsResults = &formats.ResultSummary{} + } + sc.currentScan.Violations.Watches = utils.UniqueUnion(sc.currentScan.Violations.Watches, getJasScansWatches(secrets...)...) } return results.ApplyHandlerToJasIssues(results.ScanResultsToRuns(secrets), sc.entitledForJas, sc.getJasHandler(jasutils.Secrets, isViolationsResults)) } @@ -281,8 +285,11 @@ func (sc *CmdResultsSummaryConverter) ParseIacs(_ results.ScanTarget, isViolatio if !isViolationsResults && sc.currentScan.Vulnerabilities.IacResults == nil { sc.currentScan.Vulnerabilities.IacResults = &formats.ResultSummary{} } - if isViolationsResults && sc.currentScan.Violations.IacResults == nil { - sc.currentScan.Violations.IacResults = &formats.ResultSummary{} + if isViolationsResults { + if sc.currentScan.Violations.IacResults == nil { + sc.currentScan.Violations.IacResults = &formats.ResultSummary{} + } + sc.currentScan.Violations.Watches = utils.UniqueUnion(sc.currentScan.Violations.Watches, getJasScansWatches(iacs...)...) } return results.ApplyHandlerToJasIssues(results.ScanResultsToRuns(iacs), sc.entitledForJas, sc.getJasHandler(jasutils.IaC, isViolationsResults)) } @@ -298,8 +305,11 @@ func (sc *CmdResultsSummaryConverter) ParseSast(_ results.ScanTarget, isViolatio if !isViolationsResults && sc.currentScan.Vulnerabilities.SastResults == nil { sc.currentScan.Vulnerabilities.SastResults = &formats.ResultSummary{} } - if isViolationsResults && sc.currentScan.Violations.SastResults == nil { - sc.currentScan.Violations.SastResults = &formats.ResultSummary{} + if isViolationsResults { + if sc.currentScan.Violations.SastResults == nil { + sc.currentScan.Violations.SastResults = &formats.ResultSummary{} + } + sc.currentScan.Violations.Watches = utils.UniqueUnion(sc.currentScan.Violations.Watches, getJasScansWatches(sast...)...) } return results.ApplyHandlerToJasIssues(results.ScanResultsToRuns(sast), sc.entitledForJas, sc.getJasHandler(jasutils.Sast, isViolationsResults)) } @@ -310,10 +320,14 @@ func (sc *CmdResultsSummaryConverter) getJasHandler(scanType jasutils.JasScanTyp // Only count the issue if it has a location return } - // Get the scanType count + // Get the scanType count and status + resultStatus := formats.NoStatus var count *formats.ResultSummary switch scanType { case jasutils.Secrets: + if tokenStatus := results.GetResultPropertyTokenValidation(result); tokenStatus != "" { + resultStatus = tokenStatus + } if violations { count = sc.currentScan.Violations.SecretsResults } else { @@ -339,7 +353,20 @@ func (sc *CmdResultsSummaryConverter) getJasHandler(scanType jasutils.JasScanTyp if _, ok := (*count)[severity.String()]; !ok { (*count)[severity.String()] = map[string]int{} } - (*count)[severity.String()][formats.NoStatus] += 1 + (*count)[severity.String()][resultStatus] += 1 return } } + +func getJasScansWatches(scans ...results.ScanResult[[]*sarif.Run]) (watches []string) { + for _, scanInfo := range scans { + for _, run := range scanInfo.Scan { + for _, result := range run.Results { + if watch := sarifutils.GetResultWatches(result); watch != "" { + watches = append(watches, watch) + } + } + } + } + return +} \ No newline at end of file diff --git a/utils/validations/test_mocks.go b/utils/validations/test_mocks.go index 29bcd752..0fe71996 100644 --- a/utils/validations/test_mocks.go +++ b/utils/validations/test_mocks.go @@ -8,9 +8,14 @@ import ( "strings" "testing" - "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils" + coreutils "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils" "github.com/jfrog/jfrog-cli-core/v2/utils/config" + "github.com/jfrog/jfrog-cli-security/utils" + "github.com/jfrog/jfrog-cli-security/utils/formats" + "github.com/jfrog/jfrog-cli-security/utils/formats/sarifutils" + "github.com/jfrog/jfrog-cli-security/utils/jasutils" "github.com/jfrog/jfrog-cli-security/utils/results" + "github.com/jfrog/jfrog-cli-security/utils/severityutils" "github.com/jfrog/jfrog-client-go/artifactory" "github.com/jfrog/jfrog-client-go/xray/services" xscutils "github.com/jfrog/jfrog-client-go/xsc/services/utils" @@ -22,7 +27,6 @@ const ( TestMsi = "27e175b8-e525-11ee-842b-7aa2c69b8f1f" TestScaScanId = "3d90ec4b-cf33-4846-6831-4bf9576f2235" - // TestMoreInfoUrl = "https://www.jfrog.com" TestPlatformUrl = "https://test-platform-url.jfrog.io/" TestMoreInfoUrl = "https://test-more-info-url.jfrog.io/" @@ -44,7 +48,7 @@ func CreateXscRestsMockServer(t *testing.T, testHandler restsTestHandler) (*http testServer := CreateRestsMockServer(testHandler) serverDetails := &config.ServerDetails{Url: testServer.URL + "/", XrayUrl: testServer.URL + "/xray/"} - serviceManager, err := utils.CreateServiceManager(serverDetails, -1, 0, false) + serviceManager, err := coreutils.CreateServiceManager(serverDetails, -1, 0, false) assert.NoError(t, err) return testServer, serverDetails, serviceManager } @@ -178,3 +182,90 @@ func NewMockScaResults(responses ...services.ScanResponse) (converted []results. } return } + +func CreateDummyApplicabilityRule(cve string, applicableStatus jasutils.ApplicabilityStatus) *sarif.ReportingDescriptor { + return &sarif.ReportingDescriptor{ + ID: fmt.Sprintf("applic_%s", cve), + Name: &cve, + ShortDescription: sarif.NewMultiformatMessageString(fmt.Sprintf("Scanner for %s", cve)), + FullDescription: sarif.NewMultiformatMessageString(fmt.Sprintf("The Scanner checks for %s", cve)), + Properties: map[string]interface{}{"applicability": applicableStatus.String()}, + } +} + +func CreateDummyApplicableResults(cve string, location formats.Location) *sarif.Result { + return &sarif.Result{ + Message: *sarif.NewTextMessage("ca msg"), + RuleID: utils.NewStrPtr(fmt.Sprintf("applic_%s", cve)), + Locations: []*sarif.Location{ + sarifutils.CreateLocation(location.File, location.StartLine, location.StartColumn, location.EndLine, location.EndColumn, location.Snippet), + }, + } +} + +func CreateDummyJasRule(id string, cwe ...string) *sarif.ReportingDescriptor { + descriptor := &sarif.ReportingDescriptor{ + ID: id, + Name: &id, + ShortDescription: sarif.NewMultiformatMessageString(fmt.Sprintf("Scanner for %s", id)).WithMarkdown(fmt.Sprintf("Scanner for %s", id)), + FullDescription: sarif.NewMultiformatMessageString(fmt.Sprintf("The Scanner checks for %s", id)).WithMarkdown(fmt.Sprintf("The Scanner checks for %s", id)), + } + if len(cwe) > 0 { + descriptor.DefaultConfiguration = &sarif.ReportingConfiguration{ + Parameters: &sarif.PropertyBag{ + Properties: map[string]interface{}{"CWE": strings.Join(cwe, ",")}, + }, + } + } + return descriptor +} + +func CreateDummySecretResult(id string, status jasutils.TokenValidationStatus, metadata string, location formats.Location) *sarif.Result { + return &sarif.Result{ + Message: *sarif.NewTextMessage(fmt.Sprintf("Secret %s were found", id)), + RuleID: utils.NewStrPtr(id), + Level: utils.NewStrPtr(severityutils.LevelInfo.String()), + Locations: []*sarif.Location{ + sarifutils.CreateLocation(location.File, location.StartLine, location.StartColumn, location.EndLine, location.EndColumn, location.Snippet), + }, + PropertyBag: sarif.PropertyBag{ + Properties: map[string]interface{}{"tokenValidation": status.String(), "metadata": metadata}, + }, + } +} + +func CreateDummySecretViolationResult(id string, status jasutils.TokenValidationStatus, metadata, watch, issueId string, policies []string, location formats.Location) *sarif.Result { + result := CreateDummySecretResult(id, status, metadata, location) + result.PropertyBag.Properties[sarifutils.WatchSarifPropertyKey] = watch + result.PropertyBag.Properties[sarifutils.JasIssueIdSarifPropertyKey] = issueId + result.PropertyBag.Properties[sarifutils.PoliciesSarifPropertyKey] = policies + return result +} + +func CreateDummyJasResult(id string, level severityutils.SarifSeverityLevel, location formats.Location, codeFlows ...[]formats.Location) *sarif.Result { + result := &sarif.Result{ + Message: *sarif.NewTextMessage(fmt.Sprintf("Vulnerability %s were found", id)), + RuleID: utils.NewStrPtr(id), + Level: utils.NewStrPtr(level.String()), + Locations: []*sarif.Location{ + sarifutils.CreateLocation(location.File, location.StartLine, location.StartColumn, location.EndLine, location.EndColumn, location.Snippet), + }, + PropertyBag: sarif.PropertyBag{Properties: map[string]interface{}{}}, + } + for _, codeFlow := range codeFlows { + flows := []*sarif.Location{} + for _, location := range codeFlow { + flows = append(flows, sarifutils.CreateLocation(location.File, location.StartLine, location.StartColumn, location.EndLine, location.EndColumn, location.Snippet)) + } + result.CodeFlows = append(result.CodeFlows, sarifutils.CreateCodeFlow(sarifutils.CreateThreadFlow(flows...))) + } + return result +} + +func CreateDummySastViolationResult(id string, level severityutils.SarifSeverityLevel, watch, issueId string, policies []string, location formats.Location, codeFlows ...[]formats.Location) *sarif.Result { + result := CreateDummyJasResult(id, level, location, codeFlows...) + result.PropertyBag.Properties[sarifutils.WatchSarifPropertyKey] = watch + result.PropertyBag.Properties[sarifutils.JasIssueIdSarifPropertyKey] = issueId + result.PropertyBag.Properties[sarifutils.PoliciesSarifPropertyKey] = policies + return result +} \ No newline at end of file diff --git a/utils/validations/test_validate_sarif.go b/utils/validations/test_validate_sarif.go index 266c8115..9e022359 100644 --- a/utils/validations/test_validate_sarif.go +++ b/utils/validations/test_validate_sarif.go @@ -66,6 +66,10 @@ func ValidateSarifIssuesCount(t *testing.T, params ValidationParams, report *sar actualValues.Vulnerabilities += actualValues.SastVulnerabilities actualValues.Violations += actualValues.SastViolations + if params.Total != nil { + // Not supported in the summary output + params.Total.Licenses = 0 + } ValidateCount(t, "sarif report", params, actualValues) } @@ -132,15 +136,14 @@ func countSecretsResults(report *sarif.Report) (vulnerabilities, inactiveVulnera for _, run := range allRuns { for _, result := range run.Results { isViolation := false - // JAS results does not have watch property yet, we should infer by prefix in msg - if strings.HasPrefix(sarifutils.GetResultMsgMarkdown(result), "Security violation") { + // JAS results may not have watch property, we should also try to infer by prefix in msg + if _, ok := result.Properties[sarifutils.WatchSarifPropertyKey]; ok || strings.HasPrefix(sarifutils.GetResultMsgMarkdown(result), "Security violation") { isViolation = true violations++ } else { vulnerabilities++ } - vulnerabilities++ - if tokenStatus := results.GetResultPropertyTokenValidation(result); tokenStatus == jasutils.Inactive.ToString() { + if tokenStatus := results.GetResultPropertyTokenValidation(result); tokenStatus == jasutils.Inactive.String() { if isViolation { inactiveViolations++ } else { @@ -155,8 +158,8 @@ func countSecretsResults(report *sarif.Report) (vulnerabilities, inactiveVulnera func countJasResults(runs []*sarif.Run) (vulnerabilities, violations int) { for _, run := range runs { for _, result := range run.Results { - // JAS results does not have watch property yet, we should infer by prefix in msg - if strings.HasPrefix(sarifutils.GetResultMsgMarkdown(result), "[Security violation]") { + // JAS results may not have watch property, we should also try to infer by prefix in msg + if _, ok := result.Properties[sarifutils.WatchSarifPropertyKey]; ok || strings.HasPrefix(sarifutils.GetResultMsgMarkdown(result), "Security violation") { violations++ } else { vulnerabilities++ diff --git a/utils/validations/test_validate_simple_json.go b/utils/validations/test_validate_simple_json.go index b15b52b7..24492fb6 100644 --- a/utils/validations/test_validate_simple_json.go +++ b/utils/validations/test_validate_simple_json.go @@ -149,7 +149,7 @@ func validateVulnerabilityOrViolationRow(t *testing.T, exactMatch bool, expected StringValidation{Expected: expected.Summary, Actual: actual.Summary, Msg: fmt.Sprintf("IssueId %s: Summary mismatch", expected.IssueId)}, StringValidation{Expected: expected.Severity, Actual: actual.Severity, Msg: fmt.Sprintf("IssueId %s: Severity mismatch", expected.IssueId)}, StringValidation{Expected: expected.Applicable, Actual: actual.Applicable, Msg: fmt.Sprintf("IssueId %s: Applicable mismatch", expected.IssueId)}, - StringValidation{Expected: expected.Technology.String(), Actual: actual.Technology.String(), Msg: fmt.Sprintf("IssueId %s: Technology mismatch", expected.IssueId)}, + // StringValidation{Expected: expected.Technology.String(), Actual: actual.Technology.String(), Msg: fmt.Sprintf("IssueId %s: Technology mismatch", expected.IssueId)}, ListValidation[string]{Expected: expected.References, Actual: actual.References, Msg: fmt.Sprintf("IssueId %s: References mismatch", expected.IssueId)}, StringValidation{Expected: expected.ImpactedDependencyType, Actual: actual.ImpactedDependencyType, Msg: fmt.Sprintf("IssueId %s: ImpactedDependencyType mismatch", expected.IssueId)}, diff --git a/utils/validations/test_validate_summary.go b/utils/validations/test_validate_summary.go index 7b7b90d4..3633fb8b 100644 --- a/utils/validations/test_validate_summary.go +++ b/utils/validations/test_validate_summary.go @@ -62,6 +62,16 @@ func ValidateSummaryIssuesCount(t *testing.T, params ValidationParams, results f } } } + if scan.Vulnerabilities.SecretsResults != nil { + for _, counts := range *scan.Vulnerabilities.SecretsResults { + for status, count := range counts { + switch status { + case jasutils.Inactive.String(): + actualValues.InactiveSecretsVulnerabilities += count + } + } + } + } } if scan.Violations != nil { if scan.Violations.ScaResults != nil { @@ -82,8 +92,21 @@ func ValidateSummaryIssuesCount(t *testing.T, params ValidationParams, results f } } } + if scan.Violations.SecretsResults != nil { + for _, counts := range *scan.Violations.SecretsResults { + for status, count := range counts { + switch status { + case jasutils.Inactive.String(): + actualValues.InactiveSecretsViolations += count + } + } + } + } } } - + if params.Total != nil { + // Not supported in the summary output + params.Total.Licenses = 0 + } ValidateCount(t, "summary", params, actualValues) }