From 8efb89b3b365546eca172bb06a6314e0fe83eb07 Mon Sep 17 00:00:00 2001 From: Maarten Groeneweg Date: Fri, 9 Feb 2024 16:13:06 +0100 Subject: [PATCH 1/9] feat(validate-cmd-file): add validation for read/execute rights --- README.md | 2 +- src/renovate.ts | 27 +++++++++++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index dcf87d4b984..a956d17730e 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ Specify a command to run when the image start. By default the image run `renovate`. This option is useful to customize the image before running `renovate`. -It must be an existing executable file on the local system. +It must be an existing file on the local system and the it must have execute permission. It will be mounted to the docker container. For example you can create a simple script like this one (let's call it diff --git a/src/renovate.ts b/src/renovate.ts index 7573984194d..d4be83a453b 100644 --- a/src/renovate.ts +++ b/src/renovate.ts @@ -103,14 +103,25 @@ class Renovate { } const configurationFile = this.input.configurationFile(); - if ( - configurationFile !== null && - (!fs.existsSync(configurationFile.value) || - !fs.statSync(configurationFile.value).isFile()) - ) { - throw new Error( - `configuration file '${configurationFile.value}' MUST be an existing file`, - ); + if (configurationFile !== null) { + if ( + !fs.existsSync(configurationFile.value) || + !fs.statSync(configurationFile.value).isFile() + ) { + throw new Error( + `configuration file '${configurationFile.value}' MUST be an existing file`, + ); + } + try { + fs.accessSync( + configurationFile.value, + fs.constants.S_IXUSR | fs.constants.S_IRUSR, + ); + } catch { + throw new Error( + `configuration file '${configurationFile.value}' MUST have read and execute rights`, + ); + } } } } From 869619e0493ba02d3af25f1df6bf453560a21daa Mon Sep 17 00:00:00 2001 From: Maarten Groeneweg Date: Fri, 9 Feb 2024 16:15:13 +0100 Subject: [PATCH 2/9] chore(cicd): add temp test for entrypoint --- .github/non-executable-entrypoint.sh | 7 +++++++ .github/workflows/build.yml | 10 ++++++++++ 2 files changed, 17 insertions(+) create mode 100644 .github/non-executable-entrypoint.sh diff --git a/.github/non-executable-entrypoint.sh b/.github/non-executable-entrypoint.sh new file mode 100644 index 00000000000..d7ab0985137 --- /dev/null +++ b/.github/non-executable-entrypoint.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +set -e + +install-apt sl + +exec runuser -u ubuntu renovate diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 89337fdcb1b..dd8681aa219 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -104,6 +104,16 @@ jobs: docker-cmd-file: example/entrypoint.sh docker-user: root + - name: Renovate test with entrypoint + uses: ./ + env: + LOG_LEVEL: debug + with: + configurationFile: ${{ matrix.configurationFile }} + renovate-version: ${{ env.RENOVATE_VERSION }} + docker-cmd-file: .github/workflows/non-executable-entrypoint.sh + docker-user: root + release: needs: [lint, commitlint, e2e] runs-on: ubuntu-latest From c23b2a4dbd578953f8574d26edd110c842d3f071 Mon Sep 17 00:00:00 2001 From: Maarten Groeneweg Date: Fri, 9 Feb 2024 16:25:19 +0100 Subject: [PATCH 3/9] feat(validate-cmd-file): correct validation constants --- src/renovate.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renovate.ts b/src/renovate.ts index d4be83a453b..d78f1f91099 100644 --- a/src/renovate.ts +++ b/src/renovate.ts @@ -115,7 +115,7 @@ class Renovate { try { fs.accessSync( configurationFile.value, - fs.constants.S_IXUSR | fs.constants.S_IRUSR, + fs.constants.R_OK | fs.constants.X_OK, ); } catch { throw new Error( From c6f0c0676672c10e2b535565502007f1d5b79b5e Mon Sep 17 00:00:00 2001 From: Maarten Groeneweg Date: Fri, 9 Feb 2024 16:39:03 +0100 Subject: [PATCH 4/9] feat(validate-cmd-file): corrected validation --- src/renovate.ts | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/renovate.ts b/src/renovate.ts index d78f1f91099..725b3d14765 100644 --- a/src/renovate.ts +++ b/src/renovate.ts @@ -101,25 +101,39 @@ class Renovate { if (/\s/.test(this.input.token.value)) { throw new Error('Token MUST NOT contain whitespace'); } + this.validateConfigFileArgument(); + this.validateDockerCmdFileArgument(); + } + private validateConfigFileArgument(): void { const configurationFile = this.input.configurationFile(); - if (configurationFile !== null) { + if ( + configurationFile !== null && + (!fs.existsSync(configurationFile.value) || + !fs.statSync(configurationFile.value).isFile()) + ) { + throw new Error( + `configuration file '${configurationFile.value}' MUST be an existing file`, + ); + } + } + + private validateDockerCmdFileArgument(): void { + const dockerCmdFile = this.input.getDockerCmdFile(); + if (dockerCmdFile !== null) { if ( - !fs.existsSync(configurationFile.value) || - !fs.statSync(configurationFile.value).isFile() + !fs.existsSync(dockerCmdFile) || + !fs.statSync(dockerCmdFile).isFile() ) { throw new Error( - `configuration file '${configurationFile.value}' MUST be an existing file`, + `dockerCmdFile '${dockerCmdFile}' MUST be an existing file`, ); } try { - fs.accessSync( - configurationFile.value, - fs.constants.R_OK | fs.constants.X_OK, - ); + fs.accessSync(dockerCmdFile, fs.constants.R_OK | fs.constants.X_OK); } catch { throw new Error( - `configuration file '${configurationFile.value}' MUST have read and execute rights`, + `dockerCmdFile '${dockerCmdFile}' MUST have read and execute rights`, ); } } From 49b85c96e553221ed33299f70c3cc247621c90e3 Mon Sep 17 00:00:00 2001 From: Maarten Groeneweg Date: Fri, 9 Feb 2024 16:42:06 +0100 Subject: [PATCH 5/9] chore(cicd): remove temporary e2e test --- .github/non-executable-entrypoint.sh | 7 ------- .github/workflows/build.yml | 10 ---------- 2 files changed, 17 deletions(-) delete mode 100644 .github/non-executable-entrypoint.sh diff --git a/.github/non-executable-entrypoint.sh b/.github/non-executable-entrypoint.sh deleted file mode 100644 index d7ab0985137..00000000000 --- a/.github/non-executable-entrypoint.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -set -e - -install-apt sl - -exec runuser -u ubuntu renovate diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dd8681aa219..89337fdcb1b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -104,16 +104,6 @@ jobs: docker-cmd-file: example/entrypoint.sh docker-user: root - - name: Renovate test with entrypoint - uses: ./ - env: - LOG_LEVEL: debug - with: - configurationFile: ${{ matrix.configurationFile }} - renovate-version: ${{ env.RENOVATE_VERSION }} - docker-cmd-file: .github/workflows/non-executable-entrypoint.sh - docker-user: root - release: needs: [lint, commitlint, e2e] runs-on: ubuntu-latest From 4140ebd82349903b449ef869d3dab973f46d9c6f Mon Sep 17 00:00:00 2001 From: Maarten Groeneweg Date: Fri, 9 Feb 2024 16:46:51 +0100 Subject: [PATCH 6/9] chore(doc): fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a956d17730e..15269a80c7f 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ Specify a command to run when the image start. By default the image run `renovate`. This option is useful to customize the image before running `renovate`. -It must be an existing file on the local system and the it must have execute permission. +It must be an existing file on the local system and it must have execute permission. It will be mounted to the docker container. For example you can create a simple script like this one (let's call it From b00aebe09d4665c68cdef329c38e3c6c8785b7c5 Mon Sep 17 00:00:00 2001 From: Michael Kriese Date: Tue, 13 Feb 2024 15:59:45 +0100 Subject: [PATCH 7/9] Apply suggestions from code review --- src/renovate.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/renovate.ts b/src/renovate.ts index 8ad3fbc0d2f..38111ad59f9 100644 --- a/src/renovate.ts +++ b/src/renovate.ts @@ -101,11 +101,11 @@ class Renovate { if (/\s/.test(this.input.token.value)) { throw new Error('Token MUST NOT contain whitespace'); } - this.validateConfigFileArgument(); - this.validateDockerCmdFileArgument(); + await this.validateConfigFileArgument(); + await this.validateDockerCmdFileArgument(); } - private validateConfigFileArgument(): void { + private async validateConfigFileArgument(): Promise { const configurationFile = this.input.configurationFile(); if ( configurationFile !== null && From a5fbebd976d87d1361bcfa416c32696b033af8c7 Mon Sep 17 00:00:00 2001 From: Michael Kriese Date: Tue, 13 Feb 2024 16:00:01 +0100 Subject: [PATCH 8/9] Update src/renovate.ts --- src/renovate.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renovate.ts b/src/renovate.ts index 38111ad59f9..4596d8b70f4 100644 --- a/src/renovate.ts +++ b/src/renovate.ts @@ -117,7 +117,7 @@ class Renovate { } } - private validateDockerCmdFileArgument(): void { + private async validateDockerCmdFileArgument(): Promise { const dockerCmdFile = this.input.getDockerCmdFile(); if (dockerCmdFile !== null) { if ( From 3154895fb33ed33ee34bd5f079bbc7b192f8ec99 Mon Sep 17 00:00:00 2001 From: Maarten Groeneweg Date: Sat, 17 Feb 2024 14:29:58 +0100 Subject: [PATCH 9/9] feat(validate-cmd-file): async validation --- src/renovate.ts | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/renovate.ts b/src/renovate.ts index 4596d8b70f4..d1a6450b139 100644 --- a/src/renovate.ts +++ b/src/renovate.ts @@ -119,22 +119,23 @@ class Renovate { private async validateDockerCmdFileArgument(): Promise { const dockerCmdFile = this.input.getDockerCmdFile(); - if (dockerCmdFile !== null) { + if (dockerCmdFile === null) return; + + try { + const s = await fs.stat(dockerCmdFile); + if (!s.isFile) + throw new Error(`dockerCmdFile '${dockerCmdFile}' MUST be a file`); if ( - !fs.existsSync(dockerCmdFile) || - !fs.statSync(dockerCmdFile).isFile() - ) { - throw new Error( - `dockerCmdFile '${dockerCmdFile}' MUST be an existing file`, - ); - } - try { - fs.accessSync(dockerCmdFile, fs.constants.R_OK | fs.constants.X_OK); - } catch { + (s.mode & fs.constants.R_OK) === 0 || + (s.mode & fs.constants.X_OK) === 0 + ) throw new Error( `dockerCmdFile '${dockerCmdFile}' MUST have read and execute rights`, ); - } + } catch (err) { + if (err instanceof Error && 'code' in err && err.code === 'ENOENT') + throw new Error(`dockerCmdFile '${dockerCmdFile}' does not exist`); + throw new Error(err as string); } } }