Skip to content

Commit

Permalink
fix: add retry attempts for failed NVD API requests
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremylong committed Nov 26, 2023
1 parent 939f1dc commit 57378b3
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 221 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
*/

ext {
odcVersion = '9.0.0'
openVulnClientVersion = '5.0.1'
odcVersion = '9.0.1'
openVulnClientVersion = '5.0.2'
slackWebhookVersion = '1.4.0'
spockCoreVersion = '2.3-groovy-3.0'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ class NvdExtension {
* The number of milliseconds to wait between calls to the NVD API.
*/
Integer delay
/**
* The maximum number of retry requests for a single call to the NVD API.
*/
Integer maxRetryCount
/**
* The URL for the NVD API Data feed that can be generated using https://github.com/jeremylong/Open-Vulnerability-Project/tree/main/vulnz#caching-the-nvd-cve-data.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ abstract class ConfiguredTask extends DefaultTask {

settings.setStringIfNotEmpty(NVD_API_KEY, config.nvd.apiKey)
settings.setIntIfNotNull(NVD_API_DELAY, config.nvd.delay)
settings.setIntIfNotNull(NVD_API_MAX_RETRY_COUNT, config.nvd.maxRetryCount)
settings.setIntIfNotNull(NVD_API_VALID_FOR_HOURS, config.nvd.validForHours);

settings.setStringIfNotEmpty(NVD_API_DATAFEED_URL, config.nvd.datafeedUrl)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,113 +14,110 @@ class DependencyCheckConfigurationSelectionIntegSpec extends Specification {
@TempDir
File testProjectDir

/////////////////////////////
// Integration Specification Tests are failing since upgrading to 'com.h2database:h2:2.2.224'
/////////////////////////////
// def 'test dependencies are ignored by default'() {
// given:
// copyBuildFileIntoProjectDir('skipTestGroups.gradle')
//
// when:
// def result = executeTaskAndGetResult(ANALYZE_TASK, true)
//
// then:
// result.task(":$ANALYZE_TASK").outcome == SUCCESS
// }
//
// def "test dependencies are scanned if skipTestGroups flag is false"() {
// given:
// copyBuildFileIntoProjectDir('noSkipTestGroups.gradle')
//
// when:
// def result = executeTaskAndGetResult(ANALYZE_TASK, false)
// //println "-----------------"
// //println result.output
// //println "-----------------"
// //String fileContents = new File(new File(testProjectDir, 'build/reports'), 'dependency-check-report.html').text
// //println fileContents
//
// then:
// result.task(":$ANALYZE_TASK").outcome == FAILED
// result.output.contains('CVE-2015-6420')
// result.output.contains('CVE-2014-0114')
// result.output.contains('CVE-2016-3092')
// //the nvd CVE was updated and the version used is no longer considered vulnerable
// //result.output.contains('CVE-2015-5262')
// }
//
// def "custom configurations are scanned by default"() {
// given:
// copyBuildFileIntoProjectDir('scanCustomConfiguration.gradle')
//
// when:
// def result = executeTaskAndGetResult(ANALYZE_TASK, false)
//
// then:
// result.task(":$ANALYZE_TASK").outcome == FAILED
// result.output.contains('CVE-2015-6420')
// }
//
// def "custom configurations are skipped if blacklisted"() {
// given:
// copyBuildFileIntoProjectDir('blacklistCustomConfiguration.gradle')
//
// when:
// def result = executeTaskAndGetResult(ANALYZE_TASK, true)
//
// then:
// result.task(":$ANALYZE_TASK").outcome == SUCCESS
// }
//
// def "custom configurations are skipped when only scanning whitelisted configurations"() {
// given:
// copyBuildFileIntoProjectDir('skipCustomConfigurationViaWhitelist.gradle')
//
// when:
// def result = executeTaskAndGetResult(ANALYZE_TASK, true)
//
// then:
// result.task(":$ANALYZE_TASK").outcome == SUCCESS
// }
//
// def "groups are skipped if blacklisted"() {
// given:
// copyBuildFileIntoProjectDir('skipGroups.gradle')
//
// when:
// def result = executeTaskAndGetResult(ANALYZE_TASK, true)
//
// then:
// result.task(":$ANALYZE_TASK").outcome == SUCCESS
// }
//
// def "aggregate task aggregates"() {
// given:
// copyBuildFileIntoProjectDir('aggregateParent.gradle')
// copyResourceFileIntoProjectDir('aggregateSettings.gradle', 'settings.gradle')
// copyResourceFileIntoProjectDir('aggregateApp.gradle', 'app/build.gradle')
// copyResourceFileIntoProjectDir('aggregateCore.gradle', 'core/build.gradle')
//
// when:
// def result = executeTaskAndGetResult(AGGREGATE_TASK, true)
//
// then:
// result.task(":$AGGREGATE_TASK").outcome == SUCCESS
// result.output.contains('CVE-2016-7051') //jackson cve from core
// result.output.contains('CVE-2015-6420') //commons cve from app
// }
//
// def "suppressionFiles argument can be parsed and files are being respected"() {
// given:
// copyBuildFileIntoProjectDir('suppressionFiles.gradle')
// copyResourceFileIntoProjectDir('suppressions.xml', 'suppressions.xml')
//
// when:
// def result = executeTaskAndGetResult(ANALYZE_TASK, true)
//
// then:
// result.task(":$ANALYZE_TASK").outcome == SUCCESS
// }
def 'test dependencies are ignored by default'() {
given:
copyBuildFileIntoProjectDir('skipTestGroups.gradle')

when:
def result = executeTaskAndGetResult(ANALYZE_TASK, true)

then:
result.task(":$ANALYZE_TASK").outcome == SUCCESS
}

def "test dependencies are scanned if skipTestGroups flag is false"() {
given:
copyBuildFileIntoProjectDir('noSkipTestGroups.gradle')

when:
def result = executeTaskAndGetResult(ANALYZE_TASK, false)
//println "-----------------"
//println result.output
//println "-----------------"
//String fileContents = new File(new File(testProjectDir, 'build/reports'), 'dependency-check-report.html').text
//println fileContents

then:
result.task(":$ANALYZE_TASK").outcome == FAILED
result.output.contains('CVE-2015-6420')
result.output.contains('CVE-2014-0114')
result.output.contains('CVE-2016-3092')
//the nvd CVE was updated and the version used is no longer considered vulnerable
//result.output.contains('CVE-2015-5262')
}

def "custom configurations are scanned by default"() {
given:
copyBuildFileIntoProjectDir('scanCustomConfiguration.gradle')

when:
def result = executeTaskAndGetResult(ANALYZE_TASK, false)

then:
result.task(":$ANALYZE_TASK").outcome == FAILED
result.output.contains('CVE-2015-6420')
}

def "custom configurations are skipped if blacklisted"() {
given:
copyBuildFileIntoProjectDir('blacklistCustomConfiguration.gradle')

when:
def result = executeTaskAndGetResult(ANALYZE_TASK, true)

then:
result.task(":$ANALYZE_TASK").outcome == SUCCESS
}

def "custom configurations are skipped when only scanning whitelisted configurations"() {
given:
copyBuildFileIntoProjectDir('skipCustomConfigurationViaWhitelist.gradle')

when:
def result = executeTaskAndGetResult(ANALYZE_TASK, true)

then:
result.task(":$ANALYZE_TASK").outcome == SUCCESS
}

def "groups are skipped if blacklisted"() {
given:
copyBuildFileIntoProjectDir('skipGroups.gradle')

when:
def result = executeTaskAndGetResult(ANALYZE_TASK, true)

then:
result.task(":$ANALYZE_TASK").outcome == SUCCESS
}

def "aggregate task aggregates"() {
given:
copyBuildFileIntoProjectDir('aggregateParent.gradle')
copyResourceFileIntoProjectDir('aggregateSettings.gradle', 'settings.gradle')
copyResourceFileIntoProjectDir('aggregateApp.gradle', 'app/build.gradle')
copyResourceFileIntoProjectDir('aggregateCore.gradle', 'core/build.gradle')

when:
def result = executeTaskAndGetResult(AGGREGATE_TASK, true)

then:
result.task(":$AGGREGATE_TASK").outcome == SUCCESS
result.output.contains('CVE-2016-7051') //jackson cve from core
result.output.contains('CVE-2015-6420') //commons cve from app
}

def "suppressionFiles argument can be parsed and files are being respected"() {
given:
copyBuildFileIntoProjectDir('suppressionFiles.gradle')
copyResourceFileIntoProjectDir('suppressions.xml', 'suppressions.xml')

when:
def result = executeTaskAndGetResult(ANALYZE_TASK, true)

then:
result.task(":$ANALYZE_TASK").outcome == SUCCESS
}


private void copyBuildFileIntoProjectDir(String buildFileName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class DependencyCheckGradlePluginSpec extends Specification {
project.dependencyCheck.proxy.password == null
project.dependencyCheck.nvd.apiKey == null
project.dependencyCheck.nvd.delay == null
project.dependencyCheck.nvd.maxRetryCount == null
project.dependencyCheck.outputDirectory == "${project.buildDir}/reports"
project.dependencyCheck.quickQueryTimestamp == null
project.dependencyCheck.scanConfigurations == []
Expand All @@ -106,6 +107,7 @@ class DependencyCheckGradlePluginSpec extends Specification {
nvd {
apiKey = 'apiKey'
delay = 5000
maxRetryCount = 20
}

hostedSuppressions {
Expand Down Expand Up @@ -159,6 +161,7 @@ class DependencyCheckGradlePluginSpec extends Specification {

project.dependencyCheck.nvd.apiKey == 'apiKey'
project.dependencyCheck.nvd.delay == 5000
project.dependencyCheck.nvd.maxRetryCount == 20
project.dependencyCheck.hostedSuppressions.url == 'suppressionsurl'
project.dependencyCheck.hostedSuppressions.validForHours == 5
project.dependencyCheck.hostedSuppressions.forceupdate == true
Expand Down
Loading

0 comments on commit 57378b3

Please sign in to comment.