diff --git a/entrypoint.sh b/entrypoint.sh index 3fbc600..10e6305 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -8,16 +8,17 @@ if [ -z "$INPUT_PATH" ]; then echo "${DATETIME} - ERR input path can't be empty" exit 1 else - INPUT_PATH=$(echo $INPUT_PATH | sed -e 's/^"//' -e 's/"$//') - INPUT_PARAM="-p $INPUT_PATH" + INPUT_PATH=$(echo "$INPUT_PATH" | sed -e 's/^"//' -e 's/"$//') fi ########################### # Set KICS Flags Values # ########################### -[[ ! -z "$INPUT_PAYLOAD_PATH" ]] && PAYLOAD_PATH_PARAM="-d $INPUT_PAYLOAD_PATH" -[[ ! -z "$INPUT_CONFIG_PATH" ]] && CONFIG_PATH_PARAM="--config $INPUT_CONFIG_PATH" -[[ ! -z "$INPUT_EXCLUDE_PATHS" ]] && EXCLUDE_PATHS_PARAM="-e $INPUT_EXCLUDE_PATHS" +# Flags that take a path go in "$@" so a path containing spaces stays one argument +set -- +[[ ! -z "$INPUT_PAYLOAD_PATH" ]] && set -- "$@" -d "$INPUT_PAYLOAD_PATH" +[[ ! -z "$INPUT_CONFIG_PATH" ]] && set -- "$@" --config "$INPUT_CONFIG_PATH" +[[ ! -z "$INPUT_EXCLUDE_PATHS" ]] && set -- "$@" -e "$INPUT_EXCLUDE_PATHS" [[ ! -z "$INPUT_EXCLUDE_RESULTS" ]] && EXCLUDE_RESULTS_PARAM="-x $INPUT_EXCLUDE_RESULTS" [[ ! -z "$INPUT_EXCLUDE_SEVERITIES" ]] && EXCLUDE_SEVERITIES_PARAM="--exclude-severities $INPUT_EXCLUDE_SEVERITIES" [[ ! -z "$INPUT_EXCLUDE_QUERIES" ]] && EXCLUDE_QUERIES_PARAM="--exclude-queries $INPUT_EXCLUDE_QUERIES" @@ -31,8 +32,8 @@ fi [[ ! -z "$INPUT_INCLUDE_QUERIES" ]] && INCLUDE_QUERIES_PARAM="-i $INPUT_INCLUDE_QUERIES" [[ "$INPUT_DISABLE_SECRETS" == "true" ]] && DISABLE_SECRETS_PARAM="--disable-secrets" [[ "$INPUT_DISABLE_FULL_DESCRIPTIONS" == "true" ]] && DISABLE_FULL_DESCRIPTIONS_PARAM="--disable-full-descriptions" -[[ ! -z "$INPUT_LIBRARIES_PATH" ]] && LIBRARIES_PATH_PARAM="-b $INPUT_LIBRARIES_PATH" -[[ ! -z "$INPUT_SECRETS_REGEXES_PATH" ]] && SECRETS_REGEXES_PATH_PARAM="-r $INPUT_SECRETS_REGEXES_PATH" +[[ ! -z "$INPUT_LIBRARIES_PATH" ]] && set -- "$@" -b "$INPUT_LIBRARIES_PATH" +[[ ! -z "$INPUT_SECRETS_REGEXES_PATH" ]] && set -- "$@" -r "$INPUT_SECRETS_REGEXES_PATH" [[ ! -z "$INPUT_IGNORE_ON_EXIT" ]] && IGNORE_ON_EXIT_PARAM="--ignore-on-exit $INPUT_IGNORE_ON_EXIT" [[ ! -z "$INPUT_CLOUD_PROVIDER" ]] && CLOUD_PROVIDER="--cloud-provider $INPUT_CLOUD_PROVIDER" @@ -42,9 +43,9 @@ fi # Set Queries Path # ####################### if [ ! -z "$INPUT_QUERIES" ]; then - QUERIES_PARAM="-q $INPUT_QUERIES" + set -- "$@" -q "$INPUT_QUERIES" else - QUERIES_PARAM="-q /app/bin/assets/queries" + set -- "$@" -q /app/bin/assets/queries fi ############################################### @@ -66,19 +67,19 @@ fi CP_PATH="./results.json" if [ ! -z "$INPUT_OUTPUT_PATH" ]; then - OUTPUT_PATH_PARAM="-o $INPUT_OUTPUT_PATH" + set -- "$@" -o "$INPUT_OUTPUT_PATH" CP_PATH=$INPUT_OUTPUT_PATH else - OUTPUT_PATH_PARAM="-o ./" + set -- "$@" -o ./ fi #################### # Run KICS Scan # #################### -cd $GITHUB_WORKSPACE +cd "$GITHUB_WORKSPACE" echo "${DATETIME} - INF : about to scan directory $INPUT_PATH" -echo "${DATETIME} - INF : kics command kics $INPUT_PARAM $OUTPUT_PATH_PARAM $OUTPUT_FORMATS_PARAM $PLATFORM_TYPE_PARAM $PAYLOAD_PATH_PARAM $CONFIG_PATH_PARAM $EXCLUDE_PATHS_PARAM $EXCLUDE_CATEGORIES_PARAM $EXCLUDE_RESULTS_PARAM $EXCLUDE_SEVERITIES_PARAM $EXCLUDE_QUERIES_PARAM $EXCLUDE_GITIGNORE $QUERIES_PARAM $VERBOSE_PARAM $IGNORE_ON_EXIT_PARAM $FAIL_ON_PARAM $TIMEOUT_PARAM $PROFILING_PARAM $BOM_PARAM $INCLUDE_QUERIES_PARAM $DISABLE_SECRETS_PARAM $DISABLE_FULL_DESCRIPTIONS_PARAM $LIBRARIES_PATH_PARAM $SECRETS_REGEXES_PATH_PARAM $CLOUD_PROVIDER" -/app/bin/kics scan --no-progress $INPUT_PARAM $OUTPUT_PATH_PARAM $OUTPUT_FORMATS_PARAM $PLATFORM_TYPE_PARAM $PAYLOAD_PATH_PARAM $CONFIG_PATH_PARAM $EXCLUDE_PATHS_PARAM $EXCLUDE_CATEGORIES_PARAM $EXCLUDE_RESULTS_PARAM $EXCLUDE_SEVERITIES_PARAM $EXCLUDE_QUERIES_PARAM $EXCLUDE_GITIGNORE $QUERIES_PARAM $VERBOSE_PARAM $IGNORE_ON_EXIT_PARAM $FAIL_ON_PARAM $TIMEOUT_PARAM $PROFILING_PARAM $BOM_PARAM $INCLUDE_QUERIES_PARAM $DISABLE_SECRETS_PARAM $DISABLE_FULL_DESCRIPTIONS_PARAM $LIBRARIES_PATH_PARAM $SECRETS_REGEXES_PATH_PARAM $CLOUD_PROVIDER +echo "${DATETIME} - INF : kics command kics -p $INPUT_PATH $OUTPUT_FORMATS_PARAM $PLATFORM_TYPE_PARAM $EXCLUDE_CATEGORIES_PARAM $EXCLUDE_RESULTS_PARAM $EXCLUDE_SEVERITIES_PARAM $EXCLUDE_QUERIES_PARAM $EXCLUDE_GITIGNORE $VERBOSE_PARAM $IGNORE_ON_EXIT_PARAM $FAIL_ON_PARAM $TIMEOUT_PARAM $PROFILING_PARAM $BOM_PARAM $INCLUDE_QUERIES_PARAM $DISABLE_SECRETS_PARAM $DISABLE_FULL_DESCRIPTIONS_PARAM $CLOUD_PROVIDER $*" +/app/bin/kics scan --no-progress -p "$INPUT_PATH" $OUTPUT_FORMATS_PARAM $PLATFORM_TYPE_PARAM $EXCLUDE_CATEGORIES_PARAM $EXCLUDE_RESULTS_PARAM $EXCLUDE_SEVERITIES_PARAM $EXCLUDE_QUERIES_PARAM $EXCLUDE_GITIGNORE $VERBOSE_PARAM $IGNORE_ON_EXIT_PARAM $FAIL_ON_PARAM $TIMEOUT_PARAM $PROFILING_PARAM $BOM_PARAM $INCLUDE_QUERIES_PARAM $DISABLE_SECRETS_PARAM $DISABLE_FULL_DESCRIPTIONS_PARAM $CLOUD_PROVIDER "$@" export KICS_EXIT_CODE=$? diff --git a/test/e2e/entrypoint.test.js b/test/e2e/entrypoint.test.js index a7c684f..02fb2a3 100644 --- a/test/e2e/entrypoint.test.js +++ b/test/e2e/entrypoint.test.js @@ -30,7 +30,7 @@ test('required input', async (t) => { assert.equal(flagValue(run.args, '-p'), 'terraform,modules') }) - await t.test('keeps a path containing spaces as one argument', knownBug('the unquoted $INPUT_PATH is word-split, so "my infra" becomes two arguments'), async (t) => { + await t.test('keeps a path containing spaces as one argument', async (t) => { const run = await runEntrypoint(t, { inputs: { path: 'my infra' } }) assert.deepEqual(run.args.slice(run.args.indexOf('-p'), run.args.indexOf('-p') + 2), ['-p', 'my infra']) }) @@ -44,7 +44,7 @@ test('baseline command line', async (t) => { await t.test('with no optional inputs, passes only path, output, report format and bundled queries', async (t) => { const run = await runEntrypoint(t) - assert.deepEqual(run.args, ['scan', '--no-progress', '-p', 'infra', '-o', './', '--report-formats', 'json', '-q', DEFAULT_QUERIES]) + assert.deepEqual(run.args, ['scan', '--no-progress', '-p', 'infra', '--report-formats', 'json', '-q', DEFAULT_QUERIES, '-o', './']) }) await t.test('uses the queries bundled in the image unless told otherwise', async (t) => { @@ -79,6 +79,22 @@ test('inputs mapped to KICS flags', async (t) => { }) } + const withSpaces = [ + ['payload_path', 'my dir/payload file.json', '-d'], + ['config_path', 'my dir/kics config.json', '--config'], + ['exclude_paths', 'my dir/skip me,other dir/file.tf', '-e'], + ['libraries_path', 'my libs', '-b'], + ['secrets_regexes_path', 'my dir/secret regexes.json', '-r'], + ['queries', 'my queries,team queries', '-q'], + ['output_path', 'my out', '-o'], + ] + for (const [input, value, flag] of withSpaces) { + await t.test(`${input} keeps a value containing spaces as one argument`, async (t) => { + const run = await runEntrypoint(t, { inputs: { [input]: value } }) + assert.equal(flagValue(run.args, flag), value, run.args.join(' ')) + }) + } + const switches = [ ['exclude_gitignore', '--exclude-gitignore'], ['disable_secrets', '--disable-secrets'],