From 6e14dc8dc10f061653e21879e65f5eecfb3ad204 Mon Sep 17 00:00:00 2001 From: phosphore Date: Tue, 29 Oct 2019 15:17:14 +0100 Subject: [PATCH] add verbosity option (-v) to show the issues' description, migrate to shortened git.io links --- npm-shrinkwrap.json | 72 +++++-------------- package.json | 2 +- .../checks/AtomicChecks/AffinityHTMLCheck.js | 3 +- .../checks/AtomicChecks/AffinityJSCheck.js | 3 +- .../AtomicChecks/AllowPopupHTMLCheck.js | 3 +- .../checks/AtomicChecks/AuxclickHTMLCheck.js | 3 +- .../checks/AtomicChecks/AuxclickJSCheck.js | 5 +- .../AtomicChecks/BlinkFeaturesHTMLCheck.js | 5 +- .../AtomicChecks/BlinkFeaturesJSCheck.js | 3 +- .../checks/AtomicChecks/CSPHTMLCheck.js | 3 +- src/finder/checks/AtomicChecks/CSPJSCheck.js | 5 +- .../CertificateErrorEventJSCheck.js | 3 +- .../CertificateVerifyProcJSCheck.js | 5 +- .../AtomicChecks/ContextIsolationJSCheck.js | 7 +- .../AtomicChecks/CustomArgumentsJSCheck.js | 3 +- .../AtomicChecks/CustomArgumentsJSONCheck.js | 5 +- .../AtomicChecks/DangerousFunctionsJSCheck.js | 3 +- .../AtomicChecks/ElectronVersionJSONCheck.js | 5 +- .../ExperimentalFeaturesHTMLCheck.js | 3 +- .../ExperimentalFeaturesJSCheck.js | 3 +- .../AtomicChecks/HTTPResourcesHTMLCheck.js | 3 +- .../AtomicChecks/HTTPResourcesJSCheck.js | 3 +- .../AtomicChecks/InsecureContentHTMLCheck.js | 3 +- .../AtomicChecks/InsecureContentJSCheck.js | 3 +- .../AtomicChecks/LimitNavigationJSCheck.js | 3 +- .../NodeIntegrationAttachEventJSCheck.js | 3 +- .../AtomicChecks/NodeIntegrationHTMLCheck.js | 3 +- .../AtomicChecks/NodeIntegrationJSCheck.js | 3 +- .../AtomicChecks/OpenExternalJSCheck.js | 3 +- .../PermissionRequestHandlerJSCheck.js | 3 +- .../checks/AtomicChecks/PreloadJSCheck.js | 3 +- .../AtomicChecks/ProtocolHandlersJSCheck.js | 3 +- .../checks/AtomicChecks/SandboxJSCheck.js | 5 +- .../SecurityWarningsDisabledJSCheck.js | 5 +- .../SecurityWarningsDisabledJSONCheck.js | 5 +- .../AtomicChecks/WebSecurityHTMLCheck.js | 5 +- .../checks/AtomicChecks/WebSecurityJSCheck.js | 3 +- .../GlobalChecks/AffinityGlobalCheck.js | 3 +- .../AvailableSecurityFixesGlobalCheck.js | 5 +- .../checks/GlobalChecks/CSPGlobalCheck.js | 7 +- ...PResourcesAndNodeIntegrationGlobalCheck.js | 3 +- .../LimitNavigationGlobalCheck.js | 3 +- .../PermissionRequestHandlerGlobalCheck.js | 3 +- src/finder/finder.js | 6 +- src/index.js | 10 ++- src/runner.js | 9 +-- 46 files changed, 130 insertions(+), 122 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 4ef4a3b..26e0760 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1247,52 +1247,14 @@ "string-width": "^2.1.1" } }, - "cli-table2": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/cli-table2/-/cli-table2-0.2.0.tgz", - "integrity": "sha1-LR738hig54biFFQFYtS9F3/jLZc=", + "cli-table3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", + "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", "requires": { "colors": "^1.1.2", - "lodash": "^3.10.1", - "string-width": "^1.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - } + "object-assign": "^4.1.0", + "string-width": "^2.1.1" } }, "cli-width": { @@ -1308,11 +1270,6 @@ "mimic-response": "^1.0.0" } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -1959,10 +1916,13 @@ } }, "eslint-utils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", - "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", - "dev": true + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } }, "eslint-visitor-keys": { "version": "1.1.0", @@ -3747,13 +3707,13 @@ "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-copy": { "version": "0.1.0", diff --git a/package.json b/package.json index f980cb6..79ed6f4 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "chalk": "^2.4.1", "cheerio": "^1.0.0-rc.2", "cli-progress": "^2.0.0", - "cli-table2": "^0.2.0", + "cli-table3": "^0.5.1", "escope": "^3.6.0", "eslint": "^6.5.1", "esprima": "^4.0.0", diff --git a/src/finder/checks/AtomicChecks/AffinityHTMLCheck.js b/src/finder/checks/AtomicChecks/AffinityHTMLCheck.js index ce6ccba..98ad74b 100644 --- a/src/finder/checks/AtomicChecks/AffinityHTMLCheck.js +++ b/src/finder/checks/AtomicChecks/AffinityHTMLCheck.js @@ -7,6 +7,7 @@ export default class AffinityHTMLCheck { this.id = 'AFFINITY_HTML_CHECK'; this.description = `Review the use of affinity property`; this.type = sourceTypes.HTML; + this.shortenedURL = "https://git.io/Jeu1z"; } match(cheerioObj, content) { @@ -18,7 +19,7 @@ export default class AffinityHTMLCheck { if (wp) { let features = parseWebPreferencesFeaturesString(wp); if (features['affinity'] !== undefined) - loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, properties: { "AffinityString": features['affinity']}, manualReview: true }); + loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, shortenedURL: self.shortenedURL, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, properties: { "AffinityString": features['affinity']}, manualReview: true }); } }); diff --git a/src/finder/checks/AtomicChecks/AffinityJSCheck.js b/src/finder/checks/AtomicChecks/AffinityJSCheck.js index d73bc55..b45b095 100644 --- a/src/finder/checks/AtomicChecks/AffinityJSCheck.js +++ b/src/finder/checks/AtomicChecks/AffinityJSCheck.js @@ -6,6 +6,7 @@ export default class AffinityJSCheck { this.id = 'AFFINITY_JS_CHECK'; this.description = `Review the use of affinity property`; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/Jeu1z"; } match(astNode, astHelper, scope) { @@ -26,7 +27,7 @@ export default class AffinityJSCheck { for (const node of found_nodes) { if (node.value.value) { - location.push({ line: node.value.loc.start.line, column: node.value.loc.start.column, id: this.id, description: this.description, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, properties: { "AffinityString": node.value.value }, manualReview: true }); + location.push({ line: node.value.loc.start.line, column: node.value.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, properties: { "AffinityString": node.value.value }, manualReview: true }); } } } diff --git a/src/finder/checks/AtomicChecks/AllowPopupHTMLCheck.js b/src/finder/checks/AtomicChecks/AllowPopupHTMLCheck.js index 7a4fabf..422c4e6 100644 --- a/src/finder/checks/AtomicChecks/AllowPopupHTMLCheck.js +++ b/src/finder/checks/AtomicChecks/AllowPopupHTMLCheck.js @@ -6,6 +6,7 @@ export default class AllowPopupsHTMLCheck { this.id = 'ALLOWPOPUPS_HTML_CHECK'; this.description = `Do not allow popups in webview`; this.type = sourceTypes.HTML; + this.shortenedURL = "https://git.io/Jeu1V"; } match(cheerioObj, content) { @@ -15,7 +16,7 @@ export default class AllowPopupsHTMLCheck { webviews.each(function (i, elem) { const allowpopups = cheerioObj(this).attr('allowpopups'); if (allowpopups !== undefined) { - loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, severity: severity.LOW, confidence: confidence.CERTAIN, manualReview: false }); + loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, shortenedURL: self.shortenedURL, severity: severity.LOW, confidence: confidence.CERTAIN, manualReview: false }); } }); diff --git a/src/finder/checks/AtomicChecks/AuxclickHTMLCheck.js b/src/finder/checks/AtomicChecks/AuxclickHTMLCheck.js index 0aa2fbc..f2d9521 100644 --- a/src/finder/checks/AtomicChecks/AuxclickHTMLCheck.js +++ b/src/finder/checks/AtomicChecks/AuxclickHTMLCheck.js @@ -6,6 +6,7 @@ export default class AuxclickHTMLCheck { this.id = 'AUXCLICK_HTML_CHECK'; this.description = `Limit navigation flows to untrusted origins. Middle-click may cause Electron to open a link within a new window`; this.type = sourceTypes.HTML; + this.shortenedURL = "https://git.io/Jeu1P"; } match(cheerioObj, content) { @@ -17,7 +18,7 @@ export default class AuxclickHTMLCheck { if(dbf && (dbf === "Auxclick")){ //Nothing to report }else{ - loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, severity: severity.MEDIUM, confidence: confidence.FIRM, manualReview: false }); + loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, shortenedURL: self.shortenedURL, severity: severity.MEDIUM, confidence: confidence.FIRM, manualReview: false }); } }); return loc; diff --git a/src/finder/checks/AtomicChecks/AuxclickJSCheck.js b/src/finder/checks/AtomicChecks/AuxclickJSCheck.js index 12eef61..2778989 100644 --- a/src/finder/checks/AtomicChecks/AuxclickJSCheck.js +++ b/src/finder/checks/AtomicChecks/AuxclickJSCheck.js @@ -6,6 +6,7 @@ export default class AuxclickJSCheck { this.id = 'AUXCLICK_JS_CHECK'; this.description = `Limit navigation flows to untrusted origins. Middle-click may cause Electron to open a link within a new window`; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/Jeu1K"; } match(astNode, astHelper, scope) { @@ -27,12 +28,12 @@ export default class AuxclickJSCheck { if (found_nodes.length > 0) { for (const node of found_nodes) { if (node.value.value.indexOf("Auxclick") == -1) { - location.push({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description, severity: severity.MEDIUM, confidence: confidence.FIRM, manualReview: false }); + location.push({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.FIRM, manualReview: false }); } } } else { - location.push({ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, severity: severity.MEDIUM, confidence: confidence.FIRM, manualReview: false }); + location.push({ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.FIRM, manualReview: false }); } } diff --git a/src/finder/checks/AtomicChecks/BlinkFeaturesHTMLCheck.js b/src/finder/checks/AtomicChecks/BlinkFeaturesHTMLCheck.js index 3d6907f..d9c60f7 100644 --- a/src/finder/checks/AtomicChecks/BlinkFeaturesHTMLCheck.js +++ b/src/finder/checks/AtomicChecks/BlinkFeaturesHTMLCheck.js @@ -6,6 +6,7 @@ export default class BlinkFeaturesHTMLCheck { this.id = 'BLINK_FEATURES_HTML_CHECK'; this.description = `Do not use Chromium's experimental features`; this.type = sourceTypes.HTML; + this.shortenedURL = "https://git.io/Jeu19"; } match(cheerioObj, content) { @@ -15,7 +16,7 @@ export default class BlinkFeaturesHTMLCheck { webviews.each(function (i, elem) { let wp = cheerioObj(this).attr('enableblinkfeatures'); if(wp){ - loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, severity: severity.LOW, confidence: confidence.CERTAIN, manualReview: true }); + loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, shortenedURL: self.shortenedURL, severity: severity.LOW, confidence: confidence.CERTAIN, manualReview: true }); } // search for both names for now @@ -23,7 +24,7 @@ export default class BlinkFeaturesHTMLCheck { // https://github.com/electron/electron/blob/master/docs/api/breaking-changes.md#browserwindow wp = cheerioObj(this).attr('blinkfeatures'); if(wp){ - loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, severity: severity.LOW, confidence: confidence.CERTAIN, manualReview: true }); + loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, shortenedURL: self.shortenedURL, severity: severity.LOW, confidence: confidence.CERTAIN, manualReview: true }); } }); return loc; diff --git a/src/finder/checks/AtomicChecks/BlinkFeaturesJSCheck.js b/src/finder/checks/AtomicChecks/BlinkFeaturesJSCheck.js index b3495b6..ec5e574 100644 --- a/src/finder/checks/AtomicChecks/BlinkFeaturesJSCheck.js +++ b/src/finder/checks/AtomicChecks/BlinkFeaturesJSCheck.js @@ -6,6 +6,7 @@ export default class BlinkFeaturesJSCheck { this.id = 'BLINK_FEATURES_JS_CHECK'; this.description = `Do not use Chromium’s experimental features`; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/Jeu1M"; } match(astNode, astHelper, scope){ @@ -29,7 +30,7 @@ export default class BlinkFeaturesJSCheck { node.key.value === 'blinkFeatures' || node.key.name === 'blinkFeatures')); for (const node of found_nodes) { - location.push({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description, severity: severity.LOW, confidence: confidence.CERTAIN, manualReview: true }); + location.push({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.LOW, confidence: confidence.CERTAIN, manualReview: true }); } } diff --git a/src/finder/checks/AtomicChecks/CSPHTMLCheck.js b/src/finder/checks/AtomicChecks/CSPHTMLCheck.js index 4a46d4d..0d5d610 100644 --- a/src/finder/checks/AtomicChecks/CSPHTMLCheck.js +++ b/src/finder/checks/AtomicChecks/CSPHTMLCheck.js @@ -6,6 +6,7 @@ export default class CSPHTMLCheck { this.id = 'CSP_HTML_CHECK'; this.description = `A CSP is set for this page using a meta tag`; this.type = sourceTypes.HTML; + this.shortenedURL = "https://git.io/JeuMe"; } match(cheerioObj, content) { @@ -16,7 +17,7 @@ export default class CSPHTMLCheck { const httpEquiv = cheerioObj(this).attr('http-equiv'); const cspContent = cheerioObj(this).attr('content'); if (httpEquiv && httpEquiv.toLowerCase() === "Content-Security-Policy".toLowerCase()) { - loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, severity: severity.INFORMATIONAL, confidence: confidence.TENTATIVE, properties: { "CSPstring": cspContent }, manualReview: true }); + loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, shortenedURL: self.shortenedURL, severity: severity.INFORMATIONAL, confidence: confidence.TENTATIVE, properties: { "CSPstring": cspContent }, manualReview: true }); } }); return loc; diff --git a/src/finder/checks/AtomicChecks/CSPJSCheck.js b/src/finder/checks/AtomicChecks/CSPJSCheck.js index d91b462..a86237e 100644 --- a/src/finder/checks/AtomicChecks/CSPJSCheck.js +++ b/src/finder/checks/AtomicChecks/CSPJSCheck.js @@ -6,6 +6,7 @@ export default class CSPJSCheck { this.id = 'CSP_JS_CHECK'; this.description = `Check for common responseHeaders CSP assignments`; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/JeuMe"; } match(astNode, astHelper){ @@ -27,7 +28,7 @@ export default class CSPJSCheck { if (node.value.properties) { for (const property of node.value.properties) if (property.key && property.key.value && property.key.value.toLowerCase() === "content-security-policy") - location.push({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description,severity: severity.INFORMATIONAL, confidence: confidence.TENTATIVE, properties: { "CSPstring": property.value.elements[0].value }, manualReview: true }); + location.push({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.INFORMATIONAL, confidence: confidence.TENTATIVE, properties: { "CSPstring": property.value.elements[0].value }, manualReview: true }); } // match callback({ responseHeaders: Object.assign({"Content-Security-Policy": [ "default-src 'self'" ]}, details.responseHeaders)}); as a popular stackoverflow answer suggests https://stackoverflow.com/questions/51969512/define-csp-http-header-in-electron-app else if (node.value.type === 'CallExpression') { if (node.value.arguments.length > 0) { @@ -35,7 +36,7 @@ export default class CSPJSCheck { if (argument.type === 'ObjectExpression') for (const property of argument.properties) if (property.key && property.key.value === 'Content-Security-Policy') - location.push({ line: node.value.loc.start.line, column: node.value.loc.start.column, id: this.id, description: this.description,severity: severity.INFORMATIONAL, confidence: confidence.TENTATIVE, properties: { "CSPstring": property.value.elements[0].value}, manualReview: true }); + location.push({ line: node.value.loc.start.line, column: node.value.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.INFORMATIONAL, confidence: confidence.TENTATIVE, properties: { "CSPstring": property.value.elements[0].value}, manualReview: true }); } } } diff --git a/src/finder/checks/AtomicChecks/CertificateErrorEventJSCheck.js b/src/finder/checks/AtomicChecks/CertificateErrorEventJSCheck.js index 16b9de3..16ba47d 100644 --- a/src/finder/checks/AtomicChecks/CertificateErrorEventJSCheck.js +++ b/src/finder/checks/AtomicChecks/CertificateErrorEventJSCheck.js @@ -6,6 +6,7 @@ export default class CertificateErrorEventJSCheck { this.id = 'CERTIFICATE_ERROR_EVENT_JS_CHECK'; this.description = `Do not allow insecure connections, by explicitly opting-out from TLS validation`; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/Jeu1N"; } match(astNode){ @@ -17,6 +18,6 @@ export default class CertificateErrorEventJSCheck { return null; } - return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: true }]; + return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: true }]; } } diff --git a/src/finder/checks/AtomicChecks/CertificateVerifyProcJSCheck.js b/src/finder/checks/AtomicChecks/CertificateVerifyProcJSCheck.js index dc57268..f247e14 100644 --- a/src/finder/checks/AtomicChecks/CertificateVerifyProcJSCheck.js +++ b/src/finder/checks/AtomicChecks/CertificateVerifyProcJSCheck.js @@ -6,6 +6,7 @@ export default class CertificateVerifyProcJSCheck { this.id = 'CERTIFICATE_VERIFY_PROC_JS_CHECK'; this.description = `Do not allow insecure connections, by explicitly opting-out from TLS validation or importing untrusted certificates`; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/Jeu1A"; } match(astNode){ @@ -14,12 +15,12 @@ export default class CertificateVerifyProcJSCheck { if (astNode.callee.property && astNode.callee.property.name === "setCertificateVerifyProc") { const description = 'Verify that the application does not explicitly opt-out from TLS validation'; - return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: description, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: true }]; + return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: true }]; } if (astNode.callee.property && astNode.callee.property.name === "importCertificate") { const description = 'Verify custom TLS certificates imported into the platform certificate store'; - return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: description, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: true }]; + return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: true }]; } } } diff --git a/src/finder/checks/AtomicChecks/ContextIsolationJSCheck.js b/src/finder/checks/AtomicChecks/ContextIsolationJSCheck.js index e10b8f4..ac63826 100644 --- a/src/finder/checks/AtomicChecks/ContextIsolationJSCheck.js +++ b/src/finder/checks/AtomicChecks/ContextIsolationJSCheck.js @@ -6,6 +6,7 @@ export default class ContextIsolationJSCheck { this.id = 'CONTEXT_ISOLATION_JS_CHECK'; this.description = `Review the use of the contextIsolation option`; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/Jeu1p"; } match(astNode, astHelper, scope){ @@ -37,16 +38,16 @@ export default class ContextIsolationJSCheck { // but technically it is an invalid json // just to be on the safe side show a warning if any value is insecure if(node.value.value !== true) { - location.push({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description, severity: severity.HIGH, confidence: confidence.FIRM, manualReview: false }); + location.push({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.HIGH, confidence: confidence.FIRM, manualReview: false }); } } } else { - location.push({ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, severity: severity.HIGH, confidence: confidence.FIRM, manualReview: false }); + location.push({ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.HIGH, confidence: confidence.FIRM, manualReview: false }); } } else { //No webpreferences - location.push({ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, severity: severity.HIGH, confidence: confidence.FIRM, manualReview: false }); + location.push({ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.HIGH, confidence: confidence.FIRM, manualReview: false }); } return location; diff --git a/src/finder/checks/AtomicChecks/CustomArgumentsJSCheck.js b/src/finder/checks/AtomicChecks/CustomArgumentsJSCheck.js index 49ad5cc..983d0e4 100644 --- a/src/finder/checks/AtomicChecks/CustomArgumentsJSCheck.js +++ b/src/finder/checks/AtomicChecks/CustomArgumentsJSCheck.js @@ -6,6 +6,7 @@ export default class CustomArgumentsJSCheck { this.id = 'CUSTOM_ARGUMENTS_JS_CHECK'; this.description = `Review the use of custom command line arguments`; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/Jeu1h"; this.dangerousArguments = [ "ignore-certificate-errors", "ignore-certificate-errors-spki-list", @@ -54,7 +55,7 @@ export default class CustomArgumentsJSCheck { }); if (res) - return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: false }]; + return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: false }]; } } } diff --git a/src/finder/checks/AtomicChecks/CustomArgumentsJSONCheck.js b/src/finder/checks/AtomicChecks/CustomArgumentsJSONCheck.js index fb20e9c..357cfff 100644 --- a/src/finder/checks/AtomicChecks/CustomArgumentsJSONCheck.js +++ b/src/finder/checks/AtomicChecks/CustomArgumentsJSONCheck.js @@ -8,6 +8,7 @@ export default class CustomArgumentsJSONCheck { this.id = 'CUSTOM_ARGUMENTS_JSON_CHECK'; this.description = `Search for dangerous runtime flags in the package.json file.`; this.type = sourceTypes.JSON; + this.shortenedURL = "https://git.io/Jeu1j"; this.dangerousArguments = [ "--ignore-certificate-errors", "--ignore-certificate-errors-spki-list", @@ -62,7 +63,7 @@ export default class CustomArgumentsJSONCheck { if (res) { let ln = linenumber(content.text, npmScripts[script]); - location.push({ line: ln[0].line, column: 0, id: this.id, description: this.description, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: false }); + location.push({ line: ln[0].line, column: 0, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: false }); } } @@ -80,7 +81,7 @@ export default class CustomArgumentsJSONCheck { if (res) { let ln = linenumber(content.text, npmConfig[config]); - location.push({ line: ln[0].line, column: 0, id: this.id, description: this.description, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: false }); + location.push({ line: ln[0].line, column: 0, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: false }); } } diff --git a/src/finder/checks/AtomicChecks/DangerousFunctionsJSCheck.js b/src/finder/checks/AtomicChecks/DangerousFunctionsJSCheck.js index bad0ac5..27c4938 100644 --- a/src/finder/checks/AtomicChecks/DangerousFunctionsJSCheck.js +++ b/src/finder/checks/AtomicChecks/DangerousFunctionsJSCheck.js @@ -6,6 +6,7 @@ export default class DangerousFunctionsJSCheck { this.id = 'DANGEROUS_FUNCTIONS_JS_CHECK'; this.description = `Do not use insertCSS, executeJavaScript, eval, Function, setTimeout, setInterval, setImmediate with user-supplied content`; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/Jeug9"; } match(astNode, astHelper, scope){ @@ -52,6 +53,6 @@ export default class DangerousFunctionsJSCheck { } if (shouldReport) - return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: true }]; + return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: true }]; } } diff --git a/src/finder/checks/AtomicChecks/ElectronVersionJSONCheck.js b/src/finder/checks/AtomicChecks/ElectronVersionJSONCheck.js index 959cd79..215f1be 100644 --- a/src/finder/checks/AtomicChecks/ElectronVersionJSONCheck.js +++ b/src/finder/checks/AtomicChecks/ElectronVersionJSONCheck.js @@ -7,6 +7,7 @@ export default class ElectronVersionJSONCheck { this.id = 'ELECTRON_VERSION_JSON_CHECK'; this.description = `Gets the electron version used by inspecting the package.json file.`; this.type = sourceTypes.JSON; + this.shortenedURL = "https://git.io/JeuMf"; } async match(content){ @@ -15,11 +16,11 @@ export default class ElectronVersionJSONCheck { let location = []; if (electron) { - location.push({ line: 1, column: 0, id: this.id, description: this.description, properties: { "versionNumber": electron.raw }, severity: severity.INFORMATIONAL, confidence: confidence.CERTAIN, manualReview: false }); + location.push({ line: 1, column: 0, id: this.id, description: this.description, shortenedURL: this.shortenedURL, properties: { "versionNumber": electron.raw }, severity: severity.INFORMATIONAL, confidence: confidence.CERTAIN, manualReview: false }); } if (electronDev) { - location.push({ line: 1, column: 0, id: this.id, description: this.description, properties: { "versionNumber": electronDev.raw }, severity: severity.INFORMATIONAL, confidence: confidence.CERTAIN, manualReview: true }); + location.push({ line: 1, column: 0, id: this.id, description: this.description, shortenedURL: this.shortenedURL, properties: { "versionNumber": electronDev.raw }, severity: severity.INFORMATIONAL, confidence: confidence.CERTAIN, manualReview: true }); } return location; diff --git a/src/finder/checks/AtomicChecks/ExperimentalFeaturesHTMLCheck.js b/src/finder/checks/AtomicChecks/ExperimentalFeaturesHTMLCheck.js index de9c55c..ea34b3c 100644 --- a/src/finder/checks/AtomicChecks/ExperimentalFeaturesHTMLCheck.js +++ b/src/finder/checks/AtomicChecks/ExperimentalFeaturesHTMLCheck.js @@ -7,6 +7,7 @@ export default class ExperimentalFeaturesHTMLCheck { this.id = 'EXPERIMENTAL_FEATURES_HTML_CHECK'; this.description = `Do not use Chromium's experimental features`; this.type = sourceTypes.HTML; + this.shortenedURL = "https://git.io/JeuMJ"; } match(cheerioObj, content) { @@ -18,7 +19,7 @@ export default class ExperimentalFeaturesHTMLCheck { if (wp) { let features = parseWebPreferencesFeaturesString(wp); if (features['experimentalFeatures'] === true || features['experimentalCanvasFeatures'] === true) - loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, severity: severity.LOW, confidence: confidence.CERTAIN, manualReview: false }); + loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, shortenedURL: self.shortenedURL, severity: severity.LOW, confidence: confidence.CERTAIN, manualReview: false }); } }); diff --git a/src/finder/checks/AtomicChecks/ExperimentalFeaturesJSCheck.js b/src/finder/checks/AtomicChecks/ExperimentalFeaturesJSCheck.js index 39805a2..ecf8104 100644 --- a/src/finder/checks/AtomicChecks/ExperimentalFeaturesJSCheck.js +++ b/src/finder/checks/AtomicChecks/ExperimentalFeaturesJSCheck.js @@ -6,6 +6,7 @@ export default class ExperimentalFeaturesJSCheck { this.id = 'EXPERIMENTAL_FEATURES_JS_CHECK'; this.description = `Do not use Chromium's experimental features`; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/JeuMI"; } match(astNode, astHelper, scope){ @@ -29,7 +30,7 @@ export default class ExperimentalFeaturesJSCheck { for (const node of found_nodes) { if (node.value.value === true) { - location.push({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description, severity: severity.LOW, confidence: confidence.CERTAIN, manualReview: false }); + location.push({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.LOW, confidence: confidence.CERTAIN, manualReview: false }); } } } diff --git a/src/finder/checks/AtomicChecks/HTTPResourcesHTMLCheck.js b/src/finder/checks/AtomicChecks/HTTPResourcesHTMLCheck.js index 06d9312..8dc0bf0 100644 --- a/src/finder/checks/AtomicChecks/HTTPResourcesHTMLCheck.js +++ b/src/finder/checks/AtomicChecks/HTTPResourcesHTMLCheck.js @@ -6,6 +6,7 @@ export default class HTTPResourcesHTMLCheck { this.id = 'HTTP_RESOURCES_HTML_CHECK'; this.description = `Do not allow insecure HTTP connections`; this.type = sourceTypes.HTML; + this.shortenedURL = "https://git.io/JeuMt"; } match(cheerioObj, content) { @@ -15,7 +16,7 @@ export default class HTTPResourcesHTMLCheck { webviews.each(function (i, elem) { let src = cheerioObj(this).attr('src'); if(src && (src.trim().toUpperCase().startsWith("HTTP://"))){ - loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: false }); + loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, shortenedURL: self.shortenedURL, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: false }); } }); diff --git a/src/finder/checks/AtomicChecks/HTTPResourcesJSCheck.js b/src/finder/checks/AtomicChecks/HTTPResourcesJSCheck.js index 6175fe8..01822d5 100644 --- a/src/finder/checks/AtomicChecks/HTTPResourcesJSCheck.js +++ b/src/finder/checks/AtomicChecks/HTTPResourcesJSCheck.js @@ -6,6 +6,7 @@ export default class HTTPResourcesJavascriptCheck { this.id = 'HTTP_RESOURCES_JS_CHECK'; this.description = `Do not allow insecure HTTP connections`; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/JeuML"; } match(astNode, astHelper){ @@ -27,6 +28,6 @@ export default class HTTPResourcesJavascriptCheck { return undefined; } - return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: false }]; + return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: false }]; } } diff --git a/src/finder/checks/AtomicChecks/InsecureContentHTMLCheck.js b/src/finder/checks/AtomicChecks/InsecureContentHTMLCheck.js index 4d2e951..825d3fe 100644 --- a/src/finder/checks/AtomicChecks/InsecureContentHTMLCheck.js +++ b/src/finder/checks/AtomicChecks/InsecureContentHTMLCheck.js @@ -7,6 +7,7 @@ export default class InsecureContentHTMLCheck { this.id = 'INSECURE_CONTENT_HTML_CHECK'; this.description = `Do not allow insecure HTTP connections`; this.type = sourceTypes.HTML; + this.shortenedURL = "https://git.io/JeuMq"; } match(cheerioObj, content) { @@ -18,7 +19,7 @@ export default class InsecureContentHTMLCheck { if (wp) { let features = parseWebPreferencesFeaturesString(wp); if (features['allowRunningInsecureContent'] === true) - loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: false }); + loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, shortenedURL: self.shortenedURL, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: false }); } }); diff --git a/src/finder/checks/AtomicChecks/InsecureContentJSCheck.js b/src/finder/checks/AtomicChecks/InsecureContentJSCheck.js index 4be0a1b..aff9e4c 100644 --- a/src/finder/checks/AtomicChecks/InsecureContentJSCheck.js +++ b/src/finder/checks/AtomicChecks/InsecureContentJSCheck.js @@ -6,6 +6,7 @@ export default class InsecureContentJSCheck { this.id = 'INSECURE_CONTENT_JS_CHECK'; this.description = `Do not allow insecure HTTP connections`; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/JeuMm"; } match(astNode, astHelper, scope){ @@ -26,7 +27,7 @@ export default class InsecureContentJSCheck { for (const node of found_nodes) { if (node.value.value === true) { - location.push({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: false }); + location.push({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: false }); } } } diff --git a/src/finder/checks/AtomicChecks/LimitNavigationJSCheck.js b/src/finder/checks/AtomicChecks/LimitNavigationJSCheck.js index be83556..5f9af3e 100644 --- a/src/finder/checks/AtomicChecks/LimitNavigationJSCheck.js +++ b/src/finder/checks/AtomicChecks/LimitNavigationJSCheck.js @@ -6,6 +6,7 @@ export default class LimitNavigationJSCheck { this.id = 'LIMIT_NAVIGATION_JS_CHECK'; this.description = 'Evaluate the implementation of the custom callback in the .on new-window and will-navigate events'; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/JeuM3"; } match(astNode){ @@ -14,7 +15,7 @@ export default class LimitNavigationJSCheck { if (astNode.arguments && astNode.arguments.length > 1) { var eventValue = astNode.arguments[0].value; if (astNode.arguments[0].type === "Literal" && (eventValue === "will-navigate" || eventValue === "new-window")) { - return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, severity: severity.HIGH, confidence: confidence.TENTATIVE, manualReview: true }]; + return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.HIGH, confidence: confidence.TENTATIVE, manualReview: true }]; } } } diff --git a/src/finder/checks/AtomicChecks/NodeIntegrationAttachEventJSCheck.js b/src/finder/checks/AtomicChecks/NodeIntegrationAttachEventJSCheck.js index f5bbeb8..bafbfdc 100644 --- a/src/finder/checks/AtomicChecks/NodeIntegrationAttachEventJSCheck.js +++ b/src/finder/checks/AtomicChecks/NodeIntegrationAttachEventJSCheck.js @@ -6,6 +6,7 @@ export default class NodeIntegrationAttachEventJSCheck { this.id = 'NODE_INTEGRATION_ATTACH_EVENT_JS_CHECK'; this.description = 'Disable nodeIntegration for untrusted origins'; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/JeuMZ"; } match(astNode, astHelper){ @@ -25,7 +26,7 @@ export default class NodeIntegrationAttachEventJSCheck { && node.left.property.name === 'nodeIntegration' && node.right.value === true); if (found_nodes.length > 0) { - loc.push({ line: found_nodes[0].loc.start.line, column: found_nodes[0].loc.start.column, id: this.id, description: this.description, severity: severity.HIGH, confidence: confidence.FIRM, manualReview: false }); + loc.push({ line: found_nodes[0].loc.start.line, column: found_nodes[0].loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.HIGH, confidence: confidence.FIRM, manualReview: false }); } } diff --git a/src/finder/checks/AtomicChecks/NodeIntegrationHTMLCheck.js b/src/finder/checks/AtomicChecks/NodeIntegrationHTMLCheck.js index d466abe..49d3231 100644 --- a/src/finder/checks/AtomicChecks/NodeIntegrationHTMLCheck.js +++ b/src/finder/checks/AtomicChecks/NodeIntegrationHTMLCheck.js @@ -6,6 +6,7 @@ export default class NodeIntegrationHTMLCheck { this.id = 'NODE_INTEGRATION_HTML_CHECK'; this.description = `Disable nodeIntegration for untrusted origins`; this.type = sourceTypes.HTML; + this.shortenedURL = "https://git.io/JeuMG"; } match(cheerioObj, content) { @@ -17,7 +18,7 @@ export default class NodeIntegrationHTMLCheck { const nodeintegrationInSubframes = cheerioObj(this).attr('nodeintegrationinsubframes'); if (nodeintegration !== undefined || nodeintegrationInSubframes !== undefined) { - loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, severity: severity.HIGH, confidence: confidence.FIRM, manualReview: false }); + loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, shortenedURL: self.shortenedURL, severity: severity.HIGH, confidence: confidence.FIRM, manualReview: false }); } }); return loc; diff --git a/src/finder/checks/AtomicChecks/NodeIntegrationJSCheck.js b/src/finder/checks/AtomicChecks/NodeIntegrationJSCheck.js index 57076db..4578bb5 100644 --- a/src/finder/checks/AtomicChecks/NodeIntegrationJSCheck.js +++ b/src/finder/checks/AtomicChecks/NodeIntegrationJSCheck.js @@ -6,6 +6,7 @@ export default class NodeIntegrationJSCheck { this.id = 'NODE_INTEGRATION_JS_CHECK'; this.description = `Disable nodeIntegration for untrusted origins`; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/JeuMn"; } //nodeIntegration Boolean (optional) - Whether node integration is enabled. Default is true. @@ -37,7 +38,7 @@ export default class NodeIntegrationJSCheck { } if (!nodeIntegrationFound) { - locations.push({ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, severity: severity.HIGH, confidence: confidence.FIRM, manualReview: false }); + locations.push({ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.HIGH, confidence: confidence.FIRM, manualReview: false }); } return locations; diff --git a/src/finder/checks/AtomicChecks/OpenExternalJSCheck.js b/src/finder/checks/AtomicChecks/OpenExternalJSCheck.js index fd6a37a..e250f30 100644 --- a/src/finder/checks/AtomicChecks/OpenExternalJSCheck.js +++ b/src/finder/checks/AtomicChecks/OpenExternalJSCheck.js @@ -6,6 +6,7 @@ export default class OpenExternalJSCheck { this.id = 'OPEN_EXTERNAL_JS_CHECK'; this.description = `Review the use of openExternal`; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/JeuMC"; } match(astNode, astHelper){ @@ -13,6 +14,6 @@ export default class OpenExternalJSCheck { if (!(astNode.callee.property && astNode.callee.property.name === "openExternal")) return null; if (astNode.arguments[0].type === astHelper.StringLiteral) return null; // constant, not user supplied - return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: true }]; + return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: true }]; } } diff --git a/src/finder/checks/AtomicChecks/PermissionRequestHandlerJSCheck.js b/src/finder/checks/AtomicChecks/PermissionRequestHandlerJSCheck.js index 49193f8..ee53410 100644 --- a/src/finder/checks/AtomicChecks/PermissionRequestHandlerJSCheck.js +++ b/src/finder/checks/AtomicChecks/PermissionRequestHandlerJSCheck.js @@ -6,12 +6,13 @@ export default class PermissionRequestHandlerJSCheck { this.id = 'PERMISSION_REQUEST_HANDLER_JS_CHECK'; this.description = 'Evaluate the implementation of the custom callback in setPermissionRequestHandler'; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/JeuMR"; } match(astNode){ if (astNode.type !== 'CallExpression') return null; if (astNode.callee.property && astNode.callee.property.name === "setPermissionRequestHandler") - return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: true }]; + return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: true }]; } } \ No newline at end of file diff --git a/src/finder/checks/AtomicChecks/PreloadJSCheck.js b/src/finder/checks/AtomicChecks/PreloadJSCheck.js index e728824..c3731f9 100644 --- a/src/finder/checks/AtomicChecks/PreloadJSCheck.js +++ b/src/finder/checks/AtomicChecks/PreloadJSCheck.js @@ -6,6 +6,7 @@ export default class PreloadJSCheck { this.id = 'PRELOAD_JS_CHECK'; this.description = `Review the use of preload scripts`; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/JeuMu"; } match(astNode, astHelper, scope){ @@ -25,7 +26,7 @@ export default class PreloadJSCheck { node => (node.key.value === 'preload' || node.key.name === 'preload')); for (const node of found_nodes) - location.push ({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description, severity: severity.MEDIUM, confidence: confidence.FIRM, manualReview: true }); + location.push ({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.FIRM, manualReview: true }); } return location; diff --git a/src/finder/checks/AtomicChecks/ProtocolHandlersJSCheck.js b/src/finder/checks/AtomicChecks/ProtocolHandlersJSCheck.js index 7674005..f836901 100644 --- a/src/finder/checks/AtomicChecks/ProtocolHandlersJSCheck.js +++ b/src/finder/checks/AtomicChecks/ProtocolHandlersJSCheck.js @@ -6,6 +6,7 @@ export default class ProtocolHandlerJSCheck { this.id = 'PROTOCOL_HANDLER_JS_CHECK'; this.description = `Review the use of custom protocol handlers`; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/JeuMz"; } match(astNode){ @@ -22,6 +23,6 @@ export default class ProtocolHandlerJSCheck { if (astNode.type !== 'CallExpression') return null; if (!methods.includes(astNode.callee.name) && !(astNode.callee.property && methods.includes(astNode.callee.property.name))) return null; - return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: true }]; + return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.TENTATIVE, manualReview: true }]; } } diff --git a/src/finder/checks/AtomicChecks/SandboxJSCheck.js b/src/finder/checks/AtomicChecks/SandboxJSCheck.js index 0af7ea8..6f7a124 100644 --- a/src/finder/checks/AtomicChecks/SandboxJSCheck.js +++ b/src/finder/checks/AtomicChecks/SandboxJSCheck.js @@ -6,6 +6,7 @@ export default class SandboxJSCheck { this.id = 'SANDBOX_JS_CHECK'; this.description = `Use sandbox for untrusted origins`; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/JeuM2"; } match(astNode, astHelper, scope){ @@ -29,14 +30,14 @@ export default class SandboxJSCheck { if (node.value.value === true) { continue; } - loc.push({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description, severity: severity.MEDIUM, confidence: confidence.FIRM, manualReview: false }); + loc.push({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.FIRM, manualReview: false }); } } if (wasFound) { return loc; } else { // default is false - return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, severity: severity.MEDIUM, confidence: confidence.FIRM, manualReview: false }]; + return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.FIRM, manualReview: false }]; } } } diff --git a/src/finder/checks/AtomicChecks/SecurityWarningsDisabledJSCheck.js b/src/finder/checks/AtomicChecks/SecurityWarningsDisabledJSCheck.js index 2301191..e05aec6 100644 --- a/src/finder/checks/AtomicChecks/SecurityWarningsDisabledJSCheck.js +++ b/src/finder/checks/AtomicChecks/SecurityWarningsDisabledJSCheck.js @@ -6,6 +6,7 @@ export default class SecurityWarningsDisabledJSCheck { this.id = 'SECURITY_WARNINGS_DISABLED_JS_CHECK'; this.description = 'Warns about flags disabling security warnings in the sources.'; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/JeuMa"; } match(astNode){ @@ -14,12 +15,12 @@ export default class SecurityWarningsDisabledJSCheck { if (astNode.left.object && astNode.left.object.property) { if (astNode.left.object.property.name === "env" || astNode.left.object.property.name === "webContents") { if (astNode.left.property && astNode.left.property.value && astNode.left.property.value.toString().toUpperCase() === "ELECTRON_DISABLE_SECURITY_WARNINGS" && astNode.right.value) - return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, severity: severity.INFORMATIONAL, confidence: confidence.CERTAIN, manualReview: false }]; + return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.INFORMATIONAL, confidence: confidence.CERTAIN, manualReview: false }]; } } if (astNode.left.property && astNode.left.property.name && astNode.left.property.name === "ELECTRON_DISABLE_SECURITY_WARNINGS" && astNode.right.value) { - return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, severity: severity.INFORMATIONAL, confidence: confidence.CERTAIN, manualReview: false }]; + return [{ line: astNode.loc.start.line, column: astNode.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.INFORMATIONAL, confidence: confidence.CERTAIN, manualReview: false }]; } else return null; } diff --git a/src/finder/checks/AtomicChecks/SecurityWarningsDisabledJSONCheck.js b/src/finder/checks/AtomicChecks/SecurityWarningsDisabledJSONCheck.js index 93514ff..fbfd3c1 100644 --- a/src/finder/checks/AtomicChecks/SecurityWarningsDisabledJSONCheck.js +++ b/src/finder/checks/AtomicChecks/SecurityWarningsDisabledJSONCheck.js @@ -7,6 +7,7 @@ export default class SecurityWarningsDisabledJSONCheck { this.id = 'SECURITY_WARNINGS_DISABLED_JSON_CHECK'; this.description = `Warns about flags disabling security warnings in the package.json file.`; this.type = sourceTypes.JSON; + this.shortenedURL = "https://git.io/JeuMw"; this.dangerousFlag = "ELECTRON_DISABLE_SECURITY_WARNINGS"; } @@ -26,7 +27,7 @@ export default class SecurityWarningsDisabledJSONCheck { if (res) { let ln = linenumber(content.text, npmScripts[script]); - location.push({ line: ln[0].line, column: 0, id: this.id, description: this.description, severity: severity.INFORMATIONAL, confidence: confidence.CERTAIN, manualReview: false }); + location.push({ line: ln[0].line, column: 0, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.INFORMATIONAL, confidence: confidence.CERTAIN, manualReview: false }); } } @@ -42,7 +43,7 @@ export default class SecurityWarningsDisabledJSONCheck { if (res) { let ln = linenumber(content.text, npmConfig[config]); - location.push({ line: ln[0].line, column: 0, id: this.id, description: this.description, severity: severity.INFORMATIONAL, confidence: confidence.CERTAIN, manualReview: false }); + location.push({ line: ln[0].line, column: 0, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.INFORMATIONAL, confidence: confidence.CERTAIN, manualReview: false }); } } diff --git a/src/finder/checks/AtomicChecks/WebSecurityHTMLCheck.js b/src/finder/checks/AtomicChecks/WebSecurityHTMLCheck.js index 609f00f..e6fa7e1 100644 --- a/src/finder/checks/AtomicChecks/WebSecurityHTMLCheck.js +++ b/src/finder/checks/AtomicChecks/WebSecurityHTMLCheck.js @@ -7,6 +7,7 @@ export default class WebSecurityHTMLCheck { this.id = 'WEB_SECURITY_HTML_CHECK'; this.description = `Do not use disablewebsecurity`; this.type = sourceTypes.HTML; + this.shortenedURL = "https://git.io/JeuMr"; } match(cheerioObj, content) { @@ -16,14 +17,14 @@ export default class WebSecurityHTMLCheck { webviews.each(function (i, elem) { const disablewebsecurity = cheerioObj(this).attr('disablewebsecurity'); if (disablewebsecurity !== undefined) { - loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, severity: severity.MEDIUM, confidence: confidence.CERTAIN, description: self.description, manualReview: false }); + loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, severity: severity.MEDIUM, confidence: confidence.CERTAIN, description: self.description, shortenedURL: self.shortenedURL, manualReview: false }); } let wp = cheerioObj(this).attr('webpreferences'); if (wp) { let features = parseWebPreferencesFeaturesString(wp); if (features['webSecurity'] === false) - loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: false }); + loc.push({ line: content.substr(0, elem.startIndex).split('\n').length, column: 0, id: self.id, description: self.description, shortenedURL: self.shortenedURL, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: false }); } }); diff --git a/src/finder/checks/AtomicChecks/WebSecurityJSCheck.js b/src/finder/checks/AtomicChecks/WebSecurityJSCheck.js index ee5d416..e6cea8d 100644 --- a/src/finder/checks/AtomicChecks/WebSecurityJSCheck.js +++ b/src/finder/checks/AtomicChecks/WebSecurityJSCheck.js @@ -6,6 +6,7 @@ export default class WebSecurityJSCheck { this.id = 'WEB_SECURITY_JS_CHECK'; this.description = `Do not use disablewebsecurity`; this.type = sourceTypes.JAVASCRIPT; + this.shortenedURL = "https://git.io/JeuMo"; } match(astNode, astHelper, scope){ @@ -26,7 +27,7 @@ export default class WebSecurityJSCheck { for (const node of found_nodes) { if (node.value.value === false) { - location.push({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: false }); + location.push({ line: node.key.loc.start.line, column: node.key.loc.start.column, id: this.id, description: this.description, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: false }); } } } diff --git a/src/finder/checks/GlobalChecks/AffinityGlobalCheck.js b/src/finder/checks/GlobalChecks/AffinityGlobalCheck.js index bcd09cb..4c95b11 100644 --- a/src/finder/checks/GlobalChecks/AffinityGlobalCheck.js +++ b/src/finder/checks/GlobalChecks/AffinityGlobalCheck.js @@ -6,6 +6,7 @@ export default class AffinityGlobalCheck { this.id = "AFFINITY_GLOBAL_CHECK"; this.description = { AFFINITY_FOUND: "Two or more rendereres are running with the same affinity property. Manual review is required since we don't check for the webPreferences."}; this.depends = ["AffinityJSCheck", "AffinityHTMLCheck"]; + this.shortenedURL = "https://git.io/Jeu1z"; } async perform(issues) { @@ -21,7 +22,7 @@ export default class AffinityGlobalCheck { var duplicates = Object.keys(uniq).filter((a) => uniq[a] > 1); if (duplicates.length > 0) { - otherIssues.push({ file: affinityIssues[0].file, location: {line: 0, column: 0}, id: this.id, description: this.description.AFFINITY_FOUND, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: true }); + otherIssues.push({ file: affinityIssues[0].file, location: {line: 0, column: 0}, id: this.id, description: this.description.AFFINITY_FOUND, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: true }); } } diff --git a/src/finder/checks/GlobalChecks/AvailableSecurityFixesGlobalCheck.js b/src/finder/checks/GlobalChecks/AvailableSecurityFixesGlobalCheck.js index ded3e6f..ce79d6d 100644 --- a/src/finder/checks/GlobalChecks/AvailableSecurityFixesGlobalCheck.js +++ b/src/finder/checks/GlobalChecks/AvailableSecurityFixesGlobalCheck.js @@ -12,6 +12,7 @@ export default class AvailableSecurityFixesGlobalCheck { this.description = { SECURITY_ISSUES : "Check if there are security patches applied in between the Electron version used and the latest", OUTDATED_VERSION : "A new version of Electron is available" }; this.depends = ["ElectronVersionJSONCheck"]; + this.shortenedURL = "https://git.io/Jeu1X"; this.releaseNoteSecurityFixRegex = [ /# Security/i, /\[security\]/i ]; this.githubEtagRegex = /[0-9a-f]{40}/g; this.releasesFilePath = path.resolve(path.dirname(process.argv[1]), '..'); @@ -38,9 +39,9 @@ export default class AvailableSecurityFixesGlobalCheck { var hasSecurityFixAvailable = await this.checkSecurityFixes(issue.properties.versionNumber, releases); if (hasSecurityFixAvailable) { if (issue.manualReview) // found in devDependencies - otherIssues.push({ file: versionCheckIssues[0].file, location: {line: 0, column: 0}, id: this.id, description: this.description.SECURITY_ISSUES, severity: severity.INFORMATIONAL, confidence: confidence.CERTAIN, manualReview: issue.manualReview }); + otherIssues.push({ file: versionCheckIssues[0].file, location: {line: 0, column: 0}, id: this.id, description: this.description.SECURITY_ISSUES, shortenedURL: this.shortenedURL, severity: severity.INFORMATIONAL, confidence: confidence.CERTAIN, manualReview: issue.manualReview }); else // found in dependencies - otherIssues.push({ file: versionCheckIssues[0].file, location: {line: 0, column: 0}, id: this.id, description: this.description.SECURITY_ISSUES, severity: severity.HIGH, confidence: confidence.CERTAIN, manualReview: issue.manualReview }); + otherIssues.push({ file: versionCheckIssues[0].file, location: {line: 0, column: 0}, id: this.id, description: this.description.SECURITY_ISSUES, shortenedURL: this.shortenedURL, severity: severity.HIGH, confidence: confidence.CERTAIN, manualReview: issue.manualReview }); } } } diff --git a/src/finder/checks/GlobalChecks/CSPGlobalCheck.js b/src/finder/checks/GlobalChecks/CSPGlobalCheck.js index 8772707..39f025d 100644 --- a/src/finder/checks/GlobalChecks/CSPGlobalCheck.js +++ b/src/finder/checks/GlobalChecks/CSPGlobalCheck.js @@ -9,6 +9,7 @@ export default class CSPGlobalCheck { MAYBE_WEAK_CSP: "One or more CSP directives detected seems to be vulnerable", WEAK_CSP: "One or more CSP directives detected are vulnerable" }; this.depends = ["CSPJSCheck", "CSPHTMLCheck"]; + this.shortenedURL = "https://git.io/JeuMe"; } async perform(issues) { @@ -16,7 +17,7 @@ export default class CSPGlobalCheck { var otherIssues = issues.filter(e => e.id !== 'CSP_JS_CHECK' && e.id !== 'CSP_HTML_CHECK'); if (cspIssues.length === 0) { // No CSP detected - issues.push({ file: "N/A", location: {line: 0, column: 0}, id: this.id, description: this.description.NO_CSP, severity: attributes.severity.MEDIUM, confidence: attributes.confidence.CERTAIN, manualReview: false }); + issues.push({ file: "N/A", location: {line: 0, column: 0}, id: this.id, description: this.description.NO_CSP, shortenedURL: this.shortenedURL, severity: attributes.severity.MEDIUM, confidence: attributes.confidence.CERTAIN, manualReview: false }); return issues; } else { // There is a CSP set @@ -33,9 +34,9 @@ export default class CSPGlobalCheck { } if (confidence === 2) - otherIssues.push({ file: cspIssues[0].file, location: cspIssues[0].location, id: this.id, description: this.description.WEAK_CSP, severity: attributes.severity.LOW, confidence: attributes.confidence.CERTAIN, sample: cspIssue.properties.CSPstring, manualReview: false }); + otherIssues.push({ file: cspIssues[0].file, location: cspIssues[0].location, id: this.id, description: this.description.WEAK_CSP, shortenedURL: this.shortenedURL, severity: attributes.severity.LOW, confidence: attributes.confidence.CERTAIN, sample: cspIssue.properties.CSPstring, manualReview: false }); if (confidence === 1) - otherIssues.push({ file: cspIssues[0].file, location: cspIssues[0].location, id: this.id, description: this.description.MAYBE_WEAK_CSP, severity: attributes.severity.LOW, confidence: attributes.confidence.FIRM, sample: cspIssue.properties.CSPstring, manualReview: true }); + otherIssues.push({ file: cspIssues[0].file, location: cspIssues[0].location, id: this.id, description: this.description.MAYBE_WEAK_CSP, shortenedURL: this.shortenedURL, severity: attributes.severity.LOW, confidence: attributes.confidence.FIRM, sample: cspIssue.properties.CSPstring, manualReview: true }); return otherIssues; diff --git a/src/finder/checks/GlobalChecks/HTTPResourcesAndNodeIntegrationGlobalCheck.js b/src/finder/checks/GlobalChecks/HTTPResourcesAndNodeIntegrationGlobalCheck.js index 639fb62..87ee772 100644 --- a/src/finder/checks/GlobalChecks/HTTPResourcesAndNodeIntegrationGlobalCheck.js +++ b/src/finder/checks/GlobalChecks/HTTPResourcesAndNodeIntegrationGlobalCheck.js @@ -6,6 +6,7 @@ export default class HTTPResourcesAndNodeIntegrationGlobalCheck { this.id = "HTTP_RESOURCES_WITH_NODE_INTEGRATION_GLOBAL_CHECK"; this.description = { INSECURE_INTEGRATION: "The nodeIntegration flag is enabled for the application, but some resources are loaded over an unencrypted connection."}; this.depends = ["HTTPResourcesJavascriptCheck","HTTPResourcesHTMLCheck","NodeIntegrationHTMLCheck", "NodeIntegrationJSCheck"]; + this.shortenedURL = "https://git.io/JeuM6"; } async perform(issues) { @@ -13,7 +14,7 @@ export default class HTTPResourcesAndNodeIntegrationGlobalCheck { var nodeIntegrationIssues = issues.filter(e => e.id === 'NODE_INTEGRATION_HTML_CHECK' || e.id === 'NODE_INTEGRATION_JS_CHECK'); if (httpResourcesIssues.length > 0 && nodeIntegrationIssues.length > 0) - issues.push({ file: "N/A", location: {line: 0, column: 0}, id: this.id, description: this.description.INSECURE_INTEGRATION, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: true }); + issues.push({ file: "N/A", location: {line: 0, column: 0}, id: this.id, description: this.description.INSECURE_INTEGRATION, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: true }); return issues; diff --git a/src/finder/checks/GlobalChecks/LimitNavigationGlobalCheck.js b/src/finder/checks/GlobalChecks/LimitNavigationGlobalCheck.js index 615a64f..4151676 100644 --- a/src/finder/checks/GlobalChecks/LimitNavigationGlobalCheck.js +++ b/src/finder/checks/GlobalChecks/LimitNavigationGlobalCheck.js @@ -6,6 +6,7 @@ export default class LimitNavigationGlobalCheck { this.id = "LIMIT_NAVIGATION_GLOBAL_CHECK"; this.description = { NONE_FOUND: "Missing navigation limits using .on new-window and will-navigate events" }; this.depends = ["LimitNavigationJSCheck"]; + this.shortenedURL = "https://git.io/JeuMs"; } async perform(issues) { @@ -13,7 +14,7 @@ export default class LimitNavigationGlobalCheck { var otherIssues = issues.filter(e => e.id !== 'LIMIT_NAVIGATION_JS_CHECK'); if (limitNavigationIssues.length === 0) { - otherIssues.push({ file: "N/A", location: {line: 0, column: 0}, id: this.id, description: this.description.NONE_FOUND,severity: severity.HIGH, confidence: confidence.CERTAIN, manualReview: false }); + otherIssues.push({ file: "N/A", location: {line: 0, column: 0}, id: this.id, description: this.description.NONE_FOUND, shortenedURL: this.shortenedURL, severity: severity.HIGH, confidence: confidence.CERTAIN, manualReview: false }); return otherIssues; } else { return issues; diff --git a/src/finder/checks/GlobalChecks/PermissionRequestHandlerGlobalCheck.js b/src/finder/checks/GlobalChecks/PermissionRequestHandlerGlobalCheck.js index 351274b..21dfcc1 100644 --- a/src/finder/checks/GlobalChecks/PermissionRequestHandlerGlobalCheck.js +++ b/src/finder/checks/GlobalChecks/PermissionRequestHandlerGlobalCheck.js @@ -6,6 +6,7 @@ export default class PermissionRequestHandlerGlobalCheck { this.id = "PERMISSION_REQUEST_HANDLER_GLOBAL_CHECK"; this.description = { NONE_FOUND: "Missing PermissionRequestHandler to limit specific permissions (e.g. openExternal) in response to events from particular origins."}; this.depends = ["PermissionRequestHandlerJSCheck"]; + this.shortenedURL = "https://git.io/JeuM0"; } async perform(issues) { @@ -13,7 +14,7 @@ export default class PermissionRequestHandlerGlobalCheck { var otherIssues = issues.filter(e => e.id !== 'PERMISSION_REQUEST_HANDLER_JS_CHECK'); if (permissionRequestHandlerIssues.length === 0) { - otherIssues.push({ file: "N/A", location: {line: 0, column: 0}, id: this.id, description: this.description.NONE_FOUND,severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: false }); + otherIssues.push({ file: "N/A", location: {line: 0, column: 0}, id: this.id, description: this.description.NONE_FOUND, shortenedURL: this.shortenedURL, severity: severity.MEDIUM, confidence: confidence.CERTAIN, manualReview: false }); return otherIssues; } else { return issues; diff --git a/src/finder/finder.js b/src/finder/finder.js index 829d02a..93584ae 100644 --- a/src/finder/finder.js +++ b/src/finder/finder.js @@ -64,7 +64,7 @@ export class Finder { if (matches) { for(const m of matches) { const sample = this.get_sample(fileLines, m.line - 1); - const issue = { file, sample, location: {line: m.line, column: m.column}, id: m.id, description: m.description, properties: m.properties, severity: m.severity, confidence: m.confidence, manualReview: m.manualReview }; + const issue = { file, sample, location: {line: m.line, column: m.column}, id: m.id, description: m.description, properties: m.properties, severity: m.severity, confidence: m.confidence, manualReview: m.manualReview, shortenedURL: m.shortenedURL }; issues.push(issue); } } @@ -82,7 +82,7 @@ export class Finder { if(matches){ for(const m of matches) { const sample = this.get_sample(fileLines, m.line - 1); - const issue = {file, sample, location: {line: m.line, column: m.column}, id: m.id, description: m.description, properties: m.properties, severity: m.severity, confidence: m.confidence, manualReview: m.manualReview}; + const issue = {file, sample, location: {line: m.line, column: m.column}, id: m.id, description: m.description, properties: m.properties, severity: m.severity, confidence: m.confidence, manualReview: m.manualReview, shortenedURL: m.shortenedURL }; issues.push(issue); } } @@ -94,7 +94,7 @@ export class Finder { if (matches) { for(const m of matches) { const sample = this.get_sample(fileLines, m.line - 1); - const issue = {file, sample, location: {line: m.line, column: m.column}, id: m.id, description: m.description, properties: m.properties, severity: m.severity, confidence: m.confidence, manualReview: m.manualReview}; + const issue = {file, sample, location: {line: m.line, column: m.column}, id: m.id, description: m.description, properties: m.properties, severity: m.severity, confidence: m.confidence, manualReview: m.manualReview, shortenedURL: m.shortenedURL }; issues.push(issue); } } diff --git a/src/index.js b/src/index.js index c23278e..836e936 100644 --- a/src/index.js +++ b/src/index.js @@ -30,7 +30,8 @@ program .option('-s, --severity ', 'only return findings with the specified level of severity or above') .option('-c, --confidence ', 'only return findings with the specified level of confidence or above') .option('-o, --output ', 'save the results to a file in csv or sarif format') - .option('-r, --relative','show relative path for files') + .option('-r, --relative', 'show relative path for files') + .option('-v, --verbose', 'show the description for the findings') .parse(process.argv); if(!program.input){ @@ -51,6 +52,11 @@ if (typeof program.checks !== 'undefined' && program.checks){ program.checks = program.checks.split(",").map(check => check.trim().toLowerCase()); } else program.checks = []; +if (typeof program.verbose !== 'undefined' && program.verbose) + program.verbose = true; +else + program.verbose = false; + const input = path.resolve(program.input); -run(input, program.output, program.fileFormat === 'sarif', program.checks, program.severity, program.confidence, program.relative); +run(input, program.output, program.fileFormat === 'sarif', program.checks, program.severity, program.confidence, program.relative, program.verbose); diff --git a/src/runner.js b/src/runner.js index 8eb5a6e..1d435f8 100644 --- a/src/runner.js +++ b/src/runner.js @@ -1,5 +1,5 @@ import cliProgress from 'cli-progress'; -import Table from 'cli-table2'; +import Table from 'cli-table3'; import chalk from 'chalk'; import { LoaderFile, LoaderAsar, LoaderDirectory } from './loader'; @@ -8,7 +8,7 @@ import { Finder } from './finder'; import { GlobalChecks, severity, confidence } from './finder'; import { extension, input_exists, is_directory, writeIssues, getRelativePath } from './util'; -export default async function run(input, output, isSarif, customScan, severitySet, confidenceSet, isRelative) { +export default async function run(input, output, isSarif, customScan, severitySet, confidenceSet, isRelative, isVerbose) { if (!input_exists(input)) { console.log(chalk.red('Input does not exist!')); process.exit(1); @@ -49,6 +49,7 @@ export default async function run(input, output, isSarif, customScan, severitySe let errors = []; let table = new Table({ head: ['Check ID', 'Affected File', 'Location', 'Issue Description'], + colWidths:[undefined, undefined, undefined, 50], // necessary for wordWrap wordWrap: true }); @@ -104,7 +105,7 @@ export default async function run(input, output, isSarif, customScan, severitySe // Now that we have all the "naive" findings we may analyze them further to sort out false negatives // and false positives before presenting them in the final report (e.g. CSP) issues = await globalChecker.getResults(issues); - + // adjust to Relative or Absolute path if (isRelative) @@ -119,7 +120,7 @@ export default async function run(input, output, isSarif, customScan, severitySe `${issue.id}${issue.manualReview ? chalk.bgRed(`\n*Review Required*`) : ``}\n${issue.severity.format()} | ${issue.confidence.format()}`, issue.file, `${issue.location.line}:${issue.location.column}`, - `https://github.com/doyensec/electronegativity/wiki/${issue.id}` + `${ isVerbose ? issue.description + '\n' + issue.shortenedURL : issue.shortenedURL}` ]); }