Skip to content

Commit 6c30f54

Browse files
authored
Merge branch 'bugfix' into components-docs
2 parents a1ad3e1 + 04c3d89 commit 6c30f54

4 files changed

Lines changed: 80 additions & 1 deletion

File tree

dojo/api_v2/permissions.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,23 @@ class UserHasFindingNotePermission(BaseRelatedObjectPermission):
455455
}
456456

457457

458+
class UserHasBurpRawRequestResponsePermission(permissions.BasePermission):
459+
def has_permission(self, request, view):
460+
return check_post_permission(
461+
request, Finding, "finding", Permissions.Finding_Edit,
462+
)
463+
464+
def has_object_permission(self, request, view, obj):
465+
return check_object_permission(
466+
request,
467+
obj.finding,
468+
Permissions.Finding_View,
469+
Permissions.Finding_Edit,
470+
Permissions.Finding_Edit,
471+
Permissions.Finding_Edit,
472+
)
473+
474+
458475
class UserHasImportPermission(permissions.BasePermission):
459476
def has_permission(self, request, view):
460477
# permission check takes place before validation, so we don't have access to serializer.validated_data()

dojo/api_v2/views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3011,7 +3011,7 @@ class BurpRawRequestResponseViewSet(
30113011
filterset_fields = ["finding"]
30123012
permission_classes = (
30133013
IsAuthenticated,
3014-
permissions.UserHasFindingRelatedObjectPermission,
3014+
permissions.UserHasBurpRawRequestResponsePermission,
30153015
)
30163016

30173017
def get_queryset(self):

dojo/settings/settings.dist.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,6 +1616,7 @@ def generate_url(scheme, double_slashes, user, password, host, port, path, param
16161616
"JVNDB-": "https://jvndb.jvn.jp/en/contents/", # e.g. https://jvndb.jvn.jp/en/contents/2025/JVNDB-2025-004079.html
16171617
"KB": "https://support.hcl-software.com/csm?id=kb_article&sysparm_article=", # e.g. https://support.hcl-software.com/csm?id=kb_article&sysparm_article=KB0108401
16181618
"KHV": "https://avd.aquasec.com/misconfig/kubernetes/", # e.g. https://avd.aquasec.com/misconfig/kubernetes/khv045
1619+
"KSA-": "https://www.krones.com/media/downloads/KRONES-Security-Advisory-&&.pdf", # e.g. https://www.krones.com/media/downloads/KRONES-Security-Advisory-KSA-2025-2.pdf
16191620
"LEN-": "https://support.lenovo.com/cl/de/product_security/", # e.g. https://support.lenovo.com/cl/de/product_security/LEN-94953
16201621
"MAL-": "https://cvepremium.circl.lu/vuln/", # e.g. https://cvepremium.circl.lu/vuln/mal-2025-49305
16211622
"MFSA": "https://www.mozilla.org/en-US/security/advisories/", # e.g. https://www.mozilla.org/en-US/security/advisories/mfsa2025-01/

unittests/test_rest_framework.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,6 +1788,67 @@ def test_request_response_get(self):
17881788
self.assertEqual(200, response.status_code, response.content[:1000])
17891789

17901790

1791+
@versioned_fixtures
1792+
class RequestResponsePairsAuthzTest(DojoAPITestCase):
1793+
1794+
fixtures = ["dojo_testdata.json"]
1795+
1796+
def _client_for(self, username):
1797+
user = User.objects.get(username=username)
1798+
token = Token.objects.get(user=user)
1799+
client = APIClient()
1800+
client.credentials(HTTP_AUTHORIZATION="Token " + token.key)
1801+
return client
1802+
1803+
def test_admin_can_create_request_response_pair_positive_control(self):
1804+
client = self._client_for("admin")
1805+
before = BurpRawRequestResponse.objects.filter(finding_id=7).count()
1806+
response = client.post(
1807+
"/api/v2/request_response_pairs/",
1808+
dumps({
1809+
"finding": 7,
1810+
"burpRequestBase64": "cmVxdWVzdAo=",
1811+
"burpResponseBase64": "cmVzcG9uc2UK",
1812+
}),
1813+
content_type="application/json",
1814+
)
1815+
self.assertEqual(response.status_code, 201, response.content[:1000])
1816+
self.assertEqual(BurpRawRequestResponse.objects.filter(finding_id=7).count(), before + 1)
1817+
1818+
def test_unrelated_user_cannot_create_request_response_pair_on_hidden_finding(self):
1819+
client = self._client_for("user2")
1820+
# Sanity: the victim finding is genuinely hidden from this user.
1821+
get_response = client.get("/api/v2/findings/7/")
1822+
self.assertEqual(get_response.status_code, 404)
1823+
1824+
before = BurpRawRequestResponse.objects.filter(finding_id=7).count()
1825+
response = client.post(
1826+
"/api/v2/request_response_pairs/",
1827+
dumps({
1828+
"finding": 7,
1829+
"burpRequestBase64": "cmVxdWVzdAo=",
1830+
"burpResponseBase64": "cmVzcG9uc2UK",
1831+
}),
1832+
content_type="application/json",
1833+
)
1834+
self.assertIn(response.status_code, (403, 404), response.content[:1000])
1835+
self.assertEqual(BurpRawRequestResponse.objects.filter(finding_id=7).count(), before)
1836+
1837+
def test_post_without_finding_returns_4xx(self):
1838+
client = self._client_for("user2")
1839+
response = client.post(
1840+
"/api/v2/request_response_pairs/",
1841+
dumps({
1842+
"burpRequestBase64": "cmVxdWVzdAo=",
1843+
"burpResponseBase64": "cmVzcG9uc2UK",
1844+
}),
1845+
content_type="application/json",
1846+
)
1847+
# check_post_permission raises ParseError (400) when "finding" is omitted.
1848+
self.assertGreaterEqual(response.status_code, 400)
1849+
self.assertLess(response.status_code, 500)
1850+
1851+
17911852
@versioned_fixtures
17921853
class FilesTest(DojoAPITestCase):
17931854
fixtures = ["dojo_testdata.json"]

0 commit comments

Comments
 (0)