Skip to content

Commit

Permalink
Merge GitHub reporting repository defaults with custom GitHub reporti…
Browse files Browse the repository at this point in the history
…ng configuration (#86)

* Merge GitHub reporting repository defaults with custom GitHub reporting configuration

Report GitHub configuration is merged with the default GitHub reporting configuration from the action context:
```
github:
  username: GITHUB_ACTOR,
  owner: GITHUB_REPOSITORY_OWNER,
  token,
  "project-name": GITHUB_REPOSITORY,
```

Before the default github reporting function was used and did not
take the custom configuration into account. Especially the duplication
detection and the severity as label was not used when set the github-report flag.

Signed-off-by: fisehara <[email protected]>

* typo

---------

Signed-off-by: fisehara <[email protected]>
Co-authored-by: Ramana Reddy <[email protected]>
  • Loading branch information
fisehara and RamanaReddy0M authored Jun 29, 2024
1 parent e57beb0 commit 739e112
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 54 deletions.
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ jobs:
report-config: issues.yaml
```
**GitHub Example Action running Nuclei with GitHub Issue reporting**
Setting permissions for `GITHUB_TOKEN`, according to the [github actions docs](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token).
Expand All @@ -130,6 +132,42 @@ permissions:
github-token: ${{ secrets.GITHUB_TOKEN }}
```

Using the `github-report` creates a default configuration to enable reporting to Github Issues


**GitHub Example Action running Nuclei with custom GitHub Issue reporting**

```yaml
- name: Nuclei - Vulnerability Scan
uses: projectdiscovery/nuclei-action@main
with:
target: https://example.com
report-config: github-issue-config.yaml
github-token: ${{ secrets.GITHUB_TOKEN }}
```

Create a `yaml` file to define the nuclei github issue reporting behavior:

```yaml
github:
duplicate-issue-check: true
severity-as-label: true
issue-label: '<Nuclei Scan Vulnerability>'
```

The `nuclie-action` will fill in the repository settings into the custom configuration. The file don't need to be augmented with these information manually.

```yaml
github:
username: GITHUB_ACTOR,
owner: GITHUB_REPOSITORY_OWNER,
token,
"project-name": GITHUB_REPOSITORY,
```




**GitHub Example Action running Nuclei with GitHub Security Dashboard reporting**

```yaml
Expand Down
68 changes: 41 additions & 27 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10747,24 +10747,35 @@ const GITHUB_REPOSITORY_OWNER = process.env.GITHUB_REPOSITORY_OWNER;
const GITHUB_REPOSITORY = process.env.GITHUB_REPOSITORY.replace(`${GITHUB_REPOSITORY_OWNER}/`, '');
const GITHUB_WORKSPACE = process.env.GITHUB_WORKSPACE;

async function generateGithubReportFile(token) {
const content = {
"github" : {
"username": GITHUB_ACTOR,
"owner": GITHUB_REPOSITORY_OWNER,
token,
"project-name": GITHUB_REPOSITORY,
"issue-label": "Nuclei Report"
}
async function generateGithubReportFile(token, reportConfigFileName = 'github-report.yaml') {
const gitHubRepoConfig = {
username: GITHUB_ACTOR,
owner: GITHUB_REPOSITORY_OWNER,
token,
"project-name": GITHUB_REPOSITORY,
};

let content = {};

if (reportConfigFileName) {
try {
const data = await external_fs_.promises.readFile(external_path_.join(GITHUB_WORKSPACE, reportConfigFileName), 'utf8');
const { github, ...rest } = load(data);
content = { ...rest, github: { ...gitHubRepoConfig, ...github } };
} catch (err) {
throw new Error(`Error reading the passed report config file: ${err.message}`);
}
const githubConfigYml = dump(content, {
flowLevel: 3
});
} else {
content.github = gitHubRepoConfig;
}

external_fs_.writeFileSync(external_path_.join(GITHUB_WORKSPACE, 'github-report.yaml'), githubConfigYml, err => {
if (err)
reject(err);
});
const githubConfigYml = dump(content, { flowLevel: 3 });

try {
await external_fs_.promises.writeFile(external_path_.join(GITHUB_WORKSPACE, reportConfigFileName), githubConfigYml);
} catch (err) {
throw new Error(`Error writing the report config file: ${err.message}`);
}
}
;// CONCATENATED MODULE: ./src/utils.js
function parseFlagsToArray(rawFlags) {
Expand Down Expand Up @@ -10813,9 +10824,9 @@ options.listeners = {
};

async function run() {
try {
// download and install
const binPath = await downloadAndInstall(nucleiVersion);
try {
// download and install
const binPath = await downloadAndInstall(nucleiVersion);
const params = [];

if (!target && !urls) {
Expand All @@ -10831,35 +10842,38 @@ async function run() {
new URL(templates)
params.push(`-turl=${templates}`);
}
catch(_) {
catch (_) {
params.push(`-t=${templates}`);
}
}
if (workflows) params.push(`-w=${workflows}`);
params.push(`-se=${sarifExport ? sarifExport : 'nuclei.sarif'}`);
if (markdownExport) params.push(`-me=${markdownExport}`);
if (reportConfig) params.push(`-rc=${reportConfig}`);
if (config) params.push(`-config=${config}`);
if (userAgent) params.push(`-H=${userAgent}`);
params.push(`-o=${ output ? output : 'nuclei.log' }`);
params.push(`-o=${output ? output : 'nuclei.log'}`);
if (src_json) params.push('-json');
if (includeRR) params.push('-irr');
if (omitRaw) params.push('-or');

if (flags) params.push(...parseFlagsToArray(flags));

// If everything is fine and github-report is set, generate the yaml config file.
if (githubReport) {
if (githubReport == true) {
// create default config file with name `github-report.yaml`
await generateGithubReportFile(githubToken);
params.push(`-rc=github-report.yaml`);
} else if (reportConfig != null) {
await generateGithubReportFile(githubToken, reportConfig);
params.push(`-rc=${reportConfig}`);
}

// run tool
// run tool
delete process.env.GITHUB_TOKEN
exec.exec(binPath, params, options);
} catch (error) {
core.setFailed(error.message);
}
} catch (error) {
core.setFailed(error.message);
}
}

run();
Expand Down
25 changes: 14 additions & 11 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ options.listeners = {
};

async function run() {
try {
// download and install
const binPath = await installer.downloadAndInstall(nucleiVersion);
try {
// download and install
const binPath = await installer.downloadAndInstall(nucleiVersion);
const params = [];

if (!target && !urls) {
Expand All @@ -57,35 +57,38 @@ async function run() {
new URL(templates)
params.push(`-turl=${templates}`);
}
catch(_) {
catch (_) {
params.push(`-t=${templates}`);
}
}
if (workflows) params.push(`-w=${workflows}`);
params.push(`-se=${sarifExport ? sarifExport : 'nuclei.sarif'}`);
if (markdownExport) params.push(`-me=${markdownExport}`);
if (reportConfig) params.push(`-rc=${reportConfig}`);
if (config) params.push(`-config=${config}`);
if (userAgent) params.push(`-H=${userAgent}`);
params.push(`-o=${ output ? output : 'nuclei.log' }`);
params.push(`-o=${output ? output : 'nuclei.log'}`);
if (json) params.push('-json');
if (includeRR) params.push('-irr');
if (omitRaw) params.push('-or');

if (flags) params.push(...parseFlagsToArray(flags));

// If everything is fine and github-report is set, generate the yaml config file.
if (githubReport) {
if (githubReport == true) {
// create default config file with name `github-report.yaml`
await generateGithubReportFile(githubToken);
params.push(`-rc=github-report.yaml`);
} else if (reportConfig != null) {
await generateGithubReportFile(githubToken, reportConfig);
params.push(`-rc=${reportConfig}`);
}

// run tool
// run tool
delete process.env.GITHUB_TOKEN
exec.exec(binPath, params, options);
} catch (error) {
core.setFailed(error.message);
}
} catch (error) {
core.setFailed(error.message);
}
}

run();
43 changes: 27 additions & 16 deletions src/yaml.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,33 @@ const GITHUB_REPOSITORY_OWNER = process.env.GITHUB_REPOSITORY_OWNER;
const GITHUB_REPOSITORY = process.env.GITHUB_REPOSITORY.replace(`${GITHUB_REPOSITORY_OWNER}/`, '');
const GITHUB_WORKSPACE = process.env.GITHUB_WORKSPACE;

export async function generateGithubReportFile(token) {
const content = {
"github" : {
"username": GITHUB_ACTOR,
"owner": GITHUB_REPOSITORY_OWNER,
token,
"project-name": GITHUB_REPOSITORY,
"issue-label": "Nuclei Report"
}
export async function generateGithubReportFile(token, reportConfigFileName = 'github-report.yaml') {
const gitHubRepoConfig = {
username: GITHUB_ACTOR,
owner: GITHUB_REPOSITORY_OWNER,
token,
"project-name": GITHUB_REPOSITORY,
};

let content = {};

if (reportConfigFileName) {
try {
const data = await fs.promises.readFile(path.join(GITHUB_WORKSPACE, reportConfigFileName), 'utf8');
const { github, ...rest } = yaml.load(data);
content = { ...rest, github: { ...gitHubRepoConfig, ...github } };
} catch (err) {
throw new Error(`Error reading the passed report config file: ${err.message}`);
}
const githubConfigYml = yaml.dump(content, {
flowLevel: 3
});
} else {
content.github = gitHubRepoConfig;
}

const githubConfigYml = yaml.dump(content, { flowLevel: 3 });

fs.writeFileSync(path.join(GITHUB_WORKSPACE, 'github-report.yaml'), githubConfigYml, err => {
if (err)
reject(err);
});
try {
await fs.promises.writeFile(path.join(GITHUB_WORKSPACE, reportConfigFileName), githubConfigYml);
} catch (err) {
throw new Error(`Error writing the report config file: ${err.message}`);
}
}

0 comments on commit 739e112

Please sign in to comment.