@soos-io/soos-sast
Advanced tools
Comparing version 0.1.0 to 0.1.3
187
bin/index.js
@@ -7,9 +7,7 @@ #!/usr/bin/env node | ||
const utilities_1 = require("@soos-io/api-client/dist/utilities"); | ||
const argparse_1 = require("argparse"); | ||
const FileSystem = tslib_1.__importStar(require("fs")); | ||
const Path = tslib_1.__importStar(require("path")); | ||
const form_data_1 = tslib_1.__importDefault(require("form-data")); | ||
const constants_1 = require("./utils/constants"); | ||
const process_1 = require("process"); | ||
const SOOSAnalysisApiClient_1 = tslib_1.__importDefault(require("@soos-io/api-client/dist/api/SOOSAnalysisApiClient")); | ||
const package_json_1 = require("../package.json"); | ||
const AnalysisService_1 = tslib_1.__importDefault(require("@soos-io/api-client/dist/services/AnalysisService")); | ||
const AnalysisArgumentParser_1 = tslib_1.__importDefault(require("@soos-io/api-client/dist/services/AnalysisArgumentParser")); | ||
const constants_1 = require("./constants"); | ||
class SOOSSASTAnalysis { | ||
@@ -20,104 +18,57 @@ constructor(args) { | ||
static parseArgs() { | ||
const parser = new argparse_1.ArgumentParser({ description: "SOOS SAST" }); | ||
parser.add_argument("--apiKey", { | ||
help: "SOOS API Key - get yours from https://app.soos.io/integrate/sast", | ||
default: (0, utilities_1.getEnvVariable)(constants_1.CONSTANTS.SOOS.API_KEY_ENV_VAR), | ||
const analysisArgumentParser = AnalysisArgumentParser_1.default.create(api_client_1.ScanType.SAST); | ||
analysisArgumentParser.addBaseScanArguments(api_client_1.IntegrationName.SoosSast, api_client_1.IntegrationType.Script, package_json_1.version); | ||
analysisArgumentParser.argumentParser.add_argument("--directoriesToExclude", { | ||
help: "Listing of directories or patterns to exclude from the search for manifest files. eg: **bin/start/**, **/start/**", | ||
type: (value) => { | ||
return value.split(",").map((pattern) => pattern.trim()); | ||
}, | ||
required: false, | ||
}); | ||
parser.add_argument("--apiURL", { | ||
help: "SOOS API URL - Intended for internal use only, do not modify.", | ||
default: "https://api.soos.io/api/", | ||
required: false, | ||
}); | ||
parser.add_argument("--appVersion", { | ||
help: "App Version - Intended for internal use only.", | ||
required: false, | ||
}); | ||
parser.add_argument("--branchName", { | ||
help: "The name of the branch from the SCM System.", | ||
default: null, | ||
required: false, | ||
}); | ||
parser.add_argument("--branchURI", { | ||
help: "The URI to the branch from the SCM System.", | ||
default: null, | ||
required: false, | ||
}); | ||
parser.add_argument("--buildURI", { | ||
help: "URI to CI build info.", | ||
default: null, | ||
required: false, | ||
}); | ||
parser.add_argument("--buildVersion", { | ||
help: "Version of application build artifacts.", | ||
default: null, | ||
required: false, | ||
}); | ||
parser.add_argument("--clientId", { | ||
help: "SOOS Client ID - get yours from https://app.soos.io/integrate/sast", | ||
default: (0, utilities_1.getEnvVariable)(constants_1.CONSTANTS.SOOS.CLIENT_ID_ENV_VAR), | ||
required: false, | ||
}); | ||
parser.add_argument("--commitHash", { | ||
help: "The commit hash value from the SCM System.", | ||
default: null, | ||
required: false, | ||
}); | ||
parser.add_argument("--integrationName", { | ||
help: "Integration Name - Intended for internal use only.", | ||
required: false, | ||
}); | ||
parser.add_argument("--integrationType", { | ||
help: "Integration Type - Intended for internal use only.", | ||
required: false, | ||
default: constants_1.CONSTANTS.SOOS.DEFAULT_INTEGRATION_TYPE, | ||
}); | ||
parser.add_argument("--logLevel", { | ||
help: "Minimum level to show logs: PASS, IGNORE, INFO, WARN or FAIL.", | ||
default: api_client_1.LogLevel.INFO, | ||
required: false, | ||
analysisArgumentParser.argumentParser.add_argument("--filesToExclude", { | ||
help: "Listing of files or patterns patterns to exclude from the search for manifest files. eg: **/sa**.sarif.json/, **/sast.sarif.json", | ||
type: (value) => { | ||
return (0, utilities_1.ensureEnumValue)(api_client_1.LogLevel, value); | ||
return value.split(",").map((pattern) => pattern.trim()); | ||
}, | ||
}); | ||
parser.add_argument("--operatingEnvironment", { | ||
help: "Set Operating environment for information purposes only.", | ||
default: null, | ||
required: false, | ||
}); | ||
parser.add_argument("--projectName", { | ||
help: "Project Name - this is what will be displayed in the SOOS app.", | ||
required: true, | ||
}); | ||
parser.add_argument("--scriptVersion", { | ||
help: "Script Version - Intended for internal use only.", | ||
analysisArgumentParser.argumentParser.add_argument("--sourceCodePath", { | ||
help: "The path to start searching for SAST files.", | ||
required: false, | ||
default: process.cwd(), | ||
}); | ||
parser.add_argument("--verbose", { | ||
help: "Enable verbose logging.", | ||
action: "store_true", | ||
default: false, | ||
required: false, | ||
}); | ||
parser.add_argument("sastPath", { | ||
help: "The SAST File to scan (*.sarif.json), it could be the location of the file or the file itself. When location is specified only the first file found will be scanned.", | ||
}); | ||
api_client_1.soosLogger.info("Parsing arguments"); | ||
return parser.parse_args(); | ||
return analysisArgumentParser.parseArguments(); | ||
} | ||
async runAnalysis() { | ||
const scanType = api_client_1.ScanType.SAST; | ||
const soosAnalysisService = AnalysisService_1.default.create(this.args.apiKey, this.args.apiURL); | ||
let projectHash; | ||
let branchHash; | ||
let analysisId; | ||
const filePath = await this.findSASTFilePath(); | ||
const soosAnalysisApiClient = new SOOSAnalysisApiClient_1.default(this.args.apiKey, this.args.apiURL); | ||
let scanStatusUrl; | ||
try { | ||
const { filePaths, hasMoreThanMaximumFiles } = await soosAnalysisService.findAnalysisFiles(scanType, this.args.sourceCodePath, constants_1.SOOS_SAST_CONSTANTS.FilePattern, this.args.filesToExclude, this.args.directoriesToExclude, constants_1.SOOS_SAST_CONSTANTS.MaxFiles); | ||
if (filePaths.length === 0) { | ||
throw new Error("No SAST files found."); | ||
} | ||
api_client_1.soosLogger.info("Starting SOOS SAST Analysis"); | ||
api_client_1.soosLogger.info(`Creating scan for project '${this.args.projectName}'...`); | ||
api_client_1.soosLogger.info(`Branch Name: ${this.args.branchName}`); | ||
const result = await soosAnalysisApiClient.createScan({ | ||
const result = await soosAnalysisService.setupScan({ | ||
clientId: this.args.clientId, | ||
projectName: this.args.projectName, | ||
commitHash: this.args.commitHash, | ||
branch: this.args.branchName, | ||
contributingDeveloperAudit: !this.args.contributingDeveloperId || | ||
!this.args.contributingDeveloperSource || | ||
!this.args.contributingDeveloperSourceName | ||
? [] | ||
: [ | ||
{ | ||
contributingDeveloperId: this.args.contributingDeveloperId, | ||
source: this.args.contributingDeveloperSource, | ||
sourceName: this.args.contributingDeveloperSourceName, | ||
}, | ||
], | ||
branchName: this.args.branchName, | ||
buildVersion: this.args.buildVersion, | ||
@@ -130,7 +81,6 @@ buildUri: this.args.buildUri, | ||
appVersion: this.args.appVersion, | ||
scriptVersion: null, | ||
contributingDeveloperAudit: undefined, | ||
scanType: api_client_1.ScanType.SAST, | ||
toolName: null, | ||
toolVersion: null, | ||
scanType, | ||
scriptVersion: this.args.scriptVersion, | ||
toolName: undefined, | ||
toolVersion: undefined, | ||
}); | ||
@@ -140,2 +90,3 @@ projectHash = result.projectHash; | ||
analysisId = result.analysisId; | ||
scanStatusUrl = result.scanStatusUrl; | ||
api_client_1.soosLogger.info(`Project Hash: ${projectHash}`); | ||
@@ -146,26 +97,27 @@ api_client_1.soosLogger.info(`Branch Hash: ${branchHash}`); | ||
api_client_1.soosLogger.logLineSeparator(); | ||
api_client_1.soosLogger.info("Uploading SAST File"); | ||
const formData = await this.getSastAsFormData(filePath); | ||
await soosAnalysisApiClient.uploadScanToolResult({ | ||
api_client_1.soosLogger.info("Uploading SAST Files"); | ||
const formData = await soosAnalysisService.getAnalysisFilesAsFormData(filePaths, this.args.sourceCodePath); | ||
await soosAnalysisService.analysisApiClient.uploadScanToolResult({ | ||
clientId: this.args.clientId, | ||
projectHash, | ||
branchHash, | ||
scanType: api_client_1.ScanType.SAST, | ||
scanType, | ||
scanId: analysisId, | ||
resultFile: formData, | ||
hasMoreThanMaximumFiles, | ||
}); | ||
api_client_1.soosLogger.info(`Scan result uploaded successfully`); | ||
api_client_1.soosLogger.logLineSeparator(); | ||
api_client_1.soosLogger.info(`Analysis scan started successfully, to see the results visit: ${result.scanUrl}`); | ||
api_client_1.soosLogger.info(`Scan results uploaded successfully. To see the results visit: ${result.scanUrl}`); | ||
} | ||
catch (error) { | ||
if (projectHash && branchHash && analysisId) | ||
await soosAnalysisApiClient.updateScanStatus({ | ||
await soosAnalysisService.updateScanStatus({ | ||
analysisId, | ||
clientId: this.args.clientId, | ||
projectHash, | ||
branchHash, | ||
scanType: api_client_1.ScanType.SAST, | ||
scanId: analysisId, | ||
scanType, | ||
status: api_client_1.ScanStatus.Error, | ||
message: `Error while performing scan.`, | ||
scanStatusUrl, | ||
}); | ||
@@ -176,31 +128,2 @@ api_client_1.soosLogger.error(error); | ||
} | ||
async getSastAsFormData(filePath) { | ||
try { | ||
const fileReadStream = FileSystem.createReadStream(filePath, { | ||
encoding: api_client_1.SOOS_CONSTANTS.FileUploads.Encoding, | ||
}); | ||
const formData = new form_data_1.default(); | ||
formData.append("file", fileReadStream); | ||
return formData; | ||
} | ||
catch (error) { | ||
api_client_1.soosLogger.error(`Error on getSastAsFormData: ${error}`); | ||
throw error; | ||
} | ||
} | ||
async findSASTFilePath() { | ||
const sastPathStat = await FileSystem.statSync(this.args.sastPath); | ||
if (sastPathStat.isDirectory()) { | ||
const files = await FileSystem.promises.readdir(this.args.sastPath); | ||
const sastFile = files.find((file) => constants_1.CONSTANTS.SAST.FILE_REGEX.test(file)); | ||
if (!sastFile) { | ||
throw new Error("No SAST file found in the directory."); | ||
} | ||
return Path.join(this.args.sastPath, sastFile); | ||
} | ||
if (!constants_1.CONSTANTS.SAST.FILE_REGEX.test(this.args.sastPath)) { | ||
throw new Error("The file does not match the required SAST pattern."); | ||
} | ||
return this.args.sastPath; | ||
} | ||
static async createAndRun() { | ||
@@ -215,4 +138,4 @@ api_client_1.soosLogger.info("Starting SOOS SAST Analysis"); | ||
api_client_1.soosLogger.verboseDebug(JSON.stringify((0, utilities_1.obfuscateProperties)(args, ["apiKey"]), null, 2)); | ||
(0, utilities_1.ensureValue)(args.clientId, "clientId"); | ||
(0, utilities_1.ensureValue)(args.apiKey, "apiKey"); | ||
(0, utilities_1.ensureNonEmptyValue)(args.clientId, "clientId"); | ||
(0, utilities_1.ensureNonEmptyValue)(args.apiKey, "apiKey"); | ||
api_client_1.soosLogger.logLineSeparator(); | ||
@@ -219,0 +142,0 @@ const soosSASTAnalysis = new SOOSSASTAnalysis(args); |
{ | ||
"name": "@soos-io/soos-sast", | ||
"version": "0.1.0", | ||
"version": "0.1.3", | ||
"description": "SOOS Static Application Security Testing (SAST) scanning support.", | ||
@@ -29,12 +29,12 @@ "main": "bin/index.js", | ||
"dependencies": { | ||
"@soos-io/api-client": "0.1.8", | ||
"@soos-io/api-client": "^0.2.12", | ||
"argparse": "^2.0.1", | ||
"glob": "^10.3.10", | ||
"tslib": "^2.6.2" | ||
}, | ||
"devDependencies": { | ||
"@types/argparse": "^2.0.11", | ||
"@types/glob": "^8.1.0", | ||
"@types/node": "^20.6.3", | ||
"prettier": "^2.8.8", | ||
"typescript": "^5.2.2" | ||
"@types/argparse": "^2.0.14", | ||
"@types/node": "^20.10.4", | ||
"prettier": "^3.1.1", | ||
"typescript": "^5.3.3" | ||
}, | ||
@@ -41,0 +41,0 @@ "bin": { |
@@ -29,21 +29,22 @@ # [SOOS SAST](https://soos.io/products/sast) | ||
| Argument | Default | Description | | ||
| ----------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | | ||
| `--apiKey` | `getEnvVariable(CONSTANTS.SOOS.API_KEY_ENV_VAR)` | SOOS API Key - get yours from [SOOS Integration](https://app.soos.io/integrate/sast). | | ||
| `--apiURL` | `"https://api.soos.io/api/"` | SOOS API URL - Intended for internal use only, do not modify. | | ||
| `--appVersion` | N/A | App Version - Intended for internal use only. | | ||
| `--branchName` | `null` | The name of the branch from the SCM System. | | ||
| `--branchURI` | `null` | The URI to the branch from the SCM System. | | ||
| `--buildURI` | `null` | URI to CI build info. | | ||
| `--buildVersion` | `null` | Version of application build artifacts. | | ||
| `--clientId` | `getEnvVariable(CONSTANTS.SOOS.CLIENT_ID_ENV_VAR)` | SOOS Client ID - get yours from [SOOS Integration](https://app.soos.io/integrate/sast). | | ||
| `--commitHash` | `null` | The commit hash value from the SCM System. | | ||
| `--integrationName` | N/A | Integration Name - Intended for internal use only. | | ||
| `--integrationType` | N/A | Integration Type - Intended for internal use only. | | ||
| `--logLevel` | `LogLevel.INFO` | Minimum level to show logs: PASS, IGNORE, INFO, WARN, or FAIL. | | ||
| `--operatingEnvironment`| `null` | Set Operating environment for information purposes only. | | ||
| `--otherOptions` | `null` | Other Options to pass to syft. | | ||
| `--projectName` | N/A | Project Name - this is what will be displayed in the SOOS app. | | ||
| `--scriptVersion` | N/A | Script Version - Intended for internal use only. | | ||
| `--verbose` | `false` | Enable verbose logging. | | ||
| `sastPath` | N/A | The SAST File to scan (*.sarif.json), it could be the location of the file or the file itself. When location is specified only the first file found will be scanned. | | ||
| Argument | Default | Description | | ||
| ------------------------ | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | | ||
| `--apiKey` | `getEnvVariable(CONSTANTS.SOOS.API_KEY_ENV_VAR)` | SOOS API Key - get yours from [SOOS Integration](https://app.soos.io/integrate/sast). | | ||
| `--apiURL` | N/A | SOOS API URL - Intended for internal use only, do not modify. | | ||
| `--appVersion` | N/A | App Version - Intended for internal use only. | | ||
| `--branchName` | `null` | The name of the branch from the SCM System. | | ||
| `--branchURI` | `null` | The URI to the branch from the SCM System. | | ||
| `--buildURI` | `null` | URI to CI build info. | | ||
| `--buildVersion` | `null` | Version of application build artifacts. | | ||
| `--clientId` | `getEnvVariable(CONSTANTS.SOOS.CLIENT_ID_ENV_VAR)` | SOOS Client ID - get yours from [SOOS Integration](https://app.soos.io/integrate/sast). | | ||
| `--commitHash` | `null` | The commit hash value from the SCM System. | | ||
| `--directoriesToExclude` | `**/node_modules/**, "**/bin/**", "**/obj/**", "**/lib/**` | Listing of directories or patterns to exclude from the search for manifest files. eg: **bin/start/**, **/start/** | | ||
| `--filesToExclude` | None | Listing of files or patterns to exclude from the search for manifest files. eg: **/req**.txt/, **/requirements.txt | | ||
| `--integrationName` | N/A | Integration Name - Intended for internal use only. | | ||
| `--integrationType` | N/A | Integration Type - Intended for internal use only. | | ||
| `--logLevel` | `INFO` | Minimum level to show logs: PASS, IGNORE, INFO, WARN or FAIL. | | ||
| `--operatingEnvironment` | `null` | Set Operating environment for information purposes only. | | ||
| `--projectName` | N/A | Project Name - this is what will be displayed in the SOOS app. | | ||
| `--scriptVersion` | N/A | Script Version - Intended for internal use only. | | ||
| `--sourceCodePath` | `process.cwd()` | Root path to begin recursive search for Sarif files. | | ||
| `--verbose` | `false` | Enable verbose logging. | |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
4
50
0
14549
4
158
1
+ Addedglob@^10.3.10
+ Added@isaacs/cliui@8.0.2(transitive)
+ Added@pkgjs/parseargs@0.11.0(transitive)
+ Added@soos-io/api-client@0.2.48(transitive)
+ Addedansi-regex@5.0.16.1.0(transitive)
+ Addedansi-styles@4.3.06.2.1(transitive)
+ Addedaxios@1.7.7(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbrace-expansion@2.0.1(transitive)
+ Addedcolor-convert@2.0.1(transitive)
+ Addedcolor-name@1.1.4(transitive)
+ Addedcross-spawn@7.0.5(transitive)
+ Addedeastasianwidth@0.2.0(transitive)
+ Addedemoji-regex@8.0.09.2.2(transitive)
+ Addedforeground-child@3.3.0(transitive)
+ Addedglob@10.4.5(transitive)
+ Addedis-fullwidth-code-point@3.0.0(transitive)
+ Addedisexe@2.0.0(transitive)
+ Addedjackspeak@3.4.3(transitive)
+ Addedlru-cache@10.4.3(transitive)
+ Addedminimatch@9.0.5(transitive)
+ Addedminipass@7.1.2(transitive)
+ Addedpackage-json-from-dist@1.0.1(transitive)
+ Addedpath-key@3.1.1(transitive)
+ Addedpath-scurry@1.11.1(transitive)
+ Addedproxy-from-env@1.1.0(transitive)
+ Addedshebang-command@2.0.0(transitive)
+ Addedshebang-regex@3.0.0(transitive)
+ Addedsignal-exit@4.1.0(transitive)
+ Addedstring-width@4.2.35.1.2(transitive)
+ Addedstrip-ansi@6.0.17.1.0(transitive)
+ Addedwhich@2.0.2(transitive)
+ Addedwrap-ansi@7.0.08.1.0(transitive)
- Removed@soos-io/api-client@0.1.8(transitive)
- Removedaxios@0.27.2(transitive)
Updated@soos-io/api-client@^0.2.12