Skip to content

Commit

Permalink
Fix: Projects the Principal has no access to are
Browse files Browse the repository at this point in the history
removed before sending

Signed-off-by: Thomas Schauer-Köckeis <thomas.schauer-koeckeis@rohde-schwarz.com>
  • Loading branch information
Gepardgame committed Oct 1, 2024
1 parent 793b9ea commit c6ae757
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.dependencytrack.auth.Permissions;
import org.dependencytrack.model.AffectedVersionAttribution;
import org.dependencytrack.model.Component;
import org.dependencytrack.model.ConfigPropertyConstants;
import org.dependencytrack.model.Cwe;
import org.dependencytrack.model.Project;
import org.dependencytrack.model.Vulnerability;
Expand Down Expand Up @@ -65,6 +66,7 @@
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import java.math.BigDecimal;
import java.security.Principal;
import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -219,6 +221,14 @@ public Response getVulnerabilityByVulnId(@PathParam("source") String source,
affectedComponents.add(affectedComponent);
}
vulnerability.setAffectedComponents(affectedComponents);
qm.makeTransient(vulnerability);
Principal principal = super.getPrincipal();
boolean shouldFilter = qm.isEnabled(ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED);
if (shouldFilter) {
vulnerability.setComponents(
vulnerability.getComponents().stream().filter(component -> qm.hasAccess(principal,
component.getProject())).toList());
}
return Response.ok(vulnerability).build();
} else {
return Response.status(Response.Status.NOT_FOUND).entity("The vulnerability could not be found.").build();
Expand Down Expand Up @@ -256,6 +266,15 @@ public Response getAffectedProject(@PathParam("source") String source,
final long filteredCount = filteredProjects.size();
return Response.ok(filteredProjects).header(TOTAL_COUNT_HEADER, filteredCount).build();
}
qm.makeTransient(vulnerability);
Principal principal = super.getPrincipal();
boolean shouldFilter = qm.isEnabled(ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED);
if (shouldFilter) {
vulnerability.setComponents(
vulnerability.getComponents().stream().filter(component -> qm.hasAccess(principal,
component.getProject())).toList());
}

final List<AffectedProject> projects = qm.getAffectedProjects(vulnerability);
final long totalCount = projects.size();
return Response.ok(projects).header(TOTAL_COUNT_HEADER, totalCount).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.dependencytrack.resources.v1;

import alpine.common.util.UuidUtil;
import alpine.model.Team;

Check notice on line 22 in src/test/java/org/dependencytrack/resources/v1/VulnerabilityResourceTest.java

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/test/java/org/dependencytrack/resources/v1/VulnerabilityResourceTest.java#L22

Unused import - alpine.model.Team.
import alpine.server.filters.ApiFilter;
import alpine.server.filters.AuthenticationFilter;
import org.dependencytrack.JerseyTestRule;
Expand All @@ -28,6 +29,7 @@
import org.dependencytrack.model.AnalysisResponse;
import org.dependencytrack.model.AnalysisState;
import org.dependencytrack.model.Component;
import org.dependencytrack.model.ConfigPropertyConstants;
import org.dependencytrack.model.Project;
import org.dependencytrack.model.Severity;
import org.dependencytrack.model.Vulnerability;
Expand Down Expand Up @@ -62,10 +64,10 @@ public void getVulnerabilitiesByComponentUuidTest() {
.header(X_API_KEY, apiKey)
.get(Response.class);
Assert.assertEquals(200, response.getStatus(), 0);
Assert.assertEquals(String.valueOf(2), response.getHeaderString(TOTAL_COUNT_HEADER));
Assert.assertEquals(String.valueOf(3), response.getHeaderString(TOTAL_COUNT_HEADER));
JsonArray json = parseJsonArray(response);
Assert.assertNotNull(json);
Assert.assertEquals(2, json.size());
Assert.assertEquals(3, json.size());
Assert.assertEquals("INT-1", json.getJsonObject(0).getString("vulnId"));
Assert.assertEquals("INTERNAL", json.getJsonObject(0).getString("source"));
Assert.assertEquals("Description 1", json.getJsonObject(0).getString("description"));
Expand Down Expand Up @@ -103,10 +105,10 @@ public void getVulnerabilitiesByComponentUuidIncludeSuppressedTest() {
.header(X_API_KEY, apiKey)
.get(Response.class);
Assert.assertEquals(200, response.getStatus(), 0);
Assert.assertEquals(String.valueOf(3), response.getHeaderString(TOTAL_COUNT_HEADER));
Assert.assertEquals(String.valueOf(4), response.getHeaderString(TOTAL_COUNT_HEADER));
JsonArray json = parseJsonArray(response);
Assert.assertNotNull(json);
Assert.assertEquals(3, json.size());
Assert.assertEquals(4, json.size());
Assert.assertEquals("INT-1", json.getJsonObject(0).getString("vulnId"));
Assert.assertEquals("INTERNAL", json.getJsonObject(0).getString("source"));
Assert.assertEquals("Description 1", json.getJsonObject(0).getString("description"));
Expand All @@ -131,10 +133,10 @@ public void getVulnerabilitiesByProjectTest() {
.header(X_API_KEY, apiKey)
.get(Response.class);
Assert.assertEquals(200, response.getStatus(), 0);
Assert.assertEquals(String.valueOf(4), response.getHeaderString(TOTAL_COUNT_HEADER));
Assert.assertEquals(String.valueOf(5), response.getHeaderString(TOTAL_COUNT_HEADER));
JsonArray json = parseJsonArray(response);
Assert.assertNotNull(json);
Assert.assertEquals(4, json.size());
Assert.assertEquals(5, json.size());
Assert.assertEquals("INT-1", json.getJsonObject(0).getString("vulnId"));
Assert.assertEquals("INTERNAL", json.getJsonObject(0).getString("source"));
Assert.assertEquals("Description 1", json.getJsonObject(0).getString("description"));
Expand All @@ -145,16 +147,21 @@ public void getVulnerabilitiesByProjectTest() {
Assert.assertEquals("Description 2", json.getJsonObject(1).getString("description"));
Assert.assertEquals("HIGH", json.getJsonObject(1).getString("severity"));
Assert.assertTrue(UuidUtil.isValidUUID(json.getJsonObject(1).getString("uuid")));
Assert.assertEquals("INT-4", json.getJsonObject(2).getString("vulnId"));
Assert.assertEquals("INT-6", json.getJsonObject(2).getString("vulnId"));
Assert.assertEquals("INTERNAL", json.getJsonObject(2).getString("source"));
Assert.assertEquals("Description 4", json.getJsonObject(2).getString("description"));
Assert.assertEquals("LOW", json.getJsonObject(2).getString("severity"));
Assert.assertEquals("Description 6", json.getJsonObject(2).getString("description"));
Assert.assertEquals("CRITICAL", json.getJsonObject(2).getString("severity"));
Assert.assertTrue(UuidUtil.isValidUUID(json.getJsonObject(2).getString("uuid")));
Assert.assertEquals("INT-5", json.getJsonObject(3).getString("vulnId"));
Assert.assertEquals("INT-4", json.getJsonObject(3).getString("vulnId"));
Assert.assertEquals("INTERNAL", json.getJsonObject(3).getString("source"));
Assert.assertEquals("Description 5", json.getJsonObject(3).getString("description"));
Assert.assertEquals("CRITICAL", json.getJsonObject(3).getString("severity"));
Assert.assertEquals("Description 4", json.getJsonObject(3).getString("description"));
Assert.assertEquals("LOW", json.getJsonObject(3).getString("severity"));
Assert.assertTrue(UuidUtil.isValidUUID(json.getJsonObject(3).getString("uuid")));
Assert.assertEquals("INT-5", json.getJsonObject(4).getString("vulnId"));
Assert.assertEquals("INTERNAL", json.getJsonObject(4).getString("source"));
Assert.assertEquals("Description 5", json.getJsonObject(4).getString("description"));
Assert.assertEquals("CRITICAL", json.getJsonObject(4).getString("severity"));
Assert.assertTrue(UuidUtil.isValidUUID(json.getJsonObject(4).getString("uuid")));
}

@Test
Expand All @@ -166,10 +173,10 @@ public void getVulnerabilitiesByProjectIncludeProjectSuppressedTest() {
.header(X_API_KEY, apiKey)
.get(Response.class);
Assert.assertEquals(200, response.getStatus(), 0);
Assert.assertEquals(String.valueOf(2), response.getHeaderString(TOTAL_COUNT_HEADER));
Assert.assertEquals(String.valueOf(3), response.getHeaderString(TOTAL_COUNT_HEADER));
JsonArray json = parseJsonArray(response);
Assert.assertNotNull(json);
Assert.assertEquals(2, json.size());
Assert.assertEquals(3, json.size());
Assert.assertEquals("INT-4", json.getJsonObject(0).getString("vulnId"));
Assert.assertEquals("INT-5", json.getJsonObject(1).getString("vulnId"));
}
Expand Down Expand Up @@ -241,6 +248,50 @@ public void getVulnerabilityByVulnIdInvalidTest() {
Assert.assertEquals("The vulnerability could not be found.", body);
}

@Test
public void getVulnerabilityByVulnIdACLEnabledTest() {
SampleData sampleData = new SampleData();
qm.createConfigProperty(
ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED.getGroupName(),
ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED.getPropertyName(),
"true",
ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED.getPropertyType(),
ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED.getDescription());
Response response = jersey.target(V1_VULNERABILITY + "/source/" + sampleData.v6.getSource() + "/vuln/" + sampleData.v6.getVulnId()).request()
.header(X_API_KEY, apiKey)
.get(Response.class);
Assert.assertEquals(200, response.getStatus(), 0);
Assert.assertNull(response.getHeaderString(TOTAL_COUNT_HEADER));
JsonObject json = parseJsonObject(response);
Assert.assertNotNull(json);
Assert.assertEquals("INT-6", json.getString("vulnId"));
JsonArray components = json.getJsonArray("components");
Assert.assertNotNull(components);
Assert.assertEquals(1, components.size());
}

@Test
public void getVulnerabilityByVulnIdACLDisabledTest() {
SampleData sampleData = new SampleData();
qm.createConfigProperty(
ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED.getGroupName(),
ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED.getPropertyName(),
"false",
ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED.getPropertyType(),
ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED.getDescription());
Response response = jersey.target(V1_VULNERABILITY + "/source/" + sampleData.v6.getSource() + "/vuln/" + sampleData.v6.getVulnId()).request()
.header(X_API_KEY, apiKey)
.get(Response.class);
Assert.assertEquals(200, response.getStatus(), 0);
Assert.assertNull(response.getHeaderString(TOTAL_COUNT_HEADER));
JsonObject json = parseJsonObject(response);
Assert.assertNotNull(json);
Assert.assertEquals("INT-6", json.getString("vulnId"));
JsonArray components = json.getJsonArray("components");
Assert.assertNotNull(components);
Assert.assertEquals(2, components.size());
}

@Test
public void getAffectedProjectTest() {
SampleData sampleData = new SampleData();
Expand Down Expand Up @@ -268,17 +319,59 @@ public void getAffectedProjectInvalidTest() {
Assert.assertEquals("The vulnerability could not be found.", body);
}

@Test
public void getAffectedProjectACLEnabledTest() {
SampleData sampleData = new SampleData();
qm.createConfigProperty(
ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED.getGroupName(),
ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED.getPropertyName(),
"true",
ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED.getPropertyType(),
ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED.getDescription());
Response response = jersey.target(V1_VULNERABILITY + "/source/" + sampleData.v6.getSource() + "/vuln/" + sampleData.v6.getVulnId() + "/projects").request()
.header(X_API_KEY, apiKey)
.get(Response.class);
Assert.assertEquals(200, response.getStatus(), 0);
JsonArray json = parseJsonArray(response);
Assert.assertNotNull(json);
Assert.assertEquals(1, json.size());
Assert.assertEquals("Project 1", json.getJsonObject(0).getString("name"));
Assert.assertEquals(sampleData.p1.getUuid().toString(), json.getJsonObject(0).getString("uuid"));
}

@Test
public void getAffectedProjectACLDisabledTest() {
SampleData sampleData = new SampleData();
qm.createConfigProperty(
ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED.getGroupName(),
ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED.getPropertyName(),
"false",
ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED.getPropertyType(),
ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED.getDescription());
Response response = jersey.target(V1_VULNERABILITY + "/source/" + sampleData.v6.getSource() + "/vuln/" + sampleData.v6.getVulnId() + "/projects").request()
.header(X_API_KEY, apiKey)
.get(Response.class);
Assert.assertEquals(200, response.getStatus(), 0);
JsonArray json = parseJsonArray(response);
Assert.assertNotNull(json);
Assert.assertEquals(2, json.size());
Assert.assertEquals("Project 2", json.getJsonObject(0).getString("name"));
Assert.assertEquals(sampleData.p2.getUuid().toString(), json.getJsonObject(0).getString("uuid"));
Assert.assertEquals("Project 1", json.getJsonObject(1).getString("name"));
Assert.assertEquals(sampleData.p1.getUuid().toString(), json.getJsonObject(1).getString("uuid"));
}

@Test
public void getAllVulnerabilitiesTest() {
new SampleData();
Response response = jersey.target(V1_VULNERABILITY).request()
.header(X_API_KEY, apiKey)
.get(Response.class);
Assert.assertEquals(200, response.getStatus(), 0);
Assert.assertEquals(String.valueOf(5), response.getHeaderString(TOTAL_COUNT_HEADER));
Assert.assertEquals(String.valueOf(6), response.getHeaderString(TOTAL_COUNT_HEADER));
JsonArray json = parseJsonArray(response);
Assert.assertNotNull(json);
Assert.assertEquals(5, json.size());
Assert.assertEquals(6, json.size());
Assert.assertEquals("INT-1", json.getJsonObject(0).getString("vulnId"));
Assert.assertEquals("INT-2", json.getJsonObject(1).getString("vulnId"));
Assert.assertEquals("INT-3", json.getJsonObject(2).getString("vulnId"));
Expand Down Expand Up @@ -731,10 +824,13 @@ private class SampleData {
final Vulnerability v3;
final Vulnerability v4;
final Vulnerability v5;
final Vulnerability v6;
final VulnerableSoftware vs1;

SampleData() {
p1 = qm.createProject("Project 1", null, null, null, null, null, true, false);
p1.addAccessTeam(team);

p2 = qm.createProject("Project 2", null, null, null, null, null, true, false);

c1 = new Component();
Expand Down Expand Up @@ -798,18 +894,27 @@ private class SampleData {
v5.setSeverity(Severity.CRITICAL);
v5.setDescription("Description 5");

v6 = new Vulnerability();
v6.setVulnId("INT-6");
v6.setSource(Vulnerability.Source.INTERNAL);
v6.setSeverity(Severity.CRITICAL);
v6.setDescription("Description 6");

qm.createVulnerability(v1, false);
qm.createVulnerability(v2, false);
qm.createVulnerability(v3, false);
qm.createVulnerability(v4, false);
qm.createVulnerability(v5, false);
qm.createVulnerability(v6, false);
qm.addVulnerability(v1, c1, AnalyzerIdentity.NONE);
qm.addVulnerability(v2, c1, AnalyzerIdentity.NONE);
qm.addVulnerability(v3, c1, AnalyzerIdentity.NONE);
qm.addVulnerability(v4, c2, AnalyzerIdentity.NONE);
qm.addVulnerability(v5, c2, AnalyzerIdentity.NONE);
qm.addVulnerability(v4, c3, AnalyzerIdentity.NONE);
qm.addVulnerability(v5, c3, AnalyzerIdentity.NONE);
qm.addVulnerability(v6, c1, AnalyzerIdentity.NONE);
qm.addVulnerability(v6, c3, AnalyzerIdentity.NONE);

qm.makeAnalysis(c1, v3, AnalysisState.FALSE_POSITIVE, AnalysisJustification.CODE_NOT_REACHABLE, AnalysisResponse.WILL_NOT_FIX, "Analysis details here", true);
qm.makeAnalysis(c3, v5, AnalysisState.NOT_AFFECTED, AnalysisJustification.CODE_NOT_REACHABLE, AnalysisResponse.WILL_NOT_FIX, "Analysis details here", true);
Expand Down

0 comments on commit c6ae757

Please sign in to comment.