@contrast/contrast 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierignore +2 -0
- package/README.md +120 -47
- package/dist/audit/AnalysisEngine.js +37 -0
- package/dist/audit/catalogueApplication/catalogueApplication.js +36 -0
- package/dist/audit/dotnetAnalysisEngine/index.js +25 -0
- package/dist/audit/dotnetAnalysisEngine/parseLockFileContents.js +35 -0
- package/dist/audit/dotnetAnalysisEngine/parseProjectFileContents.js +15 -0
- package/dist/audit/dotnetAnalysisEngine/readLockFileContents.js +18 -0
- package/dist/audit/dotnetAnalysisEngine/readProjectFileContents.js +14 -0
- package/dist/audit/dotnetAnalysisEngine/sanitizer.js +9 -0
- package/dist/audit/goAnalysisEngine/index.js +17 -0
- package/dist/audit/goAnalysisEngine/parseProjectFileContents.js +164 -0
- package/dist/audit/goAnalysisEngine/readProjectFileContents.js +21 -0
- package/dist/audit/goAnalysisEngine/sanitizer.js +5 -0
- package/dist/audit/javaAnalysisEngine/index.js +34 -0
- package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +153 -0
- package/dist/audit/javaAnalysisEngine/parseProjectFileContents.js +353 -0
- package/dist/audit/javaAnalysisEngine/readProjectFileContents.js +98 -0
- package/dist/audit/javaAnalysisEngine/sanitizer.js +5 -0
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +24 -0
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +24 -0
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +35 -0
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +23 -0
- package/dist/audit/languageAnalysisEngine/commonApi.js +18 -0
- package/dist/audit/languageAnalysisEngine/constants.js +20 -0
- package/dist/audit/languageAnalysisEngine/filterProjectPath.js +20 -0
- package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +25 -0
- package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +39 -0
- package/dist/audit/languageAnalysisEngine/index.js +39 -0
- package/dist/audit/languageAnalysisEngine/langugageAnalysisFactory.js +70 -0
- package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +121 -0
- package/dist/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +17 -0
- package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +257 -0
- package/dist/audit/languageAnalysisEngine/report/newReportingFeature.js +81 -0
- package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +133 -0
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +41 -0
- package/dist/audit/languageAnalysisEngine/util/capabilities.js +11 -0
- package/dist/audit/languageAnalysisEngine/util/generalAPI.js +39 -0
- package/dist/audit/languageAnalysisEngine/util/requestUtils.js +14 -0
- package/dist/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +40 -0
- package/dist/audit/nodeAnalysisEngine/index.js +31 -0
- package/dist/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +18 -0
- package/dist/audit/nodeAnalysisEngine/parseYarn2LockFileContents.js +51 -0
- package/dist/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +18 -0
- package/dist/audit/nodeAnalysisEngine/readNPMLockFileContents.js +17 -0
- package/dist/audit/nodeAnalysisEngine/readProjectFileContents.js +14 -0
- package/dist/audit/nodeAnalysisEngine/readYarnLockFileContents.js +24 -0
- package/dist/audit/nodeAnalysisEngine/sanitizer.js +9 -0
- package/dist/audit/phpAnalysisEngine/index.js +23 -0
- package/dist/audit/phpAnalysisEngine/parseLockFileContents.js +52 -0
- package/dist/audit/phpAnalysisEngine/readLockFileContents.js +13 -0
- package/dist/audit/phpAnalysisEngine/readProjectFileContents.js +16 -0
- package/dist/audit/phpAnalysisEngine/sanitizer.js +5 -0
- package/dist/audit/pythonAnalysisEngine/index.js +25 -0
- package/dist/audit/pythonAnalysisEngine/parsePipfileLockContents.js +17 -0
- package/dist/audit/pythonAnalysisEngine/parseProjectFileContents.js +21 -0
- package/dist/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +13 -0
- package/dist/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +14 -0
- package/dist/audit/pythonAnalysisEngine/sanitizer.js +7 -0
- package/dist/audit/rubyAnalysisEngine/index.js +25 -0
- package/dist/audit/rubyAnalysisEngine/parseGemfileLockContents.js +176 -0
- package/dist/audit/rubyAnalysisEngine/parsedGemfile.js +22 -0
- package/dist/audit/rubyAnalysisEngine/readGemfileContents.js +14 -0
- package/dist/audit/rubyAnalysisEngine/readGemfileLockContents.js +14 -0
- package/dist/audit/rubyAnalysisEngine/sanitizer.js +6 -0
- package/dist/commands/audit/auditConfig.js +25 -0
- package/dist/commands/audit/auditController.js +31 -0
- package/dist/commands/audit/help.js +52 -0
- package/dist/commands/audit/processAudit.js +18 -0
- package/dist/commands/auth/auth.js +1 -1
- package/dist/commands/scan/processScan.js +19 -5
- package/dist/common/HTTPClient.js +101 -13
- package/dist/common/errorHandling.js +49 -1
- package/dist/common/findLatestCLIVersion.js +23 -0
- package/dist/constants/constants.js +1 -1
- package/dist/constants/lambda.js +32 -4
- package/dist/constants/locales.js +39 -16
- package/dist/constants.js +148 -20
- package/dist/index.js +7 -1
- package/dist/lambda/aws.js +14 -11
- package/dist/lambda/help.js +4 -0
- package/dist/lambda/lambda.js +50 -27
- package/dist/lambda/lambdaUtils.js +72 -0
- package/dist/lambda/logUtils.js +11 -1
- package/dist/lambda/scanDetailCompletion.js +4 -4
- package/dist/lambda/scanRequest.js +11 -5
- package/dist/lambda/utils.js +110 -53
- package/dist/scan/autoDetection.js +0 -32
- package/dist/scan/fileUtils.js +1 -1
- package/dist/scan/help.js +12 -40
- package/dist/scan/populateProjectIdAndProjectName.js +4 -0
- package/dist/scan/saveResults.js +15 -0
- package/dist/scan/scan.js +77 -42
- package/dist/scan/scanConfig.js +20 -0
- package/dist/scan/scanController.js +13 -15
- package/dist/scan/scanResults.js +18 -16
- package/dist/utils/commonApi.js +3 -3
- package/dist/utils/fileUtils.js +31 -0
- package/dist/utils/paramsUtil/commandlineParams.js +1 -20
- package/dist/utils/paramsUtil/genericCommandLineParams.js +12 -0
- package/dist/utils/paramsUtil/paramHandler.js +3 -6
- package/dist/utils/parsedCLIOptions.js +14 -8
- package/package.json +26 -21
- package/src/audit/AnalysisEngine.js +103 -0
- package/src/audit/catalogueApplication/catalogueApplication.js +42 -0
- package/src/audit/dotnetAnalysisEngine/index.js +26 -0
- package/src/audit/dotnetAnalysisEngine/parseLockFileContents.js +47 -0
- package/src/audit/dotnetAnalysisEngine/parseProjectFileContents.js +29 -0
- package/src/audit/dotnetAnalysisEngine/readLockFileContents.js +30 -0
- package/src/audit/dotnetAnalysisEngine/readProjectFileContents.js +26 -0
- package/src/audit/dotnetAnalysisEngine/sanitizer.js +11 -0
- package/src/audit/goAnalysisEngine/index.js +18 -0
- package/src/audit/goAnalysisEngine/parseProjectFileContents.js +209 -0
- package/src/audit/goAnalysisEngine/readProjectFileContents.js +31 -0
- package/src/audit/goAnalysisEngine/sanitizer.js +7 -0
- package/src/audit/javaAnalysisEngine/index.js +41 -0
- package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +222 -0
- package/src/audit/javaAnalysisEngine/parseProjectFileContents.js +420 -0
- package/src/audit/javaAnalysisEngine/readProjectFileContents.js +141 -0
- package/src/audit/javaAnalysisEngine/sanitizer.js +6 -0
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +35 -0
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +41 -0
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +54 -0
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +32 -0
- package/src/audit/languageAnalysisEngine/commonApi.js +20 -0
- package/src/audit/languageAnalysisEngine/constants.js +23 -0
- package/src/audit/languageAnalysisEngine/filterProjectPath.js +21 -0
- package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +41 -0
- package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +72 -0
- package/src/audit/languageAnalysisEngine/index.js +45 -0
- package/src/audit/languageAnalysisEngine/langugageAnalysisFactory.js +94 -0
- package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +177 -0
- package/src/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +27 -0
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.js +303 -0
- package/src/audit/languageAnalysisEngine/report/newReportingFeature.js +124 -0
- package/src/audit/languageAnalysisEngine/report/reportingFeature.js +190 -0
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +51 -0
- package/src/audit/languageAnalysisEngine/util/capabilities.js +12 -0
- package/src/audit/languageAnalysisEngine/util/generalAPI.js +43 -0
- package/src/audit/languageAnalysisEngine/util/requestUtils.js +17 -0
- package/src/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +49 -0
- package/src/audit/nodeAnalysisEngine/index.js +35 -0
- package/src/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +20 -0
- package/src/audit/nodeAnalysisEngine/parseYarn2LockFileContents.js +63 -0
- package/src/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +26 -0
- package/src/audit/nodeAnalysisEngine/readNPMLockFileContents.js +23 -0
- package/src/audit/nodeAnalysisEngine/readProjectFileContents.js +27 -0
- package/src/audit/nodeAnalysisEngine/readYarnLockFileContents.js +36 -0
- package/src/audit/nodeAnalysisEngine/sanitizer.js +11 -0
- package/src/audit/phpAnalysisEngine/index.js +27 -0
- package/src/audit/phpAnalysisEngine/parseLockFileContents.js +60 -0
- package/src/audit/phpAnalysisEngine/readLockFileContents.js +14 -0
- package/src/audit/phpAnalysisEngine/readProjectFileContents.js +25 -0
- package/src/audit/phpAnalysisEngine/sanitizer.js +4 -0
- package/src/audit/pythonAnalysisEngine/index.js +55 -0
- package/src/audit/pythonAnalysisEngine/parsePipfileLockContents.js +23 -0
- package/src/audit/pythonAnalysisEngine/parseProjectFileContents.js +33 -0
- package/src/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +16 -0
- package/src/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +22 -0
- package/src/audit/pythonAnalysisEngine/sanitizer.js +9 -0
- package/src/audit/rubyAnalysisEngine/index.js +30 -0
- package/src/audit/rubyAnalysisEngine/parseGemfileLockContents.js +215 -0
- package/src/audit/rubyAnalysisEngine/parsedGemfile.js +39 -0
- package/src/audit/rubyAnalysisEngine/readGemfileContents.js +18 -0
- package/src/audit/rubyAnalysisEngine/readGemfileLockContents.js +17 -0
- package/src/audit/rubyAnalysisEngine/sanitizer.js +8 -0
- package/src/commands/audit/auditConfig.ts +30 -0
- package/src/commands/audit/auditController.ts +31 -0
- package/src/commands/audit/help.ts +48 -0
- package/src/commands/audit/processAudit.ts +19 -0
- package/src/commands/auth/auth.js +1 -1
- package/src/commands/scan/processScan.js +20 -5
- package/src/common/HTTPClient.js +136 -14
- package/src/common/errorHandling.ts +56 -1
- package/src/common/findLatestCLIVersion.ts +27 -0
- package/src/constants/constants.js +1 -1
- package/src/constants/lambda.js +45 -4
- package/src/constants/locales.js +48 -20
- package/src/constants.js +168 -22
- package/src/index.ts +9 -2
- package/src/lambda/aws.ts +13 -12
- package/src/lambda/help.ts +4 -0
- package/src/lambda/lambda.ts +53 -34
- package/src/lambda/lambdaUtils.ts +111 -0
- package/src/lambda/logUtils.ts +19 -1
- package/src/lambda/scanDetailCompletion.ts +4 -4
- package/src/lambda/scanRequest.ts +13 -11
- package/src/lambda/utils.ts +149 -81
- package/src/scan/autoDetection.js +0 -29
- package/src/scan/fileUtils.js +1 -1
- package/src/scan/help.js +12 -45
- package/src/scan/populateProjectIdAndProjectName.js +4 -0
- package/src/scan/saveResults.js +15 -0
- package/src/scan/scan.js +95 -59
- package/src/scan/scanConfig.js +29 -0
- package/src/scan/scanController.js +13 -13
- package/src/scan/scanResults.js +21 -19
- package/src/utils/commonApi.js +2 -3
- package/src/utils/paramsUtil/commandlineParams.js +1 -26
- package/src/utils/paramsUtil/paramHandler.js +3 -7
- package/src/utils/parsedCLIOptions.js +11 -9
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const command_line_args_1 = __importDefault(require("command-line-args"));
|
|
7
|
+
const processAudit_1 = require("./commands/audit/processAudit");
|
|
7
8
|
const auth_1 = require("./commands/auth/auth");
|
|
8
9
|
const config_1 = require("./commands/config/config");
|
|
9
10
|
const processScan_1 = require("./commands/scan/processScan");
|
|
@@ -11,6 +12,7 @@ const constants_1 = __importDefault(require("./constants"));
|
|
|
11
12
|
const constants_2 = require("./constants/constants");
|
|
12
13
|
const lambda_1 = require("./lambda/lambda");
|
|
13
14
|
const getConfig_1 = require("./utils/getConfig");
|
|
15
|
+
const findLatestCLIVersion_1 = __importDefault(require("./common/findLatestCLIVersion"));
|
|
14
16
|
const { commandLineDefinitions: { mainUsageGuide, mainDefinition } } = constants_1.default;
|
|
15
17
|
const config = (0, getConfig_1.localConfig)(constants_2.APP_NAME, constants_2.APP_VERSION);
|
|
16
18
|
const getMainOption = () => {
|
|
@@ -32,6 +34,7 @@ const start = async () => {
|
|
|
32
34
|
console.log(constants_2.APP_VERSION);
|
|
33
35
|
return;
|
|
34
36
|
}
|
|
37
|
+
await (0, findLatestCLIVersion_1.default)();
|
|
35
38
|
if (command === 'config') {
|
|
36
39
|
return (0, config_1.processConfig)(argvMain, config);
|
|
37
40
|
}
|
|
@@ -42,7 +45,10 @@ const start = async () => {
|
|
|
42
45
|
return await (0, lambda_1.processLambda)(argvMain);
|
|
43
46
|
}
|
|
44
47
|
if (command === 'scan') {
|
|
45
|
-
return await (0, processScan_1.processScan)();
|
|
48
|
+
return await (0, processScan_1.processScan)(argvMain);
|
|
49
|
+
}
|
|
50
|
+
if (command === 'audit') {
|
|
51
|
+
return await (0, processAudit_1.processAudit)(argvMain);
|
|
46
52
|
}
|
|
47
53
|
if (command === 'help' ||
|
|
48
54
|
argvMain.includes('--help') ||
|
package/dist/lambda/aws.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.throwAwsError = exports.getLambdaPolicies = exports.getLayersLinks = exports.getLambdaFunctionConfiguration = exports.getLambdaClient = exports.getIAMClient = exports.getRolePolicyNames = exports.getAttachedPolicyNames = void 0;
|
|
7
|
+
const i18n_1 = __importDefault(require("i18n"));
|
|
4
8
|
const client_lambda_1 = require("@aws-sdk/client-lambda");
|
|
5
9
|
const client_iam_1 = require("@aws-sdk/client-iam");
|
|
6
10
|
const credential_provider_ini_1 = require("@aws-sdk/credential-provider-ini");
|
|
@@ -20,11 +24,9 @@ const getLambdaClient = (lambdaOptions) => {
|
|
|
20
24
|
return new client_lambda_1.Lambda(clientOptions);
|
|
21
25
|
}
|
|
22
26
|
catch (error) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
throw error;
|
|
27
|
+
throw new cliError_1.CliError(constants_1.ERRORS.AWS_ERROR, {
|
|
28
|
+
description: error.message
|
|
29
|
+
});
|
|
28
30
|
}
|
|
29
31
|
};
|
|
30
32
|
exports.getLambdaClient = getLambdaClient;
|
|
@@ -60,7 +62,9 @@ const getLayersLinks = async (client, functionConfiguration) => {
|
|
|
60
62
|
}
|
|
61
63
|
catch (e) {
|
|
62
64
|
if (e instanceof client_lambda_1.ResourceNotFoundException) {
|
|
63
|
-
e.message =
|
|
65
|
+
e.message = i18n_1.default.__('layerNotFound', {
|
|
66
|
+
layerArn: layerDict.Arn || 'unknown_arn'
|
|
67
|
+
});
|
|
64
68
|
throw e;
|
|
65
69
|
}
|
|
66
70
|
throw e;
|
|
@@ -135,9 +139,8 @@ const getRolePolicies = async (roleName, client) => {
|
|
|
135
139
|
const getAttachedPolicies = async (roleName, client) => {
|
|
136
140
|
const listAttachedPolicies = await exports.getAttachedPolicyNames(roleName, client);
|
|
137
141
|
const attachedPoliciesPromises = listAttachedPolicies.map(async (policyDict) => {
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
});
|
|
142
|
+
const { PolicyArn, PolicyName } = policyDict;
|
|
143
|
+
const getPolicyCommand = new client_iam_1.GetPolicyCommand({ PolicyArn });
|
|
141
144
|
const policy = await client.send(getPolicyCommand);
|
|
142
145
|
if (policy.Policy) {
|
|
143
146
|
const getPolicyVersionCommand = new client_iam_1.GetPolicyVersionCommand({
|
|
@@ -146,8 +149,8 @@ const getAttachedPolicies = async (roleName, client) => {
|
|
|
146
149
|
});
|
|
147
150
|
const policyVersion = await client.send(getPolicyVersionCommand);
|
|
148
151
|
const policyDoc = JSON.parse(decodeURIComponent(policyVersion?.PolicyVersion?.Document || '{}'));
|
|
149
|
-
policyDoc['PolicyName'] =
|
|
150
|
-
policyDoc['PolicyArn'] =
|
|
152
|
+
policyDoc['PolicyName'] = PolicyName;
|
|
153
|
+
policyDoc['PolicyArn'] = PolicyArn;
|
|
151
154
|
return policyDoc;
|
|
152
155
|
}
|
|
153
156
|
});
|
package/dist/lambda/help.js
CHANGED
|
@@ -26,6 +26,10 @@ const lambdaUsageGuide = (0, command_line_usage_1.default)([
|
|
|
26
26
|
name: i18n_1.default.__('lambdaFunctionNameOption'),
|
|
27
27
|
summary: i18n_1.default.__('lambdaFunctionNameSummery')
|
|
28
28
|
},
|
|
29
|
+
{
|
|
30
|
+
name: i18n_1.default.__('lambdaListFunctionsOption'),
|
|
31
|
+
summary: i18n_1.default.__('lambdaListFunctionsSummery')
|
|
32
|
+
},
|
|
29
33
|
{
|
|
30
34
|
name: i18n_1.default.__('lambdaEndpointOption'),
|
|
31
35
|
summary: '{italic ' +
|
package/dist/lambda/lambda.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.processLambda = void 0;
|
|
6
|
+
exports.getAvailableFunctions = exports.processLambda = void 0;
|
|
7
7
|
const command_line_args_1 = __importDefault(require("command-line-args"));
|
|
8
8
|
const perf_hooks_1 = require("perf_hooks");
|
|
9
9
|
const lodash_1 = require("lodash");
|
|
@@ -17,6 +17,7 @@ const scanDetailCompletion_1 = require("./scanDetailCompletion");
|
|
|
17
17
|
const scanRequest_1 = require("./scanRequest");
|
|
18
18
|
const scanResults_1 = require("./scanResults");
|
|
19
19
|
const utils_1 = require("./utils");
|
|
20
|
+
const lambdaUtils_1 = require("./lambdaUtils");
|
|
20
21
|
const failedStates = [
|
|
21
22
|
'UNSUPPORTED',
|
|
22
23
|
'EXCLUDED',
|
|
@@ -28,32 +29,45 @@ const printHelpMessage = () => {
|
|
|
28
29
|
(0, logUtils_1.log)(help_1.lambdaUsageGuide);
|
|
29
30
|
};
|
|
30
31
|
const getLambdaOptions = (argv) => {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
32
|
+
try {
|
|
33
|
+
const lambdaDefinitions = [
|
|
34
|
+
{ name: 'function-name', alias: 'f', type: String },
|
|
35
|
+
{ name: 'list-functions', alias: 'l', type: Boolean },
|
|
36
|
+
{ name: 'region', alias: 'r', type: String },
|
|
37
|
+
{ name: 'endpoint-url', alias: 'e', type: String },
|
|
38
|
+
{ name: 'profile', alias: 'p', type: String },
|
|
39
|
+
{ name: 'help', alias: 'h', type: Boolean },
|
|
40
|
+
{ name: 'verbose', alias: 'v', type: Boolean },
|
|
41
|
+
{ name: 'json-output', alias: 'j', type: Boolean }
|
|
42
|
+
];
|
|
43
|
+
const lambdaOptions = (0, command_line_args_1.default)(lambdaDefinitions, {
|
|
44
|
+
argv,
|
|
45
|
+
partial: true,
|
|
46
|
+
camelCase: true,
|
|
47
|
+
caseInsensitive: true
|
|
48
|
+
});
|
|
49
|
+
return lambdaOptions;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
throw new cliError_1.CliError(constants_1.ERRORS.VALIDATION_FAILED, {
|
|
53
|
+
description: error.message
|
|
54
|
+
});
|
|
55
|
+
}
|
|
47
56
|
};
|
|
48
57
|
const processLambda = async (argv) => {
|
|
49
|
-
const lambdaOptions = getLambdaOptions(argv);
|
|
50
|
-
const { help } = lambdaOptions;
|
|
51
|
-
if (help) {
|
|
52
|
-
return handleLambdaHelp();
|
|
53
|
-
}
|
|
54
58
|
try {
|
|
59
|
+
const lambdaOptions = getLambdaOptions(argv);
|
|
60
|
+
const { help } = lambdaOptions;
|
|
61
|
+
if (help) {
|
|
62
|
+
return handleLambdaHelp();
|
|
63
|
+
}
|
|
55
64
|
validateRequiredLambdaParams(lambdaOptions);
|
|
56
|
-
|
|
65
|
+
if (lambdaOptions.listFunctions) {
|
|
66
|
+
await getAvailableFunctions(lambdaOptions);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
await actualProcessLambda(lambdaOptions);
|
|
70
|
+
}
|
|
57
71
|
}
|
|
58
72
|
catch (error) {
|
|
59
73
|
if (error instanceof cliError_1.CliError) {
|
|
@@ -66,6 +80,11 @@ const processLambda = async (argv) => {
|
|
|
66
80
|
}
|
|
67
81
|
};
|
|
68
82
|
exports.processLambda = processLambda;
|
|
83
|
+
const getAvailableFunctions = async (lambdaOptions) => {
|
|
84
|
+
const lambdas = await (0, lambdaUtils_1.getAllLambdas)(lambdaOptions);
|
|
85
|
+
(0, lambdaUtils_1.printAvailableLambdas)(lambdas, { runtimes: ['python', 'java'] });
|
|
86
|
+
};
|
|
87
|
+
exports.getAvailableFunctions = getAvailableFunctions;
|
|
69
88
|
const actualProcessLambda = async (lambdaOptions) => {
|
|
70
89
|
const auth = (0, paramHandler_1.getAuth)();
|
|
71
90
|
const startTime = perf_hooks_1.performance.now();
|
|
@@ -100,16 +119,18 @@ const actualProcessLambda = async (lambdaOptions) => {
|
|
|
100
119
|
const scanDurationMs = endTime - startTime;
|
|
101
120
|
(0, logUtils_1.log)(`----- Scan completed ${(scanDurationMs / 1000).toFixed(2)}s -----`);
|
|
102
121
|
if (results?.length) {
|
|
103
|
-
(0, utils_1.
|
|
122
|
+
(0, utils_1.printResults)(results);
|
|
104
123
|
}
|
|
105
124
|
};
|
|
106
125
|
const validateRequiredLambdaParams = (options) => {
|
|
107
126
|
if (options._unknown?.length) {
|
|
108
127
|
throw new cliError_1.CliError(constants_1.ERRORS.VALIDATION_FAILED, {
|
|
109
|
-
description: i18n_1.default.__('notSupportedFlags',
|
|
128
|
+
description: i18n_1.default.__('notSupportedFlags', {
|
|
129
|
+
flags: options._unknown.join('\n')
|
|
130
|
+
})
|
|
110
131
|
});
|
|
111
132
|
}
|
|
112
|
-
if (!options?.functionName) {
|
|
133
|
+
if (!options?.functionName && !options?.listFunctions) {
|
|
113
134
|
throw new cliError_1.CliError(constants_1.ERRORS.VALIDATION_FAILED, {
|
|
114
135
|
errorCode: 'missingFunctionName'
|
|
115
136
|
});
|
|
@@ -120,7 +141,9 @@ const validateRequiredLambdaParams = (options) => {
|
|
|
120
141
|
.map(p => `--${(0, lodash_1.kebabCase)(p)}`);
|
|
121
142
|
if (flagsWithoutValues.length) {
|
|
122
143
|
throw new cliError_1.CliError(constants_1.ERRORS.VALIDATION_FAILED, {
|
|
123
|
-
description: i18n_1.default.__('missingFlagArguments',
|
|
144
|
+
description: i18n_1.default.__('missingFlagArguments', {
|
|
145
|
+
flags: flagsWithoutValues.join('\n')
|
|
146
|
+
})
|
|
124
147
|
});
|
|
125
148
|
}
|
|
126
149
|
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.printAvailableLambdas = exports.getAllLambdas = void 0;
|
|
7
|
+
const log_symbols_1 = __importDefault(require("log-symbols"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const i18n_1 = __importDefault(require("i18n"));
|
|
10
|
+
const client_lambda_1 = require("@aws-sdk/client-lambda");
|
|
11
|
+
const lodash_1 = require("lodash");
|
|
12
|
+
const aws_1 = require("./aws");
|
|
13
|
+
const oraWrapper_1 = __importDefault(require("../utils/oraWrapper"));
|
|
14
|
+
const logUtils_1 = require("./logUtils");
|
|
15
|
+
const printAvailableLambdas = (fucntions = [], options) => {
|
|
16
|
+
const { runtimes, filterText = '' } = options;
|
|
17
|
+
const searchValue = filterText?.trim().toLowerCase();
|
|
18
|
+
const filteredFunctions = fucntions
|
|
19
|
+
.filter(f => runtimes.some(r => f.Runtime?.includes(r)))
|
|
20
|
+
.filter(f => f.FunctionName?.toLowerCase().includes(searchValue));
|
|
21
|
+
(0, logUtils_1.log)(i18n_1.default.__('availableForScan', {
|
|
22
|
+
icon: log_symbols_1.default.success,
|
|
23
|
+
count: `${filteredFunctions.length}`
|
|
24
|
+
}));
|
|
25
|
+
const groupByRuntime = (0, lodash_1.groupBy)(filteredFunctions, 'Runtime');
|
|
26
|
+
Object.entries(groupByRuntime).forEach(([runtime, arr]) => {
|
|
27
|
+
const sorted = (0, lodash_1.sortBy)(arr, 'FunctionName');
|
|
28
|
+
const count = `${arr.filter(a => a.Runtime === runtime).length}`;
|
|
29
|
+
(0, logUtils_1.log)(chalk_1.default.gray(i18n_1.default.__('runtimeCount', { runtime, count })));
|
|
30
|
+
sorted.forEach(f => {
|
|
31
|
+
const size = f.CodeSize ? (0, logUtils_1.getReadableFileSize)(f.CodeSize) : '';
|
|
32
|
+
(0, logUtils_1.log)(`${f.FunctionName} ${chalk_1.default.gray(`(${size})`)}`);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
exports.printAvailableLambdas = printAvailableLambdas;
|
|
37
|
+
const getAllLambdas = async (lambdaOptions) => {
|
|
38
|
+
const functions = [];
|
|
39
|
+
const spinner = oraWrapper_1.default.returnOra(i18n_1.default.__('loadingFunctionList'));
|
|
40
|
+
try {
|
|
41
|
+
const client = (0, aws_1.getLambdaClient)(lambdaOptions);
|
|
42
|
+
const command = new client_lambda_1.ListFunctionsCommand({});
|
|
43
|
+
oraWrapper_1.default.startSpinner(spinner);
|
|
44
|
+
const data = await client.send(command);
|
|
45
|
+
const { Functions } = data;
|
|
46
|
+
let { NextMarker } = data;
|
|
47
|
+
if (!Functions?.length) {
|
|
48
|
+
oraWrapper_1.default.failSpinner(spinner, i18n_1.default.__('noFunctionsFound'));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
functions.push(...Functions);
|
|
52
|
+
spinner.text = i18n_1.default.__('functionsFound', { count: `${functions.length}` });
|
|
53
|
+
while (NextMarker) {
|
|
54
|
+
command.input.Marker = NextMarker;
|
|
55
|
+
const chank = await client.send(command);
|
|
56
|
+
if (chank.Functions?.length) {
|
|
57
|
+
functions.push(...chank.Functions);
|
|
58
|
+
spinner.text = i18n_1.default.__('functionsFound', {
|
|
59
|
+
count: `${functions.length}`
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
NextMarker = chank.NextMarker;
|
|
63
|
+
}
|
|
64
|
+
oraWrapper_1.default.succeedSpinner(spinner, i18n_1.default.__('functionsFound', { count: `${functions.length}` }));
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
oraWrapper_1.default.failSpinner(spinner, i18n_1.default.__('failedToLoadFunctions'));
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
return functions;
|
|
71
|
+
};
|
|
72
|
+
exports.getAllLambdas = getAllLambdas;
|
package/dist/lambda/logUtils.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.prettyPrintJson = exports.log = void 0;
|
|
6
|
+
exports.getReadableFileSize = exports.prettyPrintJson = exports.log = void 0;
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
8
|
const util_1 = __importDefault(require("util"));
|
|
9
9
|
const log = (message, styles) => {
|
|
@@ -34,3 +34,13 @@ const prettyPrintJson = (obj, depth = null) => {
|
|
|
34
34
|
console.log(util_1.default.inspect(objToPrint, { colors: true, depth }));
|
|
35
35
|
};
|
|
36
36
|
exports.prettyPrintJson = prettyPrintJson;
|
|
37
|
+
const getReadableFileSize = (fileSizeInBytes) => {
|
|
38
|
+
let i = -1;
|
|
39
|
+
const byteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB'];
|
|
40
|
+
do {
|
|
41
|
+
fileSizeInBytes = fileSizeInBytes / 1024;
|
|
42
|
+
i++;
|
|
43
|
+
} while (fileSizeInBytes > 1024);
|
|
44
|
+
return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
|
|
45
|
+
};
|
|
46
|
+
exports.getReadableFileSize = getReadableFileSize;
|
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getScanResources = exports.pollScanUntilCompletion = void 0;
|
|
7
|
+
const i18n_1 = __importDefault(require("i18n"));
|
|
7
8
|
const requestUtils_1 = require("../utils/requestUtils");
|
|
8
9
|
const commonApi_1 = require("../utils/commonApi");
|
|
9
10
|
const oraWrapper_1 = __importDefault(require("../utils/oraWrapper"));
|
|
@@ -23,9 +24,8 @@ exports.getScanResources = getScanResources;
|
|
|
23
24
|
const pollScanUntilCompletion = async (config, timeoutInMinutes, params, scanId) => {
|
|
24
25
|
const client = (0, commonApi_1.getHttpClient)(config);
|
|
25
26
|
const activeStatuses = ['PENDING', 'SCANNING', 'QUEUED'];
|
|
26
|
-
const startedText = 'Scan started';
|
|
27
27
|
const maxEndTime = new Date().getTime() + timeoutInMinutes * MS_IN_MINUTE;
|
|
28
|
-
const startScanSpinner = oraWrapper_1.default.returnOra(
|
|
28
|
+
const startScanSpinner = oraWrapper_1.default.returnOra(i18n_1.default.__('scanStarted'));
|
|
29
29
|
oraWrapper_1.default.startSpinner(startScanSpinner);
|
|
30
30
|
await (0, requestUtils_1.sleep)(5000);
|
|
31
31
|
let complete = false;
|
|
@@ -42,11 +42,11 @@ const pollScanUntilCompletion = async (config, timeoutInMinutes, params, scanId)
|
|
|
42
42
|
await (0, requestUtils_1.sleep)(2 * 1000);
|
|
43
43
|
}
|
|
44
44
|
catch (error) {
|
|
45
|
-
oraWrapper_1.default.failSpinner(startScanSpinner, '
|
|
45
|
+
oraWrapper_1.default.failSpinner(startScanSpinner, i18n_1.default.__('scanFailed'));
|
|
46
46
|
throw error;
|
|
47
47
|
}
|
|
48
48
|
if (Date.now() >= maxEndTime) {
|
|
49
|
-
oraWrapper_1.default.failSpinner(startScanSpinner, '
|
|
49
|
+
oraWrapper_1.default.failSpinner(startScanSpinner, i18n_1.default.__('scanTimedOut'));
|
|
50
50
|
throw new cliError_1.CliError(constants_1.ERRORS.FAILED_TO_GET_SCAN, {
|
|
51
51
|
errorCode: 'waitingTimedOut'
|
|
52
52
|
});
|
|
@@ -17,13 +17,13 @@ const constants_1 = require("./constants");
|
|
|
17
17
|
const sendScanPostRequest = async (config, params, functionsEvent, showProgress = false) => {
|
|
18
18
|
const client = (0, commonApi_1.getHttpClient)(config);
|
|
19
19
|
if (showProgress) {
|
|
20
|
-
(0, logUtils_1.log)(
|
|
20
|
+
(0, logUtils_1.log)(i18n_1.default.__('sendingScanRequest', { icon: log_symbols_1.default.success }));
|
|
21
21
|
}
|
|
22
22
|
const res = await client.postFunctionScan(config, params, functionsEvent);
|
|
23
23
|
const { statusCode, body } = res;
|
|
24
24
|
if (statusCode === 201) {
|
|
25
25
|
if (showProgress) {
|
|
26
|
-
(0, logUtils_1.log)(
|
|
26
|
+
(0, logUtils_1.log)(i18n_1.default.__('scanRequestedSuccessfully', { icon: log_symbols_1.default.success }));
|
|
27
27
|
}
|
|
28
28
|
return body?.data?.scanId;
|
|
29
29
|
}
|
|
@@ -32,7 +32,10 @@ const sendScanPostRequest = async (config, params, functionsEvent, showProgress
|
|
|
32
32
|
let description = '';
|
|
33
33
|
switch (errorCode) {
|
|
34
34
|
case 'not_supported_runtime':
|
|
35
|
-
description = i18n_1.default.__(errorCode,
|
|
35
|
+
description = i18n_1.default.__(errorCode, {
|
|
36
|
+
runtime: data?.runtime,
|
|
37
|
+
supportedRuntimes: data?.supportedRuntimes.sort().join(' | ')
|
|
38
|
+
});
|
|
36
39
|
errorCode = false;
|
|
37
40
|
break;
|
|
38
41
|
}
|
|
@@ -59,7 +62,10 @@ const requestScanFunctionPost = async (config, lambdaOptions) => {
|
|
|
59
62
|
const { verbose, jsonOutput, functionName } = lambdaOptions;
|
|
60
63
|
const lambdaClient = (0, aws_1.getLambdaClient)(lambdaOptions);
|
|
61
64
|
if (!jsonOutput) {
|
|
62
|
-
(0, logUtils_1.log)(
|
|
65
|
+
(0, logUtils_1.log)(i18n_1.default.__('fetchingConfiguration', {
|
|
66
|
+
icon: log_symbols_1.default.success,
|
|
67
|
+
functionName: chalk_1.default.bold(functionName)
|
|
68
|
+
}));
|
|
63
69
|
}
|
|
64
70
|
const lambdaConfig = await (0, aws_1.getLambdaFunctionConfiguration)(lambdaClient, lambdaOptions);
|
|
65
71
|
if (!lambdaConfig?.Configuration) {
|
|
@@ -84,7 +90,7 @@ const requestScanFunctionPost = async (config, lambdaOptions) => {
|
|
|
84
90
|
accountId: parsedARN.accountId
|
|
85
91
|
};
|
|
86
92
|
if (verbose) {
|
|
87
|
-
(0, logUtils_1.log)(
|
|
93
|
+
(0, logUtils_1.log)(i18n_1.default.__('fetchedConfiguration', { icon: log_symbols_1.default.success }));
|
|
88
94
|
(0, logUtils_1.prettyPrintJson)(functionEvent);
|
|
89
95
|
}
|
|
90
96
|
const scanId = await sendScanPostRequest(config, params, functionEvent, !jsonOutput);
|
package/dist/lambda/utils.js
CHANGED
|
@@ -3,41 +3,128 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.exportedForTesting = exports.
|
|
6
|
+
exports.exportedForTesting = exports.printResults = exports.toLowerKeys = void 0;
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
8
|
const lodash_1 = require("lodash");
|
|
9
|
+
const i18n_1 = __importDefault(require("i18n"));
|
|
9
10
|
const logUtils_1 = require("./logUtils");
|
|
11
|
+
i18n_1.default.setLocale('en');
|
|
12
|
+
class PrintVulnerability {
|
|
13
|
+
constructor(index, vulnerability, group) {
|
|
14
|
+
const { severityText, title, description, remediation, categoryText } = vulnerability;
|
|
15
|
+
this.group = group;
|
|
16
|
+
this.vulnerability = vulnerability;
|
|
17
|
+
this.index = index;
|
|
18
|
+
this.title = title;
|
|
19
|
+
this.severity = (0, lodash_1.capitalize)(severityText);
|
|
20
|
+
this.description = underlineLinks(description);
|
|
21
|
+
this.remediation = remediation?.description;
|
|
22
|
+
this.recommendation = '';
|
|
23
|
+
this.whatHappened = '';
|
|
24
|
+
if (categoryText === 'PERMISSIONS') {
|
|
25
|
+
this.formatPermissions();
|
|
26
|
+
}
|
|
27
|
+
else if (categoryText === 'DEPENDENCIES') {
|
|
28
|
+
this.formatDependencies();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
formatPermissions() {
|
|
32
|
+
const { leastPrivilege, comment } = this.vulnerability.evidence;
|
|
33
|
+
const violatingPolicies = leastPrivilege?.violatingPolicies || [];
|
|
34
|
+
const filteredPolicies = violatingPolicies
|
|
35
|
+
.filter((vp) => vp?.suggestedPolicy?.suggestedPolicyCode?.length)
|
|
36
|
+
.map((vp) => vp?.suggestedPolicy);
|
|
37
|
+
const shouldNumerate = filteredPolicies.length > 1;
|
|
38
|
+
filteredPolicies.forEach((policies, i) => {
|
|
39
|
+
const { suggestedPolicyCode, description } = policies;
|
|
40
|
+
suggestedPolicyCode.forEach((policy) => {
|
|
41
|
+
const { snippet, title } = policy;
|
|
42
|
+
this.recommendation += shouldNumerate
|
|
43
|
+
? ` ${i + 1}. ${description}\n`
|
|
44
|
+
: `${description}\n`;
|
|
45
|
+
if (title !== 'DELETE POLICY') {
|
|
46
|
+
this.recommendation += `${snippet}\n`;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
if (comment?.length) {
|
|
51
|
+
const splitComment = (comment) => {
|
|
52
|
+
const [policy, description] = comment.split(':').map(c => c.trim());
|
|
53
|
+
return { policy, description };
|
|
54
|
+
};
|
|
55
|
+
const groupByPolicy = (0, lodash_1.groupBy)(comment, c => splitComment(c).policy);
|
|
56
|
+
Object.entries(groupByPolicy).forEach(([policy, commentArr]) => {
|
|
57
|
+
const comments = commentArr
|
|
58
|
+
.map(splitComment)
|
|
59
|
+
.map(({ description }) => ` - ${description}`)
|
|
60
|
+
.join('\n');
|
|
61
|
+
this.whatHappened += i18n_1.default.__('whatHappenedItem', { policy, comments });
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
formatDependencies() {
|
|
66
|
+
if (!this.group?.length) {
|
|
67
|
+
this.recommendation = this.vulnerability?.remediation?.description;
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const maxSeverity = (0, lodash_1.minBy)(this.group, 'severity');
|
|
71
|
+
this.title = i18n_1.default.__('vulnerableDependency');
|
|
72
|
+
this.severity = (0, lodash_1.capitalize)(maxSeverity.severityText);
|
|
73
|
+
this.recommendation = maxSeverity.remediation?.description;
|
|
74
|
+
const library = groupByDependency({ title: this.vulnerability.title });
|
|
75
|
+
const [packageName, version] = library.split(':');
|
|
76
|
+
const allCves = this.group.map(groupByCVE);
|
|
77
|
+
this.description = i18n_1.default.__mf('vulnerableDependencyDescriptions', {
|
|
78
|
+
NUM: this.group.length,
|
|
79
|
+
packageName,
|
|
80
|
+
version,
|
|
81
|
+
cves: allCves.join(' | ')
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
print() {
|
|
85
|
+
(0, logUtils_1.log)(`${this.index}.`);
|
|
86
|
+
(0, logUtils_1.log)(`${chalk_1.default.bold(this.severity)} | ${chalk_1.default.bold(this.title)} ${this.description}`);
|
|
87
|
+
if (this.whatHappened) {
|
|
88
|
+
(0, logUtils_1.log)(`\n${chalk_1.default.bold(i18n_1.default.__('whatHappenedTitle'))}\n${this.whatHappened}`);
|
|
89
|
+
}
|
|
90
|
+
if (this.recommendation) {
|
|
91
|
+
(0, logUtils_1.log)(`${chalk_1.default.bold(i18n_1.default.__('recommendation'))}\n${this.recommendation}`);
|
|
92
|
+
}
|
|
93
|
+
(0, logUtils_1.log)('');
|
|
94
|
+
}
|
|
95
|
+
}
|
|
10
96
|
const groupByCVE = ({ title }) => title.substring(0, title.indexOf('[') - 1);
|
|
11
97
|
const groupByDependency = ({ title }) => title.substring(title.indexOf('[') + 1, title.indexOf(']'));
|
|
12
|
-
const
|
|
13
|
-
(0, logUtils_1.log)('');
|
|
98
|
+
const printResults = (results) => {
|
|
14
99
|
const vulnerabs = results.filter(r => r.category === 1 || r.category === 4);
|
|
15
100
|
const sortBySeverity = (0, lodash_1.sortBy)(vulnerabs, ['severity', 'title']);
|
|
16
101
|
const notDependencies = sortBySeverity.filter(r => r.category !== 1);
|
|
17
102
|
const dependencies = sortBySeverity.filter(r => r.category === 1);
|
|
18
103
|
const dependenciesByLibrary = (0, lodash_1.groupBy)(dependencies, groupByDependency);
|
|
19
|
-
|
|
20
|
-
notDependencies.forEach(
|
|
104
|
+
(0, logUtils_1.log)('');
|
|
105
|
+
notDependencies.forEach((vulnerability, index) => {
|
|
106
|
+
const printVulnerab = new PrintVulnerability(index + 1, vulnerability);
|
|
107
|
+
printVulnerab.print();
|
|
108
|
+
});
|
|
21
109
|
const prevIndex = notDependencies.length + 1;
|
|
22
|
-
Object.entries(dependenciesByLibrary).forEach(([
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
(0, logUtils_1.log)(prevIndex + i);
|
|
26
|
-
(0, logUtils_1.log)(`${chalk_1.default.bold((0, lodash_1.capitalize)(maxSeverity.severityText))} | ${chalk_1.default.bold('Vulnerable dependency')} ${library} has ${group.length} known CVEs`);
|
|
27
|
-
(0, logUtils_1.log)(allCves.join(', '));
|
|
28
|
-
if (maxSeverity.remediation?.description) {
|
|
29
|
-
(0, logUtils_1.log)(`${chalk_1.default.bold('Recommendation:')} ${maxSeverity.remediation.description}`);
|
|
30
|
-
}
|
|
31
|
-
(0, logUtils_1.log)('');
|
|
110
|
+
Object.entries(dependenciesByLibrary).forEach(([, group], i) => {
|
|
111
|
+
const printVulnerab = new PrintVulnerability(prevIndex + i, group[0], group);
|
|
112
|
+
printVulnerab.print();
|
|
32
113
|
});
|
|
114
|
+
const dependenciesCount = Object.keys(dependenciesByLibrary).length;
|
|
33
115
|
const resultCount = notDependencies.length + dependenciesCount;
|
|
116
|
+
(0, logUtils_1.log)(i18n_1.default.__n('foundVulnerabilities', resultCount), { bold: true });
|
|
117
|
+
const counters = getNotDependenciesCounters(notDependencies);
|
|
118
|
+
if (dependenciesCount) {
|
|
119
|
+
counters.push(i18n_1.default.__n('dependenciesCount', dependenciesCount));
|
|
120
|
+
}
|
|
121
|
+
(0, logUtils_1.log)(counters.join(' | '), { bold: true });
|
|
122
|
+
};
|
|
123
|
+
exports.printResults = printResults;
|
|
124
|
+
const getNotDependenciesCounters = (notDependencies) => {
|
|
34
125
|
const groupByType = (0, lodash_1.groupBy)(notDependencies, ['categoryText']);
|
|
35
|
-
|
|
36
|
-
(0, logUtils_1.log)(`Found ${resultCount} vulnerabilities`, { bold: true });
|
|
37
|
-
summary.push(`${dependenciesCount} Dependencies`);
|
|
38
|
-
(0, logUtils_1.log)(chalk_1.default.bold(summary.join(' | ')));
|
|
126
|
+
return Object.values(groupByType).map(group => `${group.length} ${(0, lodash_1.capitalize)(group[0].categoryText)}`);
|
|
39
127
|
};
|
|
40
|
-
exports.prettyPrintResults = prettyPrintResults;
|
|
41
128
|
const underlineLinks = (text) => {
|
|
42
129
|
if (!text) {
|
|
43
130
|
return text;
|
|
@@ -45,35 +132,6 @@ const underlineLinks = (text) => {
|
|
|
45
132
|
const urlRegex = /(https?:\/\/[^\s]+)/g;
|
|
46
133
|
return text.replace(urlRegex, chalk_1.default.underline('$1'));
|
|
47
134
|
};
|
|
48
|
-
const printVulnerability = (vulnerability, index) => {
|
|
49
|
-
(0, logUtils_1.log)(index + 1);
|
|
50
|
-
const descriptionWithLinks = underlineLinks(vulnerability.description);
|
|
51
|
-
(0, logUtils_1.log)(`${chalk_1.default.bold((0, lodash_1.capitalize)(vulnerability.severityText))} | ${chalk_1.default.bold(vulnerability.title)} ${descriptionWithLinks}`);
|
|
52
|
-
const category = vulnerability?.categoryText;
|
|
53
|
-
switch (category) {
|
|
54
|
-
case 'PERMISSIONS':
|
|
55
|
-
printLeastPrivilegeRemediation(vulnerability);
|
|
56
|
-
break;
|
|
57
|
-
default:
|
|
58
|
-
printRemediation(vulnerability);
|
|
59
|
-
}
|
|
60
|
-
(0, logUtils_1.log)('');
|
|
61
|
-
};
|
|
62
|
-
const printLeastPrivilegeRemediation = (vulnerability) => {
|
|
63
|
-
(0, logUtils_1.log)(`${chalk_1.default.bold('Recommendation:')} Replace the existing policies with the following`);
|
|
64
|
-
const violatingPolicies = vulnerability?.evidence?.leastPrivilege?.violatingPolicies || [];
|
|
65
|
-
violatingPolicies
|
|
66
|
-
.filter((vp) => vp?.suggestedPolicy?.suggestedPolicyCode?.length)
|
|
67
|
-
.map((vp) => vp?.suggestedPolicy?.suggestedPolicyCode)
|
|
68
|
-
.forEach((policies) => {
|
|
69
|
-
policies.forEach((policy) => {
|
|
70
|
-
console.log(policy.snippet);
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
};
|
|
74
|
-
const printRemediation = (vulnerability) => {
|
|
75
|
-
(0, logUtils_1.log)(`Remediation - ${vulnerability?.remediation?.description || 'Unknown'}`);
|
|
76
|
-
};
|
|
77
135
|
function toLowerKeys(obj) {
|
|
78
136
|
return Object.keys(obj).reduce((accumulator, key) => {
|
|
79
137
|
const new_key = `${key[0].toLowerCase()}${key.slice(1)}`;
|
|
@@ -83,8 +141,7 @@ function toLowerKeys(obj) {
|
|
|
83
141
|
}
|
|
84
142
|
exports.toLowerKeys = toLowerKeys;
|
|
85
143
|
exports.exportedForTesting = {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
underlineLinks
|
|
144
|
+
underlineLinks,
|
|
145
|
+
printResults,
|
|
146
|
+
PrintVulnerability
|
|
90
147
|
};
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const i18n = require('i18n');
|
|
3
|
-
const { zipValidator } = require('./scan');
|
|
4
3
|
const fileFinder = require('./fileUtils');
|
|
5
|
-
const { supportedLanguages } = require('../constants/constants');
|
|
6
4
|
const autoDetectFileAndLanguage = async (configToUse) => {
|
|
7
5
|
const entries = await fileFinder.findFile();
|
|
8
6
|
if (entries.length === 1) {
|
|
@@ -15,8 +13,6 @@ const autoDetectFileAndLanguage = async (configToUse) => {
|
|
|
15
13
|
if (configToUse.name === undefined) {
|
|
16
14
|
configToUse.name = entries[0];
|
|
17
15
|
}
|
|
18
|
-
zipValidator(configToUse);
|
|
19
|
-
assignLanguage(entries, configToUse);
|
|
20
16
|
}
|
|
21
17
|
else {
|
|
22
18
|
errorOnFileDetection(entries);
|
|
@@ -42,35 +38,7 @@ const errorOnFileDetection = entries => {
|
|
|
42
38
|
}
|
|
43
39
|
process.exit(1);
|
|
44
40
|
};
|
|
45
|
-
const assignLanguage = (entries, configToUse) => {
|
|
46
|
-
let split = entries[0].split('.');
|
|
47
|
-
const fileType = split[split.length - 1];
|
|
48
|
-
if (fileType === 'war' || fileType === 'jar') {
|
|
49
|
-
console.log('Language is Java');
|
|
50
|
-
configToUse.language = 'JAVA';
|
|
51
|
-
}
|
|
52
|
-
else if (fileType === 'dll') {
|
|
53
|
-
console.log('Language is Dotnet');
|
|
54
|
-
configToUse.language = 'DOTNET';
|
|
55
|
-
}
|
|
56
|
-
else if (fileType === 'js') {
|
|
57
|
-
console.log('Language is Javascript');
|
|
58
|
-
configToUse.language = supportedLanguages.JAVASCRIPT;
|
|
59
|
-
}
|
|
60
|
-
else if (fileType === 'zip') {
|
|
61
|
-
if (configToUse.language !== supportedLanguages.JAVASCRIPT) {
|
|
62
|
-
console.log(i18n.__('zipErrorScan'));
|
|
63
|
-
process.exit(1);
|
|
64
|
-
}
|
|
65
|
-
console.log('Language is Javascript within zip file');
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
console.log(i18n.__('unknownFileErrorScan'));
|
|
69
|
-
process.exit(1);
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
41
|
module.exports = {
|
|
73
42
|
autoDetectFileAndLanguage,
|
|
74
|
-
assignLanguage,
|
|
75
43
|
errorOnFileDetection
|
|
76
44
|
};
|