Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
1 change: 0 additions & 1 deletion dojo/importers/auto_create_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ def get_target_product_if_exists(
if product_type_name and product.prod_type.name != product_type_name:
msg = (
"The fetched product has a conflict with the supplied product type name: "
f"existing product type name - {product.prod_type.name} vs "
f"supplied product type name - {product_type_name}"
)
raise ValueError(msg)
Expand Down
72 changes: 72 additions & 0 deletions unittests/test_apiv2_import_error_disclosure.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""
Regression tests for information disclosure through the scan-import permission classes.

The import permission classes resolve caller-supplied names against unscoped managers
before any authorization call runs. A mismatch between the supplied product type name
and the stored one must not put the stored name into the error body, because the caller
reaching that branch may hold no grant on the resolved product at all.
"""
from rest_framework.authtoken.models import Token
from rest_framework.test import APIClient

from dojo.models import Dojo_User, Product, Product_Type

from .dojo_test_case import DojoTestCase

SECRET_PRODUCT_TYPE_NAME = "Confidential Tenant Name Sentinel"


class TestImportErrorDisclosure(DojoTestCase):

@classmethod
def setUpTestData(cls):
cls.product_type = Product_Type.objects.create(name=SECRET_PRODUCT_TYPE_NAME)
cls.product = Product.objects.create(
name="Import Disclosure Victim Product",
description="victim",
prod_type=cls.product_type,
)
# No Product_Member, no Product_Type_Member, no staff, no superuser.
cls.outsider = Dojo_User.objects.create_user(
username="import_disclosure_outsider", is_active=True,
)
cls.token = Token.objects.create(user=cls.outsider)

def _client(self):
client = APIClient()
client.credentials(HTTP_AUTHORIZATION=f"Token {self.token.key}")
return client

def _payload(self):
return {
"scan_type": "Generic Findings Import",
"product_name": self.product.name,
"product_type_name": "a name the caller guessed wrong",
"engagement_name": "an engagement that does not exist",
}

def _assert_no_disclosure(self, response):
self.assertEqual(response.status_code, 400)
self.assertNotIn(SECRET_PRODUCT_TYPE_NAME, response.content.decode())

def test_outsider_cannot_read_the_product_type(self):
response = self._client().get(f"/api/v2/product_types/{self.product_type.id}/")
self.assertEqual(response.status_code, 404)

def test_import_scan_does_not_disclose_product_type_name(self):
self._assert_no_disclosure(
self._client().post("/api/v2/import-scan/", self._payload()),
)

def test_reimport_scan_does_not_disclose_product_type_name(self):
self._assert_no_disclosure(
self._client().post("/api/v2/reimport-scan/", self._payload()),
)

def test_endpoint_meta_import_does_not_disclose_product_type_name(self):
payload = self._payload()
payload.pop("scan_type")
payload.pop("engagement_name")
self._assert_no_disclosure(
self._client().post("/api/v2/endpoint_meta_import/", payload),
)
2 changes: 0 additions & 2 deletions unittests/test_importers_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,6 @@ def test_import_with_invalid_parameters(self):
engagement=None, product_type_name=another_product_type_name, product_name=PRODUCT_NAME_DEFAULT, engagement_name="valentijn", expected_http_status_code=400)
self.assertEqual(import0, [(
"The fetched product has a conflict with the supplied product type name: "
f"existing product type name - {PRODUCT_TYPE_NAME_DEFAULT} vs "
f"supplied product type name - {another_product_type_name}"
)])

Expand Down Expand Up @@ -1108,7 +1107,6 @@ def test_reimport_with_invalid_parameters(self):
engagement=None, product_type_name=another_product_type_name, product_name=PRODUCT_NAME_DEFAULT, engagement_name="valentijn", expected_http_status_code=400)
self.assertEqual(import0, [(
"The fetched product has a conflict with the supplied product type name: "
f"existing product type name - {PRODUCT_TYPE_NAME_DEFAULT} vs "
f"supplied product type name - {another_product_type_name}"
)])

Expand Down
Loading