Skip to content

Commit

Permalink
Add the ability to manually specify addtional CPE entries to be check…
Browse files Browse the repository at this point in the history
…ed. (#361)

Co-authored-by: Jeremy Long <[email protected]>
  • Loading branch information
gordoninnes and jeremylong authored Mar 15, 2024
1 parent 41b5074 commit 4cffcda
Show file tree
Hide file tree
Showing 6 changed files with 121 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 @@ -206,12 +208,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 @@ -274,4 +282,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,13 @@ 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 org.owasp.dependencycheck.utils.Checksum
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 +461,19 @@ abstract class AbstractAnalyze extends ConfiguredTask {
}
}
}

config.additionalCpes.each {
var dependency = new Dependency(true);
dependency.setDescription(it.description)
dependency.setDisplayFileName(it.cpe);
dependency.setSha1sum(Checksum.getSHA1Checksum(it.cpe));
dependency.setSha256sum(Checksum.getSHA256Checksum(it.cpe));
dependency.setMd5sum(Checksum.getMD5Checksum(it.cpe));
dependency.addVulnerableSoftwareIdentifier(new CpeIdentifier(CpeParser.parse(it.cpe), Confidence.HIGHEST))
dependency.setFileName("")
dependency.setActualFilePath("")
engine.addDependency(dependency)
}
}

/**
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 @@ -150,6 +150,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 @@ -188,6 +205,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 4cffcda

Please sign in to comment.