Skip to content

Commit a753d63

Browse files
authored
Merge pull request #88 from lazy-actions/feat/use-template-option
Support trivy template option
2 parents 45ac207 + 63e138a commit a753d63

File tree

11 files changed

+149
-349
lines changed

11 files changed

+149
-349
lines changed

.prettierrc.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
semi: true
22
singleQuote: true
3-
trailingComma: es5
3+
trailingComma: none
44
parser": typescript
55
bracketSpacing: true

README.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ If vulnerabilities are found by Trivy, it creates the following GitHub Issue.
1111

1212
![image](./assets/img/issue.png)
1313

14-
## Usage
15-
16-
### Inputs
14+
## Inputs
1715

1816
|Parameter|Required|Default Value|Description|
1917
|:--:|:--:|:--:|:--|
@@ -22,21 +20,21 @@ If vulnerabilities are found by Trivy, it creates the following GitHub Issue.
2220
|severity|False|HIGH,CRITICAL|Severities of vulnerabilities (separated by commma)|
2321
|vuln_type|False|os,library|Scan target are os and / or library (separated by commma)|
2422
|ignore_unfixed|False|false|Ignore unfixed vulnerabilities<br>Please specify `true` or `false`|
25-
|issue|False|true|Decide whether creating issue when vulnerabilities are found by trivy.<br>Please specify `true` or `false`|
26-
|token|True if issue parameter is true else False|N/A|GitHub Access Token.<br>${{ secrets.GITHUB_TOKEN }} is recommended.|
23+
|template|False|N/A|Trivy --template option<br>By default, it uses src/template/default.tpl which is based on [contrib/html.tpl](https://github.com/aquasecurity/trivy/blob/main/contrib/html.tpl)<br>reference: [Report Formats - Trivy](https://aquasecurity.github.io/trivy/v0.18.3/examples/report/#template)|
24+
|token|True|N/A|GitHub Access Token.<br>${{ secrets.GITHUB_TOKEN }} is recommended.|
2725
|issue_title|False|Security Alert|Issue title|
2826
|issue_label|False|trivy,vulnerability|Issue label (separated by commma)|
2927
|issue_assignee|False|N/A|Issue assignee (separated by commma)|
3028
|fail_on_vulnerabilities|False|false|Whether the action should fail if any vulnerabilities were found.|
3129

32-
### Outputs
30+
## Outputs
3331

3432
|Parameter|Description|
3533
|:--:|:--|
3634
|html_url|The URL to view the issue|
3735
|issue_number|The created issue number|
3836

39-
## Example Workflow
37+
## Example
4038

4139
Detect your docker image vulnerability everyday at 9:00 (UTC).
4240

@@ -55,7 +53,7 @@ jobs:
5553
- name: Pull docker image
5654
run: docker pull sample
5755

58-
- uses: lazy-actions/gitrivy@main
56+
- uses: lazy-actions/gitrivy@v2
5957
with:
6058
token: ${{ secrets.GITHUB_TOKEN }}
6159
image: sample

__tests__/downloader.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,23 @@ describe('Trivy command', () => {
9797
expect(result).toBeFalsy();
9898
});
9999
});
100+
101+
describe('Exists trivy command', () => {
102+
beforeAll(() => {
103+
fs.writeFileSync('./trivy', '');
104+
});
105+
106+
afterAll(() => {
107+
removeTrivyCmd('.');
108+
});
109+
110+
test('exists', () => {
111+
const result = downloader.trivyExists('.');
112+
expect(result).toBeTruthy();
113+
});
114+
115+
test('does not exist', () => {
116+
const result = downloader.trivyExists('src');
117+
expect(result).toBeFalsy();
118+
});
119+
});

__tests__/trivy.test.ts

Lines changed: 13 additions & 188 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,15 @@
1-
import * as fs from 'fs';
1+
import * as path from 'path';
22
import { Downloader } from '../src/downloader';
3-
import { Trivy } from '../src/trivy';
4-
import { Vulnerability, TrivyOption } from '../src/interface';
3+
import { scan } from '../src/trivy';
4+
import { TrivyOption } from '../src/interface';
55
import { removeTrivyCmd } from './helper';
66

77
const downloader = new Downloader();
8-
const trivy = new Trivy();
9-
10-
describe('Trivy command', () => {
11-
beforeAll(() => {
12-
fs.writeFileSync('./trivy', '');
13-
});
14-
15-
afterAll(() => {
16-
removeTrivyCmd('.');
17-
});
18-
19-
test('exists', () => {
20-
const result = downloader.trivyExists('.');
21-
expect(result).toBeTruthy();
22-
});
23-
24-
test('does not exist', () => {
25-
const result = downloader.trivyExists('src');
26-
expect(result).toBeFalsy();
27-
});
28-
});
8+
const template = path.join(__dirname, '../src/template/default.tpl');
299

