Skip to content

Commit

Permalink
refactor: escape user input to prevent script injection (#56)
Browse files Browse the repository at this point in the history
* refactor: use run step condition (#55)

* refactor: use run step condition

Composite run steps have had support for conditions [since November 9th, 2021](https://github.blog/changelog/2021-11-09-github-actions-conditional-execution-of-steps-in-actions/).

* chore: bump patch version

* refactor: escape user inputs to prevent script injections

See [Understanding the risk of script injections](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#understanding-the-risk-of-script-injections).

* refactor: pass GitHub token as environment variable instead of command line argument

This is done to decrease the change of the GitHub token from appearing in any logs.

* refactor: use core API for logging to decrease the risk of secret leaks

* chore: bump patch version
  • Loading branch information
LayZeeDK authored Sep 2, 2022
1 parent 526caa9 commit c1bcacc
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 40 deletions.
4 changes: 3 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ runs:
steps:
- name: Set base and head SHAs used for nx affected
id: setSHAs
env:
GITHUB_TOKEN: ${{ github.token }}
shell: bash
run: node $GITHUB_ACTION_PATH/dist/index.js ${{ github.token }} ${{ inputs.main-branch-name }} ${{ inputs.error-on-no-successful-workflow }} ${{ inputs.last-successful-event }} ${{ inputs.working-directory }} ${{ inputs.workflow-id }}
run: node $GITHUB_ACTION_PATH/dist/index.js

- name: Log base and head SHAs used for nx affected
shell: bash
Expand Down
37 changes: 18 additions & 19 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -62798,12 +62798,11 @@ const { execSync } = __nccwpck_require__(3129);
const { existsSync } = __nccwpck_require__(5747);

const { runId, repo: { repo, owner }, eventName } = github.context;
process.env.GITHUB_TOKEN = process.argv[2];
const mainBranchName = process.argv[3];
const errorOnNoSuccessfulWorkflow = process.argv[4];
const lastSuccessfulEvent = process.argv[5];
const workingDirectory = process.argv[6];
const workflowId = process.argv[7];
const mainBranchName = core.getInput('main-branch-name');
const errorOnNoSuccessfulWorkflow = core.getInput('error-on-no-successful-workflow');
const lastSuccessfulEvent = core.getInput('last-successful-event');
const workingDirectory = core.getInput('working-directory');
const workflowId = core.getInput('workflow-id');
const defaultWorkingDirectory = '.';

let BASE_SHA;
Expand All @@ -62812,15 +62811,15 @@ let BASE_SHA;
if (existsSync(workingDirectory)) {
process.chdir(workingDirectory);
} else {
process.stdout.write('\n');
process.stdout.write(`WARNING: Working directory '${workingDirectory}' doesn't exist.\n`);
core.warning('\n');
core.warning(`WARNING: Working directory '${workingDirectory}' doesn't exist.\n`);
}
}

const HEAD_SHA = execSync(`git rev-parse HEAD`, { encoding: 'utf-8' });

if (eventName === 'pull_request') {
BASE_SHA = execSync(`git merge-base origin/${mainBranchName} HEAD`, { encoding: 'utf-8' });
BASE_SHA = execSync(`git merge-base origin/"${mainBranchName}" HEAD`, { encoding: 'utf-8' });
} else {
try {
BASE_SHA = await findSuccessfulCommit(workflowId, runId, owner, repo, mainBranchName, lastSuccessfulEvent);
Expand All @@ -62834,19 +62833,19 @@ let BASE_SHA;
reportFailure(mainBranchName);
return;
} else {
process.stdout.write('\n');
process.stdout.write(`WARNING: Unable to find a successful workflow run on 'origin/${mainBranchName}'\n`);
process.stdout.write(`We are therefore defaulting to use HEAD~1 on 'origin/${mainBranchName}'\n`);
process.stdout.write('\n');
process.stdout.write(`NOTE: You can instead make this a hard error by setting 'error-on-no-successful-workflow' on the action in your workflow.\n`);
core.warning('\n');
core.warning(`WARNING: Unable to find a successful workflow run on 'origin/${mainBranchName}'\n`);
core.warning(`We are therefore defaulting to use HEAD~1 on 'origin/${mainBranchName}'\n`);
core.warning('\n');
core.warning(`NOTE: You can instead make this a hard error by setting 'error-on-no-successful-workflow' on the action in your workflow.\n`);

BASE_SHA = execSync(`git rev-parse HEAD~1`, { encoding: 'utf-8' });
core.setOutput('noPreviousBuild', 'true');
}
} else {
process.stdout.write('\n');
process.stdout.write(`Found the last successful workflow run on 'origin/${mainBranchName}'\n`);
process.stdout.write(`Commit: ${BASE_SHA}\n`);
core.info('\n');
core.info(`Found the last successful workflow run on 'origin/${mainBranchName}'\n`);
core.info(`Commit: ${BASE_SHA}\n`);
}
}

Expand Down Expand Up @@ -62883,8 +62882,8 @@ async function findSuccessfulCommit(workflow_id, run_id, owner, repo, branch, la
branch,
run_id
}).then(({ data: { workflow_id } }) => workflow_id);
process.stdout.write('\n');
process.stdout.write(`Workflow Id not provided. Using workflow '${workflow_id}'\n`);
core.info('\n');
core.info(`Workflow Id not provided. Using workflow '${workflow_id}'\n`);
}
// fetch all workflow runs on a given repo/branch/workflow with push and success
const shas = await octokit.request(`GET /repos/${owner}/${repo}/actions/workflows/${workflow_id}/runs`, {
Expand Down
37 changes: 18 additions & 19 deletions find-successful-workflow.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@ const { execSync } = require('child_process');
const { existsSync } = require('fs');

const { runId, repo: { repo, owner }, eventName } = github.context;
process.env.GITHUB_TOKEN = process.argv[2];
const mainBranchName = process.argv[3];
const errorOnNoSuccessfulWorkflow = process.argv[4];
const lastSuccessfulEvent = process.argv[5];
const workingDirectory = process.argv[6];
const workflowId = process.argv[7];
const mainBranchName = core.getInput('main-branch-name');
const errorOnNoSuccessfulWorkflow = core.getInput('error-on-no-successful-workflow');
const lastSuccessfulEvent = core.getInput('last-successful-event');
const workingDirectory = core.getInput('working-directory');
const workflowId = core.getInput('workflow-id');
const defaultWorkingDirectory = '.';

let BASE_SHA;
Expand All @@ -19,15 +18,15 @@ let BASE_SHA;
if (existsSync(workingDirectory)) {
process.chdir(workingDirectory);
} else {
process.stdout.write('\n');
process.stdout.write(`WARNING: Working directory '${workingDirectory}' doesn't exist.\n`);
core.warning('\n');
core.warning(`WARNING: Working directory '${workingDirectory}' doesn't exist.\n`);
}
}

const HEAD_SHA = execSync(`git rev-parse HEAD`, { encoding: 'utf-8' });

if (eventName === 'pull_request') {
BASE_SHA = execSync(`git merge-base origin/${mainBranchName} HEAD`, { encoding: 'utf-8' });
BASE_SHA = execSync(`git merge-base origin/"${mainBranchName}" HEAD`, { encoding: 'utf-8' });
} else {
try {
BASE_SHA = await findSuccessfulCommit(workflowId, runId, owner, repo, mainBranchName, lastSuccessfulEvent);
Expand All @@ -41,19 +40,19 @@ let BASE_SHA;
reportFailure(mainBranchName);
return;
} else {
process.stdout.write('\n');
process.stdout.write(`WARNING: Unable to find a successful workflow run on 'origin/${mainBranchName}'\n`);
process.stdout.write(`We are therefore defaulting to use HEAD~1 on 'origin/${mainBranchName}'\n`);
process.stdout.write('\n');
process.stdout.write(`NOTE: You can instead make this a hard error by setting 'error-on-no-successful-workflow' on the action in your workflow.\n`);
core.warning('\n');
core.warning(`WARNING: Unable to find a successful workflow run on 'origin/${mainBranchName}'\n`);
core.warning(`We are therefore defaulting to use HEAD~1 on 'origin/${mainBranchName}'\n`);
core.warning('\n');
core.warning(`NOTE: You can instead make this a hard error by setting 'error-on-no-successful-workflow' on the action in your workflow.\n`);

BASE_SHA = execSync(`git rev-parse HEAD~1`, { encoding: 'utf-8' });
core.setOutput('noPreviousBuild', 'true');
}
} else {
process.stdout.write('\n');
process.stdout.write(`Found the last successful workflow run on 'origin/${mainBranchName}'\n`);
process.stdout.write(`Commit: ${BASE_SHA}\n`);
core.info('\n');
core.info(`Found the last successful workflow run on 'origin/${mainBranchName}'\n`);
core.info(`Commit: ${BASE_SHA}\n`);
}
}

Expand Down Expand Up @@ -90,8 +89,8 @@ async function findSuccessfulCommit(workflow_id, run_id, owner, repo, branch, la
branch,
run_id
}).then(({ data: { workflow_id } }) => workflow_id);
process.stdout.write('\n');
process.stdout.write(`Workflow Id not provided. Using workflow '${workflow_id}'\n`);
core.info('\n');
core.info(`Workflow Id not provided. Using workflow '${workflow_id}'\n`);
}
// fetch all workflow runs on a given repo/branch/workflow with push and success
const shas = await octokit.request(`GET /repos/${owner}/${repo}/actions/workflows/${workflow_id}/runs`, {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"private": true,
"version": "2.2.5",
"version": "2.2.6",
"license": "MIT",
"description": "This package.json is here purely to control the version of the Action, in combination with https://github.com/JamesHenry/publish-shell-action",
"scripts": {
Expand Down

0 comments on commit c1bcacc

Please sign in to comment.