From d45eec08d95c935dba55f6c15692475aa96939bf Mon Sep 17 00:00:00 2001 From: Artur Ribeiro <153724638+cx-artur-ribeiro@users.noreply.github.com> Date: Sun, 11 Oct 2026 12:19:37 +0100 Subject: [PATCH 1/2] fix: keep a scan path containing spaces as a single argument --- entrypoint.sh | 7 +++---- test/e2e/entrypoint.test.js | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/entrypoint.sh b/entrypoint.sh index 3fbc600..53ff7d2 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -8,8 +8,7 @@ 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 ########################### @@ -77,8 +76,8 @@ fi #################### 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_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 -p "$INPUT_PATH" $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 export KICS_EXIT_CODE=$? diff --git a/test/e2e/entrypoint.test.js b/test/e2e/entrypoint.test.js index a7c684f..4a0d4c0 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']) }) From 13091d39a453f655bd30ac68193780fec6f374f1 Mon Sep 17 00:00:00 2001 From: Artur Ribeiro <153724638+cx-artur-ribeiro@users.noreply.github.com> Date: Sun, 11 Oct 2026 12:29:37 +0100 Subject: [PATCH 2/2] fix: keep path-valued inputs containing spaces as single arguments --- entrypoint.sh | 26 ++++++++++++++------------ test/e2e/entrypoint.test.js | 18 +++++++++++++++++- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/entrypoint.sh b/entrypoint.sh index 53ff7d2..10e6305 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -14,9 +14,11 @@ 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" @@ -30,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" @@ -41,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 ############################################### @@ -65,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 -p $INPUT_PATH $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 -p "$INPUT_PATH" $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 4a0d4c0..02fb2a3 100644 --- a/test/e2e/entrypoint.test.js +++ b/test/e2e/entrypoint.test.js @@ -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'],