Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/main/java/org/dependencytrack/model/PolicyCondition.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ public enum Subject {
SWID_TAGID,
VERSION,
COMPONENT_HASH,
CWE
CWE,
VULNERABILITY_ID
}

@PrimaryKey
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/org/dependencytrack/policy/PolicyEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public PolicyEngine() {
evaluators.add(new ComponentAgePolicyEvaluator());
evaluators.add(new ComponentHashPolicyEvaluator());
evaluators.add(new CwePolicyEvaluator());
evaluators.add(new VulnerabilityIdPolicyEvaluator());
Comment thread
sahibamittal marked this conversation as resolved.
}

public List<PolicyViolation> evaluate(final List<Component> components) {
Expand Down Expand Up @@ -143,6 +144,7 @@ private PolicyViolation.Type determineViolationType(final PolicyCondition.Subjec
case CPE:
case SWID_TAGID:
case COMPONENT_HASH:
case VULNERABILITY_ID:
case VERSION:
return PolicyViolation.Type.OPERATIONAL;
case LICENSE:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* This file is part of Dependency-Track.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
* Copyright (c) Steve Springett. All Rights Reserved.
*/
package org.dependencytrack.policy;

import alpine.common.logging.Logger;
import org.dependencytrack.model.Component;
import org.dependencytrack.model.Policy;
import org.dependencytrack.model.PolicyCondition;
import org.dependencytrack.model.Vulnerability;

import java.util.ArrayList;
import java.util.List;

/**
* Evaluates the component vulnerabilities against a policy based on vulnerability ID.
*/
public class VulnerabilityIdPolicyEvaluator extends AbstractPolicyEvaluator {

private static final Logger LOGGER = Logger.getLogger(VulnerabilityIdPolicyEvaluator.class);

/**
* {@inheritDoc}
*/
@Override
public PolicyCondition.Subject supportedSubject() {
return PolicyCondition.Subject.VULNERABILITY_ID;
}

/**
* {@inheritDoc}
*/
@Override
public List<PolicyConditionViolation> evaluate(final Policy policy, final Component component) {
final List<PolicyConditionViolation> violations = new ArrayList<>();
final List<PolicyCondition> policyConditions = super.extractSupportedConditions(policy);
for (final Vulnerability vulnerability : qm.getAllVulnerabilities(component, false)) {
for (final PolicyCondition condition: policyConditions) {
LOGGER.debug("Evaluating component (" + component.getUuid() + ") against policy condition (" + condition.getUuid() + ")");
if (PolicyCondition.Operator.IS == condition.getOperator()) {
if (vulnerability.getVulnId().equals(condition.getValue())) {
violations.add(new PolicyConditionViolation(condition, component));
}
} else if (PolicyCondition.Operator.IS_NOT == condition.getOperator()) {
if (! vulnerability.getVulnId().equals(condition.getValue())) {
violations.add(new PolicyConditionViolation(condition, component));
}
}
}
}
return violations;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* This file is part of Dependency-Track.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
* Copyright (c) Steve Springett. All Rights Reserved.
*/
package org.dependencytrack.policy;

import org.dependencytrack.PersistenceCapableTest;
import org.dependencytrack.model.Component;
import org.dependencytrack.model.Policy;
import org.dependencytrack.model.PolicyCondition;
import org.dependencytrack.model.Project;
import org.dependencytrack.model.Vulnerability;
import org.dependencytrack.tasks.scanners.AnalyzerIdentity;
import org.junit.Assert;
import org.junit.Test;

import java.util.List;

public class VulnerabilityIdPolicyEvaluatorTest extends PersistenceCapableTest {

@Test
public void hasMatch() {
Policy policy = qm.createPolicy("Test Policy", Policy.Operator.ANY, Policy.ViolationState.INFO);
PolicyCondition condition = qm.createPolicyCondition(policy, PolicyCondition.Subject.VULNERABILITY_ID, PolicyCondition.Operator.IS, "test-123");
Project project = new Project();
project.setName("My Project");
Component component = new Component();
component.setName("Test Component");
component.setProject(project);
Vulnerability vulnerability = new Vulnerability();
vulnerability.setVulnId("test-123");
vulnerability.setSource(Vulnerability.Source.INTERNAL);
qm.persist(project);
qm.persist(component);
qm.persist(vulnerability);
qm.addVulnerability(vulnerability, component, AnalyzerIdentity.INTERNAL_ANALYZER);
PolicyEvaluator evaluator = new VulnerabilityIdPolicyEvaluator();
evaluator.setQueryManager(qm);
List<PolicyConditionViolation> violations = evaluator.evaluate(policy, component);
Assert.assertEquals(1, violations.size());
PolicyConditionViolation violation = violations.get(0);
Assert.assertEquals(component.getId(), violation.getComponent().getId());
Assert.assertEquals(condition, violation.getPolicyCondition());
}

@Test
public void noMatch() {
Policy policy = qm.createPolicy("Test Policy", Policy.Operator.ANY, Policy.ViolationState.INFO);
qm.createPolicyCondition(policy, PolicyCondition.Subject.VULNERABILITY_ID, PolicyCondition.Operator.IS, "test-123");
Project project = new Project();
project.setName("My Project");
Component component = new Component();
component.setName("Test Component");
component.setVersion("1.0");
component.setProject(project);
Vulnerability vulnerability = new Vulnerability();
vulnerability.setVulnId("test-789");
vulnerability.setSource(Vulnerability.Source.INTERNAL);
qm.persist(project);
qm.persist(component);
qm.persist(vulnerability);
qm.addVulnerability(vulnerability, component, AnalyzerIdentity.INTERNAL_ANALYZER);
PolicyEvaluator evaluator = new VulnerabilityIdPolicyEvaluator();
evaluator.setQueryManager(qm);
List<PolicyConditionViolation> violations = evaluator.evaluate(policy, component);
Assert.assertEquals(0, violations.size());
}

@Test
public void noMatchIsNotOperator() {
Policy policy = qm.createPolicy("Test Policy", Policy.Operator.ANY, Policy.ViolationState.INFO);
qm.createPolicyCondition(policy, PolicyCondition.Subject.VULNERABILITY_ID, PolicyCondition.Operator.IS_NOT, "test-123");
Project project = new Project();
project.setName("My Project");
Component component = new Component();
component.setName("Test Component");
component.setVersion("1.0");
component.setProject(project);
Vulnerability vulnerability = new Vulnerability();
vulnerability.setVulnId("test-123");
vulnerability.setSource(Vulnerability.Source.INTERNAL);
qm.persist(project);
qm.persist(component);
qm.persist(vulnerability);
qm.addVulnerability(vulnerability, component, AnalyzerIdentity.INTERNAL_ANALYZER);
PolicyEvaluator evaluator = new VulnerabilityIdPolicyEvaluator();
evaluator.setQueryManager(qm);
List<PolicyConditionViolation> violations = evaluator.evaluate(policy, component);
Assert.assertEquals(0, violations.size());
}
}