Skip to content
This repository was archived by the owner on Jul 18, 2025. It is now read-only.

Commit ca157da

Browse files
authored
Merge pull request #132 from docker/add-severity-threshold-tag
add support of --severity-threshold Snyk flag
2 parents 5c8ee91 + 6f22854 commit ca157da

5 files changed

Lines changed: 94 additions & 0 deletions

File tree

README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,45 @@ Licenses: enabled
221221

222222
Tested 200 dependencies for known issues, found 157 issues.
223223
```
224+
If you want to only display some level of vulnerabilities, the `--severity` flag allows you to choose between 3 levels of
225+
vulnerabilities `low`,`medium` or `high`. By using this tag you will only report vulnerabilities of the provided level
226+
or higher.
227+
228+
```console
229+
$ docker scan --severity=medium docker-scan:e2e
230+
./bin/docker-scan_darwin_amd64 scan --severity=medium docker-scan:e2e
231+
232+
Testing docker-scan:e2e...
233+
234+
✗ Medium severity vulnerability found in sqlite3/libsqlite3-0
235+
Description: Divide By Zero
236+
Info: https://snyk.io/vuln/SNYK-DEBIAN10-SQLITE3-466337
237+
Introduced through: gnupg2/gnupg@2.2.12-1+deb10u1, subversion@1.10.4-1+deb10u1, mercurial@4.8.2-1+deb10u1
238+
From: gnupg2/gnupg@2.2.12-1+deb10u1 > gnupg2/gpg@2.2.12-1+deb10u1 > sqlite3/libsqlite3-0@3.27.2-3
239+
From: subversion@1.10.4-1+deb10u1 > subversion/libsvn1@1.10.4-1+deb10u1 > sqlite3/libsqlite3-0@3.27.2-3
240+
From: mercurial@4.8.2-1+deb10u1 > python-defaults/python@2.7.16-1 > python2.7@2.7.16-2+deb10u1 > python2.7/libpython2.7-stdlib@2.7.16-2+deb10u1 > sqlite3/libsqlite3-0@3.27.2-3
241+
242+
✗ Medium severity vulnerability found in sqlite3/libsqlite3-0
243+
Description: Uncontrolled Recursion
244+
...
245+
✗ High severity vulnerability found in binutils/binutils-common
246+
Description: Missing Release of Resource after Effective Lifetime
247+
Info: https://snyk.io/vuln/SNYK-DEBIAN10-BINUTILS-403318
248+
Introduced through: gcc-defaults/g++@4:8.3.0-1
249+
From: gcc-defaults/g++@4:8.3.0-1 > gcc-defaults/gcc@4:8.3.0-1 > gcc-8@8.3.0-6 > binutils@2.31.1-16 > binutils/binutils-common@2.31.1-16
250+
From: gcc-defaults/g++@4:8.3.0-1 > gcc-defaults/gcc@4:8.3.0-1 > gcc-8@8.3.0-6 > binutils@2.31.1-16 > binutils/libbinutils@2.31.1-16 > binutils/binutils-common@2.31.1-16
251+
From: gcc-defaults/g++@4:8.3.0-1 > gcc-defaults/gcc@4:8.3.0-1 > gcc-8@8.3.0-6 > binutils@2.31.1-16 > binutils/binutils-x86-64-linux-gnu@2.31.1-16 > binutils/binutils-common@2.31.1-16
252+
and 4 more...
253+
254+
Organization: docker-desktop-test
255+
Package manager: deb
256+
Project name: docker-image|docker-scan
257+
Docker image: docker-scan:e2e
258+
Platform: linux/amd64
259+
Licenses: enabled
260+
261+
Tested 200 dependencies for known issues, found 37 issues.
262+
```
224263

225264
If your image has unfixed issues, and you need to bypass the error code, you can use the `--fail-on` flag.
226265
```console

cmd/docker-scan/main.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ type options struct {
7070
forceOptIn bool
7171
forceOptOut bool
7272
failOn string
73+
severity string
7374
}
7475

