Skip to content

Commit 64f0551

Browse files
authored
feat: Add support for failBuildOnUnusedSuppressionRule (#430)
Signed-off-by: Chad Wilson <chadw@thoughtworks.com>
1 parent e74cc96 commit 64f0551

16 files changed

+80
-79
lines changed

src/main/groovy/org/owasp/dependencycheck/gradle/extension/DependencyCheckExtension.groovy

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ class DependencyCheckExtension {
166166
* is 0.0 which means all identified vulnerabilities would be considered a failure.
167167
*/
168168
Float junitFailOnCVSS = 0.0f
169+
/**
170+
* Specifies that if any unused suppression rule is found, the build will fail.
171+
*/
172+
Boolean failBuildOnUnusedSuppressionRule = false
169173
/**
170174
* Displays a summary of the findings. Defaults to true.
171175
*/

src/main/groovy/org/owasp/dependencycheck/gradle/tasks/ConfiguredTask.groovy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ abstract class ConfiguredTask extends DefaultTask {
106106

107107
settings.setBooleanIfNotNull(DOWNLOADER_QUICK_QUERY_TIMESTAMP, config.quickQueryTimestamp)
108108
settings.setFloat(JUNIT_FAIL_ON_CVSS, config.junitFailOnCVSS)
109+
settings.setBooleanIfNotNull(FAIL_ON_UNUSED_SUPPRESSION_RULE, config.failBuildOnUnusedSuppressionRule)
109110
settings.setBooleanIfNotNull(HOSTED_SUPPRESSIONS_ENABLED, config.hostedSuppressions.enabled)
110111
settings.setBooleanIfNotNull(HOSTED_SUPPRESSIONS_FORCEUPDATE, config.hostedSuppressions.forceupdate)
111112
settings.setStringIfNotNull(HOSTED_SUPPRESSIONS_URL, config.hostedSuppressions.url)

src/test/groovy/org/owasp/dependencycheck/gradle/DependencyCheckConfigurationSelectionIntegSpec.groovy

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,20 @@ class DependencyCheckConfigurationSelectionIntegSpec extends Specification {
132132
result.task(":$ANALYZE_TASK").outcome == SUCCESS
133133
}
134134

135+
def "analysis fails when unused suppression rule is present"() {
136+
given:
137+
copyBuildFileIntoProjectDir('suppressionFilesFailOnUnusedRule.gradle')
138+
copyResourceFileIntoProjectDir('suppressions.xml', 'suppressions.xml')
139+
140+
when:
141+
def result = executeTaskAndGetResult(ANALYZE_TASK, false)
142+
143+
then:
144+
result.task(":$ANALYZE_TASK").outcome == FAILED
145+
result.output.contains('Suppression Rule had zero matches')
146+
result.output.contains('commons-collections')
147+
}
148+
135149

136150
private void copyBuildFileIntoProjectDir(String buildFileName) {
137151
copyResourceFileIntoProjectDir(buildFileName, 'build.gradle')

src/test/groovy/org/owasp/dependencycheck/gradle/DependencyCheckGradlePluginSpec.groovy

Lines changed: 25 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -97,46 +97,31 @@ class DependencyCheckGradlePluginSpec extends Specification {
9797
def slackWebhookUrl = 'https://slack.com/webhook'
9898
when:
9999
project.dependencyCheck {
100-
proxy {
101-
server = '127.0.0.1'
102-
port = 3128
103-
username = 'proxyUsername'
104-
password = 'proxyPassword'
105-
nonProxyHosts = ['localhost']
106-
}
107-
nvd {
108-
apiKey = 'apiKey'
109-
delay = 5000
110-
maxRetryCount = 20
111-
}
112-
113-
hostedSuppressions {
114-
url = 'suppressionsurl'
115-
validForHours = 5
116-
forceupdate = true
117-
}
118-
119-
slack {
120-
enabled = true
121-
webhookUrl = slackWebhookUrl
122-
}
123-
124-
analyzers {
125-
artifactory {
126-
enabled = true
127-
url = 'https://example.com/artifacgtory'
128-
bearerToken = 'abc123=='
129-
}
130-
kev {
131-
enabled = false
132-
url = "https://example.com"
133-
validForHours = 12
134-
}
135-
retirejs {
136-
filters = ['filter1', 'filter2']
137-
filterNonVulnerable = true
138-
}
139-
}
100+
proxy.server = '127.0.0.1'
101+
proxy.port = 3128
102+
proxy.username = 'proxyUsername'
103+
proxy.password = 'proxyPassword'
104+
proxy.nonProxyHosts = ['localhost']
105+
106+
nvd.apiKey = 'apiKey'
107+
nvd.delay = 5000
108+
nvd.maxRetryCount = 20
109+
110+
hostedSuppressions.url = 'suppressionsurl'
111+
hostedSuppressions.validForHours = 5
112+
hostedSuppressions.forceupdate = true
113+
114+
slack.enabled = true
115+
slack.webhookUrl = slackWebhookUrl
116+
117+
analyzers.artifactory.enabled = true
118+
analyzers.artifactory.url = 'https://example.com/artifacgtory'
119+
analyzers.artifactory.bearerToken = 'abc123=='
120+
analyzers.kev.enabled = false
121+
analyzers.kev.url = "https://example.com"
122+
analyzers.kev.validForHours = 12
123+
analyzers.retirejs.filters = ['filter1', 'filter2']
124+
analyzers.retirejs.filterNonVulnerable = true
140125

141126
outputDirectory = 'outputDirectory'
142127
quickQueryTimestamp = false

src/test/groovy/org/owasp/dependencycheck/gradle/DependencyCheckPluginIntegSpec.groovy

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,7 @@ class DependencyCheckPluginIntegSpec extends Specification {
5757
implementation group: 'commons-collections', name: 'commons-collections', version: '3.2'
5858
}
5959
dependencyCheck {
60-
nvd {
61-
datafeedUrl = 'https://jeremylong.github.io/DependencyCheck/hb_nvd/'
62-
}
60+
nvd.datafeedUrl = 'https://jeremylong.github.io/DependencyCheck/hb_nvd/'
6361
}
6462
""".stripIndent()
6563
}
@@ -100,9 +98,7 @@ class DependencyCheckPluginIntegSpec extends Specification {
10098
implementation group: 'commons-collections', name: 'commons-collections', version: '3.2'
10199
}
102100
dependencyCheck {
103-
nvd {
104-
datafeedUrl = 'https://jeremylong.github.io/DependencyCheck/hb_nvd/'
105-
}
101+
nvd.datafeedUrl = 'https://jeremylong.github.io/DependencyCheck/hb_nvd/'
106102
}
107103
""".stripIndent()
108104
}

src/test/resources/aggregateParent.gradle

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ plugins {
66
dependencyCheck {
77
failOnError=true
88
format="HTML"
9-
nvd {
10-
datafeedUrl = 'https://jeremylong.github.io/DependencyCheck/hb_nvd/'
11-
}
9+
nvd.datafeedUrl = 'https://jeremylong.github.io/DependencyCheck/hb_nvd/'
1210
}
1311

1412
subprojects {

src/test/resources/blacklistCustomConfiguration.gradle

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,5 @@ dependencies {
2222
dependencyCheck {
2323
failBuildOnCVSS = 0
2424
skipConfigurations = ['foo']
25-
nvd {
26-
datafeedUrl = 'https://jeremylong.github.io/DependencyCheck/hb_nvd/'
27-
}
25+
nvd.datafeedUrl = 'https://jeremylong.github.io/DependencyCheck/hb_nvd/'
2826
}

src/test/resources/noSkipTestGroups.gradle

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,5 @@ dependencies {
3030
dependencyCheck {
3131
failBuildOnCVSS = 0
3232
skipTestGroups = false
33-
nvd {
34-
datafeedUrl = 'https://jeremylong.github.io/DependencyCheck/hb_nvd/'
35-
}
33+
nvd.datafeedUrl = 'https://jeremylong.github.io/DependencyCheck/hb_nvd/'
3634
}

src/test/resources/outputDir.gradle

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,5 @@ dependencies {
2020
}
2121

2222
dependencyCheck {
23-
nvd {
24-
datafeedUrl = 'https://jeremylong.github.io/DependencyCheck/hb_nvd/'
25-
}
23+
nvd.datafeedUrl = 'https://jeremylong.github.io/DependencyCheck/hb_nvd/'
2624
}

src/test/resources/scanAdditionalCpesConfiguration.gradle

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,5 @@ dependencyCheck {
2323
cpe = "cpe:2.3:a:apache:commons_fileupload:1.3.1:*:*:*:*:*:*:*"
2424
}
2525
}
26-
nvd {
27-
datafeedUrl = 'https://jeremylong.github.io/DependencyCheck/hb_nvd/'
28-
}
26+
nvd.datafeedUrl = 'https://jeremylong.github.io/DependencyCheck/hb_nvd/'
2927
}

0 commit comments

Comments
 (0)