Skip to content

Commit 110345a

Browse files
committed
Allow scanning orgs
1 parent 671eeb8 commit 110345a

File tree

6 files changed

+59
-39
lines changed

6 files changed

+59
-39
lines changed

.github/workflows/sample.yml

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,8 @@ permissions:
77
on:
88
workflow_dispatch:
99
inputs:
10-
owner:
11-
description: 'Org or user name'
12-
required: true
13-
type: string
14-
repo:
15-
description: 'Repository name'
10+
owner-repo:
11+
description: 'Org or org/repo to scan'
1612
required: true
1713
type: string
1814

@@ -22,5 +18,4 @@ jobs:
2218
steps:
2319
- uses: GitHubSecurityLab/pwn-request-scanner@9791f6e2ab36a9ca92342d4b2adc749e870133b9 # v1
2420
with:
25-
owner: ${{ inputs.owner }}
26-
repo: ${{ inputs.repo }}
21+
owner-repo: ${{ inputs.owner-repo }}

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ The `pwn request scanner` is a simple tool that doesn't go into depths of analyz
1111
You can run the scanner as:
1212

1313
* GitHub Action in your repository. Just copy the [sample workflow](.github/workflows/sample.yml) or fork the repository and run the workflow from your fork.
14-
* Run `node dist/index.js <github_owner> <repo_name>` in a codespace.
14+
* Run `node dist/index.js owner/repo` or `node dist/index.js owner` in a codespace.
1515
* Locally running the [index.js](dist/index.js) script from the dist folder. Set environment variable `GITHUB_TOKEN` to your Personal Access Token (PAT).

action.yml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,8 @@ inputs:
55
description: 'GitHub token to call REST API'
66
required: false
77
default: ${{ github.token }}
8-
owner:
9-
description: 'Org or user name'
10-
required: true
11-
type: string
12-
repo:
13-
description: 'Repository name'
8+
owner-repo:
9+
description: 'Org or org/repo to scan'
1410
required: true
1511
type: string
1612

dist/index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/index.js

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
const core = require('@actions/core');
22
const github = require('@actions/github');
33
import {
4-
convertWorkflowTemplate,
5-
NoOperationTraceWriter,
6-
parseWorkflow
4+
convertWorkflowTemplate,
5+
NoOperationTraceWriter,
6+
parseWorkflow
77
} from "@actions/workflow-parser";
88

99
let verbose = false;
1010
let log = console.log;
1111
let debug = (msg) => { if (verbose) { log(msg); } }
1212

13-
async function run(owner, repo, token) {
14-
console.log("Working...");
15-
const octokit = github.getOctokit(token)
16-
17-
debug(`Listing branches for ${owner}/${repo}.`);
13+
async function run_repo(owner, repo, octokit) {
14+
console.log(`Listing branches for ${owner}/${repo}.`);
1815
const branches = await octokit.rest.repos.listBranches({
1916
owner,
2017
repo,
@@ -35,7 +32,7 @@ async function run(owner, repo, token) {
3532
continue;
3633
}
3734

38-
debug(`Checking branch ${branchName} for workflows.`);
35+
console.log(`Checking branch ${branchName} for workflows.`);
3936
let contents;
4037
try {
4138
contents = await octokit.rest.repos.getContent({
@@ -49,9 +46,9 @@ async function run(owner, repo, token) {
4946
debug(`Branch ${branchName} does not contain any workflows.`);
5047
continue;
5148
}
52-
throw(`Error: ${error.status}. Failed to retrieve contents for branch ${branchName}`, error);
49+
throw (`Error: ${error.status}. Failed to retrieve contents for branch ${branchName}`, error);
5350
}
54-
51+
5552
for (const file of contents.data) {
5653
const lowerCaseFile = file.name.toLowerCase();
5754
if (file.type === 'file' && (lowerCaseFile.endsWith('.yml') || lowerCaseFile.endsWith('.yaml'))) {
@@ -89,47 +86,79 @@ async function run(owner, repo, token) {
8986
continue;
9087
}
9188

92-
if (!found) {
89+
found = true;
90+
console.log(`https://github.com/${owner}/${repo}/blob/${branchName}/${file.path} from non-default branch uses pull_request_target`);
91+
}
92+
}
93+
}
94+
95+
return found;
96+
}
97+
98+
async function run(owner_repo, token) {
99+
const octokit = github.getOctokit(token)
100+
let found = false;
101+
let owner, repo;
102+
[owner, repo] = owner_repo.split('/');
103+
104+
if (repo === undefined) {
105+
debug(`Listing repositories for owner ${owner}.`);
106+
for await (const response of octokit.paginate.iterator(octokit.rest.repos.listForOrg, {
107+
org: owner,
108+
type: 'all',
109+
per_page: 100
110+
})) {
111+
for (const repo of response.data) {
112+
const repoFound = await run_repo(
113+
owner,
114+
repo.name,
115+
octokit
116+
);
117+
if (repoFound) {
93118
found = true;
94-
console.log('These workflows from non-default branch use pull_request_target:');
95119
}
96-
console.log(`https://github.com/${owner}/${repo}/blob/${branchName}/${file.path}`);
97120
}
98121
}
99122
}
123+
else {
124+
found = await run_repo(
125+
owner,
126+
repo,
127+
octokit
128+
);
129+
}
100130

101131
console.log(`Done. ${found ? 'Found issues.' : 'No issues found.'}`);
102132
return found;
103133
}
104134

105135
function printUsageAndExit() {
106-
console.log('Usage: node index.js <github_owner> <repo_name> [--verbose]');
107-
process.exit(1);
136+
console.log('Usage: node index.js owner/repo [--verbose]');
137+
process.exit(1);
108138
}
109139

110140
if (process.env.GITHUB_ACTIONS) {
111141
verbose = process.env.RUNNER_DEBUG ? true : false;
112-
const owner = core.getInput('owner');
113-
const repo = core.getInput('repo');
142+
const owner_repo = core.getInput('owner-repo');
114143
const token = core.getInput('token');
115144

116-
run(owner, repo, token).catch(error => {
145+
run(owner_repo, token).catch(error => {
117146
core.setFailed(error);
118147
}).then(found => {
119148
if (found) {
120149
core.warning('Workflows from non-default branches were detected to use pull_request_target. See logs for the details.');
121150
}
122151
});
123152
} else {
124-
if (process.argv.length < 4) {
153+
if (process.argv.length < 3) {
125154
printUsageAndExit();
126155
}
127156
if (process.env.GITHUB_TOKEN === undefined) {
128157
console.log('Error: GITHUB_TOKEN environment variable is not set.');
129158
process.exit(1);
130159
}
131-
verbose = process.argv.length > 4 && process.argv[4] === '--verbose' ? true : false;
132-
run(process.argv[2], process.argv[3], process.env.GITHUB_TOKEN).catch(error => {
160+
verbose = process.argv.length > 3 && process.argv[3] === '--verbose' ? true : false;
161+
run(process.argv[2], process.env.GITHUB_TOKEN).catch(error => {
133162
console.log(`Error: ${error}`);
134163
process.exit(1);
135164
});

0 commit comments

Comments
 (0)