7576
func newScanCmd(ctx context.Context, dockerCli command.Cli) *cobra.Command {
@@ -99,6 +100,7 @@ func newScanCmd(ctx context.Context, dockerCli command.Cli) *cobra.Command {
99100
cmd.Flags().BoolVar(&flags.forceOptIn, "accept-license", false, "Accept using a third party scanning provider")
100101
cmd.Flags().BoolVar(&flags.forceOptOut, "reject-license", false, "Reject using a third party scanning provider")
101102
cmd.Flags().StringVar(&flags.failOn, "fail-on", "", "Only fail when there are vulnerabilities that can be fixed (all|upgradable|patchable)")
103+
cmd.Flags().StringVar(&flags.severity, "severity", "", "Only report vulnerabilities of provided level or higher (low|medium|high)")
102104

103105
return cmd
104106
}
@@ -134,6 +136,12 @@ func configureProvider(ctx context.Context, dockerCli command.Streams, flags opt
134136
}
135137
opts = append(opts, provider.WithFailOn(flags.failOn))
136138
}
139+
if flags.severity != "" {
140+
if flags.severity != "low" && flags.severity != "medium" && flags.severity != "high" {
141+
return nil, fmt.Errorf("--severity takes only 'low', 'medium' or 'high' values")
142+
}
143+
opts = append(opts, provider.WithSeverity(flags.severity))
144+
}
137145
return provider.NewSnykProvider(opts...)
138146
}
139147

e2e/scan_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,43 @@ func TestScanWithFailOnBadValue(t *testing.T) {
297297
Err: "--fail-on takes only 'all', 'upgradable' or 'patchable' values"})
298298
}
299299

300+
func TestScanWithSeverity(t *testing.T) {
301+
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
302+
t.Skip("Can't run on this ci platform (windows containers or no engine installed)")
303+
}
304+
_, cleanFunction := createSnykConfFile(t, os.Getenv("E2E_TEST_AUTH_TOKEN"))
305+
defer cleanFunction()
306+
307+
cmd, configDir, cleanup := dockerCli.createTestCmd()
308+
defer cleanup()
309+
310+
createScanConfigFile(t, configDir)
311+
312+
cmd.Command = dockerCli.Command("scan", "--accept-license", "--severity=medium", ImageWithVulnerabilities)
313+
output := icmd.RunCmd(cmd).Assert(t, icmd.Expected{ExitCode: 1}).Combined()
314+
assert.Assert(t, strings.Contains(output, "alpine:3.10.0")) // beginning of the dependency tree
315+
assert.Assert(t, cmp.Regexp("found .* issues", output))
316+
assert.Assert(t, !strings.Contains(output, "Low severity"))
317+
}
318+
319+
func TestScanWithSeverityBadValue(t *testing.T) {
320+
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
321+
t.Skip("Can't run on this ci platform (windows containers or no engine installed)")
322+
}
323+
_, cleanFunction := createSnykConfFile(t, os.Getenv("E2E_TEST_AUTH_TOKEN"))
324+
defer cleanFunction()
325+
326+
cmd, configDir, cleanup := dockerCli.createTestCmd()
327+
defer cleanup()
328+
329+
createScanConfigFile(t, configDir)
330+
331+
cmd.Command = dockerCli.Command("scan", "--accept-license", "--severity=unsupportedValue", ImageWithVulnerabilities)
332+
icmd.RunCmd(cmd).Assert(t, icmd.Expected{
333+
ExitCode: 1,
334+
Err: "--severity takes only 'low', 'medium' or 'high' values"})
335+
}
336+
300337
func createSnykConfFile(t *testing.T, token string) (*fs.Dir, func()) {
301338
content := fmt.Sprintf(`{"api" : "%s"}`, token)
302339
homeDir := fs.NewDir(t, t.Name(),

e2e/testdata/plugin-usage.golden

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Options:
1717
optional token (with --token), or web base
1818
token if empty
1919
--reject-license Reject using a third party scanning provider
20+
--severity string Only report vulnerabilities of provided level
21+
or higher (low|medium|high)
2022
--token string Authentication token to login to the third
2123
party scanning provider
2224
--version Display version of the scan plugin

internal/provider/snyk.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,14 @@ func WithFailOn(failOn string) SnykProviderOps {
144144
}
145145
}
146146

147+
// WithSeverity only reports vulnerabilities of the provided level or higher
148+
func WithSeverity(severity string) SnykProviderOps {
149+
return func(provider *snykProvider) error {
150+
provider.flags = append(provider.flags, "--severity-threshold="+severity)
151+
return nil
152+
}
153+
}
154+
147155
func (s *snykProvider) Authenticate(token string) error {
148156
if token != "" {
149157
if _, err := uuid.Parse(token); err != nil {

0 commit comments

Comments
 (0)