BetaHuhn/deploy-to-vercel-action

Commit message `commands` are unescaped

Siilwyn opened this issue ยท 10 comments

๐Ÿž Describe the bug

Running a commit that contains backticks (`), cause the action to fail because the shell seems to try and run what is contained within the backticks.

๐Ÿ“š To Reproduce
Create a commit with e.g. the message: Switch to ESM format to remove need on dependency fsx

Deploy using this action using default config (no custom options), result:

Error: Command failed: vercel -t *** -m "githubCommitAuthorName=Selwyn" -m "githubCommitAuthorLogin=Siilwyn" -m "githubCommitMessage=Switch to ESM format to remove need on dependency `fsx`" -m "githubCommitOrg=voorhoede" -m "githubCommitRepo=life-terra-platform" -m "githubCommitRef=paginate-translations" -m "githubCommitSha=0aa1994f696737ebe462c6fab9931ce937382c5c" -m "githubOrg=voorhoede" -m "githubRepo=life-terra-platform" -m "githubDeployment=1"
/bin/sh: 1: fsx: not found

Hey @Siilwyn thanks for taking the time to open this Issue!

Running a commit that contains backticks (`), cause the action to fail because the shell seems to try and run what is contained within the backticks.

Looks like we need to escape backticks before running the command.

Would you be able to create a PR for this? No worries if not, I will work on this sometime this week!

I'm wondering how to fix this though,

seems like escaping the command should be done here:

exec(command, (err, stdout) => {
err ? reject(err) : resolve(stdout.trim())
})

Since the command is constructed a solution would be to use child_process.spawn which accepts arguments as an array, seems like that would escape the value for us:

const { spawn } = require('child_process');
const process = spawn('echo', ['`fsx`']);

process.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

process.stderr.on('data', (data) => {
  console.error(`stderr: ${data}`);
});

process.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
});

Logs 'fsx' instead of executing it, thoughts?

That seems like the best/safest solution as we don't have to handle escaping ourselfs.

How are multiple arguments and options handled with the array? Here's how the command is constructed right now:

let command = `vercel -t ${ VERCEL_TOKEN }`
if (VERCEL_SCOPE) {
command += ` --scope ${ VERCEL_SCOPE }`
}
if (PRODUCTION) {
command += ` --prod`
}
if (commit) {
const metadata = [
`githubCommitAuthorName=${ commit.authorName }`,
`githubCommitAuthorLogin=${ commit.authorLogin }`,
`githubCommitMessage=${ commit.commitMessage }`,
`githubCommitOrg=${ USER }`,
`githubCommitRepo=${ REPOSITORY }`,
`githubCommitRef=${ REF }`,
`githubCommitSha=${ SHA }`,
`githubOrg=${ USER }`,
`githubRepo=${ REPOSITORY }`,
`githubDeployment=1`
]
metadata.forEach((item) => {
command += ` -m "${ item }"`
})

Made a PR as a start, feel free to edit/merge and/or review. I haven't tested this yet, not sure how I would too. ๐Ÿค”

Great, will take a look!

I haven't tested this yet, not sure how I would too.

No worries, I will test it. There is not really an easy way to do it, I have a test repository where I am running the action from the develop branch of this repo.

Got it to work. Had to use a bit of a different syntax for the arguments and also parse the deployment URL out of stdout manually with regex.

commands are now escaped.

Let me know if you encounter any other issues!

๐ŸŽ‰ This issue has been resolved in version 1.3.17 ๐ŸŽ‰

The release is available on GitHub release

To use the latest version, use the Action with the v1 tag:

uses: BetaHuhn/deploy-to-vercel-action@v1

Or the latest tag:

uses: BetaHuhn/deploy-to-vercel-action@latest

Your semantic-release bot ๐Ÿ“ฆ๐Ÿš€

Thanks again @Siilwyn!

Cool thank you too for this super helpful action!

No problem, glad you find it useful!