Skip to content

Commit

Permalink
Add the ability to manually specify addtional CPE entries to be checked.
Browse files Browse the repository at this point in the history
  • Loading branch information
gordoninnes committed Nov 10, 2023
1 parent a015c8e commit 89a639a
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.owasp.dependencycheck.gradle.extension

import org.gradle.api.Named

/**
* Holder for the information regarding an additional CPE to be checked.
*/
@groovy.transform.CompileStatic
class AdditionalCpe implements Named {

AdditionalCpe(String name) {
this.name = name;
}

/**
* Name assigned to the CPE entry during configuration.
*/
String name;

/**
* Description for the what the CPE represents.
*/
String description

/**
* The CPE to be checked against the database.
*/
String cpe
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

package org.owasp.dependencycheck.gradle.extension

import org.gradle.api.Action
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Project

import java.util.stream.Collectors
Expand Down Expand Up @@ -210,12 +212,18 @@ class DependencyCheckExtension {
* A set of files or folders to scan.
*/
List<File> scanSet
/**
* Additional CPE to be analyzed.
*/
NamedDomainObjectContainer<AdditionalCpe> additionalCpes =
project.objects.domainObjectContainer(AdditionalCpe.class)

/**
* The configuration extension for cache settings.
*/
CacheExtension cache = new CacheExtension()


/**
* Allows programmatic configuration of the proxy extension
* @param configClosure the closure to configure the proxy extension
Expand Down Expand Up @@ -278,4 +286,12 @@ class DependencyCheckExtension {
def cache(Closure configClosure) {
return project.configure(cache, configClosure)
}

/**
* Allows programmatic configuration of additional CPEs to be analyzed
* @param action the action used to add entries to additional CPEs container.
*/
def additionalCpes(Action<NamedDomainObjectContainer<AdditionalCpe>> action) {
action.execute(additionalCpes)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@ import org.owasp.dependencycheck.dependency.Confidence
import org.owasp.dependencycheck.dependency.Dependency
import org.owasp.dependencycheck.dependency.IncludedByReference
import org.owasp.dependencycheck.dependency.Vulnerability
import org.owasp.dependencycheck.dependency.naming.CpeIdentifier
import org.owasp.dependencycheck.exception.ExceptionCollection
import org.owasp.dependencycheck.exception.ReportException
import org.owasp.dependencycheck.gradle.service.SlackNotificationSenderService
import org.owasp.dependencycheck.utils.SeverityUtil
import us.springett.parsers.cpe.CpeParser

import static org.owasp.dependencycheck.dependency.EvidenceType.PRODUCT
import static org.owasp.dependencycheck.dependency.EvidenceType.VENDOR
Expand Down Expand Up @@ -458,6 +460,15 @@ abstract class AbstractAnalyze extends ConfiguredTask {
}
}
}

config.additionalCpes.each {
var dep = new Dependency(true);
dep.setDescription(it.description)
dep.addVulnerableSoftwareIdentifier(new CpeIdentifier(CpeParser.parse(it.cpe), Confidence.HIGHEST))
dep.setFileName("")
dep.setActualFilePath("")
engine.addDependency(dep)
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@ class DependencyCheckConfigurationSelectionIntegSpec extends Specification {
//result.output.contains('CVE-2015-5262')
}

def "additional CPEs are scanned when present"() {
given:
copyBuildFileIntoProjectDir('scanAdditionalCpesConfiguration.gradle')

when:
def result = executeTaskAndGetResult(ANALYZE_TASK, false)

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

def "custom configurations are scanned by default"() {
given:
copyBuildFileIntoProjectDir('scanCustomConfiguration.gradle')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,23 @@ class DependencyCheckGradlePluginSpec extends Specification {
suppressionFiles = ['./src/config/suppression1.xml', './src/config/suppression2.xml']
suppressionFileUser = 'suppressionFileUsername'
suppressionFilePassword = 'suppressionFilePassword'

additionalCpes {
additional1 {
description = "Additional1"
cpe = "cpe:2.3:a:aGroup1:aPackage1:123:*:*:*:*:*:*:*"
}

additional2 {
description = "Additional2"
cpe = "cpe:2.3:a:aGroup2:aPackage2:123:*:*:*:*:*:*:*"
}

additional3 {
description = "Additional3"
cpe = "cpe:2.3:a:aGroup3:aPackage3:123:*:*:*:*:*:*:*"
}
}
}

then:
Expand Down Expand Up @@ -185,6 +202,10 @@ class DependencyCheckGradlePluginSpec extends Specification {
project.dependencyCheck.analyzers.retirejs.filterNonVulnerable == true
project.dependencyCheck.slack.enabled == true
project.dependencyCheck.slack.webhookUrl == slackWebhookUrl
project.dependencyCheck.additionalCpes.size() == 3
project.dependencyCheck.additionalCpes.getByName('additional1').description == 'Additional1'
project.dependencyCheck.additionalCpes.getByName('additional1').cpe == 'cpe:2.3:a:aGroup1:aPackage1:123:*:*:*:*:*:*:*'

}

def 'scanConfigurations and skipConfigurations are mutually exclusive'() {
Expand Down
26 changes: 26 additions & 0 deletions src/test/resources/scanAdditionalCpesConfiguration.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
plugins {
id 'org.owasp.dependencycheck'
id 'java'
}

sourceCompatibility = 1.5
version = '1.0'

repositories {
mavenLocal()
mavenCentral()
}

dependencyCheck {
failBuildOnCVSS = 0
additionalCpes {
commonsCollections {
description = "Commons Collections 3.2"
cpe = "cpe:2.3:a:apache:commons_collections:3.2:*:*:*:*:*:*:*"
}
commonsFileUpload {
description = "Commons File Upload 1.3.1"
cpe = "cpe:2.3:a:apache:commons_fileupload:1.3.1:*:*:*:*:*:*:*"
}
}
}

0 comments on commit 89a639a

Please sign in to comment.