Skip to content

Commit 897edb3

Browse files
committed
feat: scan list of target
1 parent 33dc3ba commit 897edb3

File tree

8 files changed

+232
-41
lines changed

8 files changed

+232
-41
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
node_modules
22
.npmrc
3+
logs

.npmignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
.npmrc
2-
node_modules
2+
node_modules
3+
logs

README.md

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ CodeQL Agent CLI is a tool that automates the process of using CodeQL, a semanti
1919
## Features
2020

2121
- Automated CodeQL from detect language, create database and scan.
22-
- Scan remote target (e.g. GitHub repository) or local target (e.g. source code folder).
22+
- Scan remote target (e.g. GitHub repository) or local target (e.g. source code folder). Support scan list of target.
2323
- Support running on Docker which prepackaged and precompiled CodeQL for running code scanning (*under development*).
2424
- Send results to Discord webhook.
2525

@@ -65,23 +65,33 @@ codeql-agent scan -h
6565
This will display help for the tool. Here are all the switches of `scan` command supports.
6666

6767
```console
68+
____ _ ___ _ _ _
69+
/ ___|___ __| | ___ / _ \| | / \ __ _ ___ _ __ | |_
70+
| | / _ \ / _` |/ _ \ | | | | / _ \ / _` |/ _ \ '_ \| __|
71+
| |__| (_) | (_| | __/ |_| | |___ / ___ \ (_| | __/ | | | |_
72+
\____\___/ \__,_|\___|\__\_\_____| /_/ \_\__, |\___|_| |_|\__|
73+
|___/
74+
Author: doublevkay - Version: 0.3.0
75+
6876
Usage: codeql-agent scan [options] <target>
6977

70-
scan a source code folder or remote repository (e.g. GitHub repository)
78+
scan a target. Target could be source code folder, remote repository (e.g. GitHub repository) or a list of target.
7179

7280
Arguments:
73-
target source code folder or remote repository.
81+
target source code folder, remote repository or list of target.
7482

7583
Examples:
7684
codeql-agent scan src/sammple
77-
codeql-agent scan src/sammple --use-docker
85+
codeql-agent scan targets.txt
7886
codeql-agent scan https://github.com/OWASP/NodeGoat
7987

8088
Options:
81-
-l, --language <language> language of source code. Supported languages: go, java, cpp, csharp, cpp, javascript, ruby. Omitting this option to auto-detect the language.
89+
-l, --language <language> language of source code. Supported languages: go, java, cpp, csharp, cpp, javascript, ruby. Omitting this option to auto-detect the
90+
language.
8291
-o, --output <output> output folder. Default: <target>-codeql-results
83-
-c, --command <command> command to create database for compiled languages, omit if the only languages requested are Python and JavaScript. This specifies the build commands needed to invoke the compiler. If
84-
you don't set this variable, CodeQL will attempt to detect the build system automatically, using a built-in autobuilder
92+
-c, --command <command> command to create database for compiled languages, omit if the only languages requested are Python and JavaScript. This specifies
93+
the build commands needed to invoke the compiler. If you don't set this variable, CodeQL will attempt to detect the build system
94+
automatically, using a built-in autobuilder
8595
-t, --threads <number> number of threads to use. Pass 0 to use one threads per core on the machine. Default: 1 (default: 1)
8696
--query <query> CodeQL query to run. Default: <language>-security-extended.qls
8797
--format <format> output format. Default: sarif-latest (default: "sarif-latest")

cli.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ program
2626
.version(config.version);
2727

2828
program.command('scan')
29-
.description('scan a source code folder or remote repository (e.g. GitHub repository)')
30-
.argument('<target>', 'source code folder or remote repository.\n\nExamples:\n\tcodeql-agent scan src/sammple\n\tcodeql-agent scan src/sammple --use-docker\n\tcodeql-agent scan https://github.com/OWASP/NodeGoat')
29+
.description('scan a target. Target could be source code folder, remote repository (e.g. GitHub repository) or a list of target.')
30+
.argument('<target>', 'source code folder, remote repository or list of target.\n\nExamples:\n\tcodeql-agent scan src/sammple\n\tcodeql-agent scan targets.txt\n\tcodeql-agent scan https://github.com/OWASP/NodeGoat')
3131
.option('-l, --language <language>', 'language of source code. Supported languages: go, java, cpp, csharp, cpp, javascript, ruby. Omitting this option to auto-detect the language.',)
3232
.option('-o, --output <output>', 'output folder. Default: <target>-codeql-results')
3333
.option('-c, --command <command>', 'command to create database for compiled languages, omit if the only languages requested are Python and JavaScript. This specifies the build commands needed to invoke the compiler. If you don\'t set this variable, CodeQL will attempt to detect the build system automatically, using a built-in autobuilder')

index.js

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,62 +3,69 @@ const utils = require('./utils');
33
const fs = require('fs');
44
const config = require('./config');
55
const path = require('path');
6+
const pLimit = require('p-limit');
67

78
module.exports = {
89
scan: scanAction
910
}
1011

1112
async function scanAction(sourceTarget, options) {
1213
if (options.verbose) { defaultLogger.setLevel('verbose') }
14+
if (options.enableFileLogging) { defaultLogger.enableFileTransport() }
15+
if (options.discordWebhook) { bugLogger.enableDiscordTransport(options.discordWebhook) }
16+
options.enableFileLogging = undefined
17+
options.discordWebhook = undefined
1318
if (options.useDocker) {
1419
await utils.isCommandExist('docker', defaultLogger);
1520
defaultLogger.error('Docker is not supported yet.');
1621
return;
1722
}
18-
if (options.enableFileLogging) { defaultLogger.enableFileTransport() }
19-
if (options.discordWebhook) { bugLogger.enableDiscordTransport(options.discordWebhook) }
2023
await utils.isCommandExist('codeql', defaultLogger);
21-
// Create Database
22-
var createDbOptions = { ...options };
23-
createDbOptions.output = options.dbOutput;
24+
if (fs.existsSync(sourceTarget) && fs.statSync(sourceTarget).isFile()) {
25+
const targets = fs.readFileSync(sourceTarget, 'utf8').split(/\r?\n/);
26+
const limit = pLimit(1);
27+
return await Promise.all(targets.map((target) => limit(() => scanAction(target, options))));
28+
}
2429
var isRemoteRepository = utils.isRemoteRepository(sourceTarget);
30+
var sourceFolderPath = '';
2531
if (isRemoteRepository) {
2632
defaultLogger.info(`Cloning remote repository ${sourceTarget}`)
2733
sourceFolderPath = await utils.cloneRemoteRepository(sourceTarget, defaultLogger);
2834
} else sourceFolderPath = sourceTarget;
35+
if (!fs.existsSync(sourceFolderPath)) {
36+
defaultLogger.error(`Source folder \`${sourceFolderPath}\` does not exist.`);
37+
return [];
38+
}
2939
sourceFolderPath = fs.realpathSync(sourceFolderPath);
3040
defaultLogger.info(`Creating CodeQL database for ${sourceFolderPath}...`)
41+
42+
// Create Database
43+
var createDbOptions = { ...options };
44+
createDbOptions.output = options.dbOutput;
3145
var { args: createDbArgs, databasePath } = await utils.setupCreateDatabaseCommandArgs(sourceFolderPath, createDbOptions, defaultLogger);
3246
defaultLogger.verbose(`Options:`);
3347
for (const key in options) {
3448
const element = options[key];
3549
defaultLogger.verbose(`[+] ${key}: ${element}`);
3650
}
3751
createDbExitCode = await utils.executeCommand('codeql', createDbArgs, 'Create CodeQL database', defaultLogger);
38-
defaultLogger.info(`CodeQL database created at ${databasePath}.`)
39-
if (isRemoteRepository && options.removeRemoteRepository) {
40-
defaultLogger.info(`Removing remote repository ${sourceFolderPath}`)
41-
await utils.removeFolder(sourceFolderPath, defaultLogger);
42-
}
4352
if (options.createDbOnly) {
4453
return databasePath;
4554
}
55+
4656
// Scan Database
4757
const outputFolderPath = options.output ? options.output : path.resolve(`${databasePath.endsWith('-codeql-database') ? databasePath.slice(0, -16) : databasePath}-codeql-results`);
4858
if (!fs.existsSync(outputFolderPath)) {
4959
fs.mkdirSync(outputFolderPath);
5060
}
5161
const languages = await utils.getDatabaseLanguages(databasePath, defaultLogger);
52-
if (!languages) {
53-
defaultLogger.error('Can not detect languages. Please specify the language using --language option');
54-
return;
55-
}
5662
for (const language of languages) {
5763
options.language = language;
5864
languageDatabasePath = path.resolve(`${databasePath}${path.sep}${language}`);
59-
options.output = path.resolve(outputFolderPath, `${language}-codeql-result.sarif`)
65+
const scanOption = { ...options };
66+
scanOption.output = path.resolve(outputFolderPath, `${language}-codeql-result.sarif`)
6067
defaultLogger.info(`Scanning ${language} code in ${databasePath}...`)
61-
var { args: scanArgs } = await utils.setupScanCommandArgs(languageDatabasePath, options, defaultLogger);
68+
var { args: scanArgs } = await utils.setupScanCommandArgs(languageDatabasePath, scanOption, defaultLogger);
6269
await utils.executeCommand('codeql', scanArgs, 'Scan CodeQL database', defaultLogger);
6370
}
6471
defaultLogger.info(`CodeQL scan results saved at ${outputFolderPath}.`)
@@ -78,9 +85,14 @@ async function scanAction(sourceTarget, options) {
7885
meta: alert
7986
});
8087
}
88+
if (isRemoteRepository && options.removeRemoteRepository) {
89+
defaultLogger.verbose(`Removing remote repository ${sourceFolderPath}`)
90+
utils.removeFolder(sourceFolderPath, defaultLogger);
91+
}
8192
if (options.removeDatabase) {
82-
defaultLogger.info(`Removing database folder ${databasePath}`)
83-
await utils.removeFolder(databasePath, defaultLogger);
93+
defaultLogger.verbose(`Removing database folder ${databasePath}`)
94+
utils.removeFolder(databasePath, defaultLogger);
8495
}
8596
return alerts;
8697
}
98+

0 commit comments

Comments
 (0)