Skip to content

Commit 23e993b

Browse files
authored
FileUpload Base64 extension fix (#11203)
* initial files but likely to change * improved file extension checks * remove os import * Use file url * not used imports, file url or title
1 parent df5ad5f commit 23e993b

4 files changed

Lines changed: 51 additions & 16 deletions

File tree

dojo/api_v2/serializers.py

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import json
22
import logging
3-
import os
43
import re
54
from datetime import datetime
65

@@ -803,20 +802,8 @@ class Meta:
803802

804803
def validate(self, data):
805804
if file := data.get("file"):
806-
ext = os.path.splitext(file.name)[1] # [0] returns path+filename
807-
valid_extensions = settings.FILE_UPLOAD_TYPES
808-
if ext.lower() not in valid_extensions:
809-
if accepted_extensions := f"{', '.join(valid_extensions)}":
810-
msg = (
811-
"Unsupported extension. Supported extensions are as "
812-
f"follows: {accepted_extensions}"
813-
)
814-
else:
815-
msg = (
816-
"File uploads are prohibited due to the list of acceptable "
817-
"file extensions being empty"
818-
)
819-
raise ValidationError(msg)
805+
# the clean will validate the file extensions and raise a Validation error if the extensions are not accepted
806+
FileUpload(title=file.name, file=file).clean()
820807
return data
821808
return None
822809

dojo/models.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import re
77
import warnings
88
from datetime import datetime
9+
from pathlib import Path
910
from uuid import uuid4
1011

1112
import hyperlink
@@ -741,6 +742,28 @@ def get_accessible_url(self, obj, obj_id):
741742

742743
return f"access_file/{self.id}/{obj_id}/{obj_type}"
743744

745+
def clean(self):
746+
if not self.title:
747+
self.title = "<No Title>"
748+
749+
valid_extensions = settings.FILE_UPLOAD_TYPES
750+
751+
# why does this not work with self.file....
752+
if self.file:
753+
file_name = self.file.url
754+
else:
755+
file_name = self.title
756+
if Path(file_name).suffix.lower() not in valid_extensions:
757+
if accepted_extensions := f"{', '.join(valid_extensions)}":
758+
msg = (
759+
_("Unsupported extension. Supported extensions are as follows: %s") % accepted_extensions
760+
)
761+
else:
762+
msg = (
763+
_("File uploads are prohibited due to the list of acceptable file extensions being empty")
764+
)
765+
raise ValidationError(msg)
766+
744767

745768
class Product_Type(models.Model):
746769

dojo/tools/generic/json_parser.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
from dojo.models import Endpoint, Finding
1+
import base64
2+
3+
from django.core.files.base import ContentFile
4+
5+
from dojo.models import Endpoint, FileUpload, Finding
26
from dojo.tools.parser_test import ParserTest
37

48

@@ -103,6 +107,11 @@ def _get_test_json(self, data):
103107
endpoint = Endpoint(**endpoint_item)
104108
finding.unsaved_endpoints.append(endpoint)
105109
if unsaved_files:
110+
for unsaved_file in unsaved_files:
111+
data = base64.b64decode(unsaved_file.get("data"))
112+
title = unsaved_file.get("title", "<No title>")
113+
FileUpload(title=title, file=ContentFile(data)).clean()
114+
106115
finding.unsaved_files = unsaved_files
107116
if finding.cve:
108117
finding.unsaved_vulnerability_ids = [finding.cve]

unittests/scans/generic/test_with_image_no_ext.json

Lines changed: 16 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)