3010
describe('Trivy scan', () => {
3111
let trivyPath: string;
32-
const image: string = 'alpine:3.10';
12+
const image = 'knqyf263/vuln-image';
3313

3414
beforeAll(async () => {
3515
trivyPath = !downloader.trivyExists(__dirname)
@@ -46,58 +26,32 @@ describe('Trivy scan', () => {
4626
severity: 'HIGH,CRITICAL',
4727
vulnType: 'os,library',
4828
ignoreUnfixed: true,
49-
format: 'json',
29+
template
5030
};
51-
const result: Vulnerability[] | string = trivy.scan(
52-
trivyPath,
53-
image,
54-
option
55-
);
31+
const result = scan(trivyPath, image, option) as string;
5632
expect(result.length).toBeGreaterThanOrEqual(1);
57-
expect(result).toBeInstanceOf(Object);
5833
});
5934

6035
test('without ignoreUnfixed', () => {
6136
const option: TrivyOption = {
6237
severity: 'HIGH,CRITICAL',
6338
vulnType: 'os,library',
6439
ignoreUnfixed: false,
65-
format: 'json',
40+
template
6641
};
67-
const result: Vulnerability[] | string = trivy.scan(
68-
trivyPath,
69-
image,
70-
option
71-
);
42+
const result: string = scan(trivyPath, image, option) as string;
7243
expect(result.length).toBeGreaterThanOrEqual(1);
73-
expect(result).toBeInstanceOf(Object);
74-
});
75-
76-
test('with table format', () => {
77-
const option: TrivyOption = {
78-
severity: 'HIGH,CRITICAL',
79-
vulnType: 'os,library',
80-
ignoreUnfixed: false,
81-
format: 'table',
82-
};
83-
const result: Vulnerability[] | string = trivy.scan(
84-
trivyPath,
85-
image,
86-
option
87-
);
88-
expect(result.length).toBeGreaterThanOrEqual(1);
89-
expect(result).toMatch(/alpine:3\.10/);
9044
});
9145

9246
test('with invalid severity', () => {
9347
const invalidOption: TrivyOption = {
9448
severity: 'INVALID',
9549
vulnType: 'os,library',
9650
ignoreUnfixed: true,
97-
format: 'json',
51+
template
9852
};
9953
expect(() => {
100-
trivy.scan(trivyPath, image, invalidOption);
54+
scan(trivyPath, image, invalidOption);
10155
}).toThrowError('Trivy option error: INVALID is unknown severity');
10256
});
10357

@@ -106,139 +60,10 @@ describe('Trivy scan', () => {
10660
severity: 'HIGH',
10761
vulnType: 'INVALID',
10862
ignoreUnfixed: true,
109-
format: 'json',
63+
template
11064
};
11165
expect(() => {
112-
trivy.scan(trivyPath, image, invalidOption);
66+
scan(trivyPath, image, invalidOption);
11367
}).toThrowError('Trivy option error: INVALID is unknown vuln-type');
11468
});
11569
});
116-
117-
describe('Parse', () => {
118-
const image: string = 'alpine:3.10';
119-
120-
test('the result without vulnerabilities', () => {
121-
const vulnerabilities: Vulnerability[] = [
122-
{
123-
Target: 'alpine:3.10 (alpine 3.10.3)',
124-
Vulnerabilities: null,
125-
},
126-
];
127-
const result = trivy.parse(image, vulnerabilities);
128-
expect(result).toBe('');
129-
});
130-
131-
test('the result including vulnerabilities', () => {
132-
const vulnerabilities: Vulnerability[] = [
133-
{
134-
Target: 'alpine:3.9 (alpine 3.9.4)',
135-
Vulnerabilities: [
136-
{
137-
VulnerabilityID: 'CVE-2019-14697',
138-
PkgName: 'musl',
139-
InstalledVersion: '1.1.20-r4',
140-
FixedVersion: '1.1.20-r5',
141-
Description:
142-
"musl libc through 1.1.23 has an x87 floating-point stack adjustment imbalance, related to the math/i386/ directory. In some cases, use of this library could introduce out-of-bounds writes that are not present in an application's source code.",
143-
Severity: 'HIGH',
144-
References: [
145-
'http://www.openwall.com/lists/oss-security/2019/08/06/4',
146-
'https://www.openwall.com/lists/musl/2019/08/06/1',
147-
],
148-
},
149-
{
150-
VulnerabilityID: 'CVE-2019-1549',
151-
PkgName: 'openssl',
152-
InstalledVersion: '1.1.1b-r1',
153-
FixedVersion: '1.1.1d-r0',
154-
Title: 'openssl: information disclosure in fork()',
155-
Description:
156-
'OpenSSL 1.1.1 introduced a rewritten random number generator (RNG). This was intended to include protection in the event of a fork() system call in order to ensure that the parent and child processes did not share the same RNG state. However this protection was not being used in the default case. A partial mitigation for this issue is that the output from a high precision timer is mixed into the RNG state so the likelihood of a parent and child process sharing state is significantly reduced. If an application already calls OPENSSL_init_crypto() explicitly using OPENSSL_INIT_ATFORK then this problem does not occur at all. Fixed in OpenSSL 1.1.1d (Affected 1.1.1-1.1.1c).',
157-
Severity: 'MEDIUM',
158-
References: [
159-
'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1549',
160-
'https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=1b0fe00e2704b5e20334a16d3c9099d1ba2ef1be',
161-
'https://lists.fedoraproject.org/archives/list/[email protected]/message/GY6SNRJP2S7Y42GIIDO3HXPNMDYN2U3A/',
162-
'https://security.netapp.com/advisory/ntap-20190919-0002/',
163-
'https://support.f5.com/csp/article/K44070243',
164-
'https://www.openssl.org/news/secadv/20190910.txt',
165-
],
166-
},
167-
],
168-
},
169-
];
170-
const result = trivy.parse(image, vulnerabilities);
171-
expect(result).toMatch(
172-
/\|Title\|Severity\|CVE\|Package Name\|Installed Version\|Fixed Version\|References\|/
173-
);
174-
expect(result).toContain(image);
175-
});
176-
});
177-
178-
describe('Validate trivy option', () => {
179-
test('with a valid severity', () => {
180-
const options: string[] = ['HIGH'];
181-
const result = trivy['validateSeverity'](options);
182-
expect(result).toBeTruthy();
183-
});
184-
185-
test('with two valid severities', () => {
186-
const options: string[] = ['HIGH', 'CRITICAL'];
187-
const result = trivy['validateSeverity'](options);
188-
expect(result).toBeTruthy();
189-
});
190-
191-
test('with an invalid severity', () => {
192-
const options: string[] = ['INVALID'];
193-
expect(() => {
194-
trivy['validateSeverity'](options);
195-
}).toThrowError('Trivy option error: INVALID is unknown severity');
196-
});
197-
198-
test('with two invalid severities', () => {
199-
const options: string[] = ['INVALID', 'ERROR'];
200-
expect(() => {
201-
trivy['validateSeverity'](options);
202-
}).toThrowError('Trivy option error: INVALID,ERROR is unknown severity');
203-
});
204-
205-
test('with an invalid and a valid severities', () => {
206-
const options: string[] = ['INVALID', 'HIGH'];
207-
expect(() => {
208-
trivy['validateSeverity'](options);
209-
}).toThrowError('Trivy option error: INVALID,HIGH is unknown severity');
210-
});
211-
212-
test('with a valid vuln-type', () => {
213-
const options: string[] = ['os'];
214-
const result = trivy['validateVulnType'](options);
215-
expect(result).toBeTruthy();
216-
});
217-
218-
test('with two valid vuln-types', () => {
219-
const options: string[] = ['os', 'library'];
220-
const result = trivy['validateVulnType'](options);
221-
expect(result).toBeTruthy();
222-
});
223-
224-
test('with an invalid vuln-type', () => {
225-
const options: string[] = ['INVALID'];
226-
expect(() => {
227-
trivy['validateVulnType'](options);
228-
}).toThrowError('Trivy option error: INVALID is unknown vuln-type');
229-
});
230-
231-
test('with two invalid vuln-types', () => {
232-
const options: string[] = ['INVALID', 'ERROR'];
233-
expect(() => {
234-
trivy['validateVulnType'](options);
235-
}).toThrowError('Trivy option error: INVALID,ERROR is unknown vuln-type');
236-
});
237-
238-
test('with a valid and an invalid vuln-types', () => {
239-
const options: string[] = ['INVALID', 'os'];
240-
expect(() => {
241-
trivy['validateVulnType'](options);
242-
}).toThrowError('Trivy option error: INVALID,os is unknown vuln-type');
243-
});
244-
});

__tests__/utils.test.ts

Lines changed: 0 additions & 12 deletions
This file was deleted.

action.yml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,12 @@ inputs:
2121
description: 'Ignore unfixed vulnerabilities [true, false]'
2222
default: 'false'
2323
required: false
24-
issue:
25-
description: 'Decide whether to create a issue when vulnerabilities are found [true, false]'
26-
default: 'true'
27-
required: false
24+
template:
25+
description: 'Trivy --template option'
26+
required: false
2827
token:
2928
description: 'GitHub access token used to create a issue'
30-
required: false
29+
required: true
3130
issue_title:
3231
description: 'Issue title'
3332
default: 'Security Alert'

0 commit comments

Comments
 (0)