Skip to content

Commit 4ddde36

Browse files
authored
Merge pull request #643 from MerginMaps/whitelisting_extensions_mimetypes
Support for whitelisting extensions/mimetype
2 parents 8efd371 + 64a3844 commit 4ddde36

4 files changed

Lines changed: 39 additions & 1 deletion

File tree

deployment/community/.env.template

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ LOCAL_PROJECTS=/data
109109

110110
#BLACKLIST='.mergin/, .DS_Store, .directory' # cast=Csv()
111111

112+
# extra file extensions to permit beyond the default block-list, e.g. '.py, .sh'
113+
#UPLOAD_EXTENSIONS_WHITELIST=
114+
112115
#FILE_EXPIRATION=48 * 3600 # for clean up of old files where diffs were applied, in seconds
113116

114117
#LOCKFILE_EXPIRATION=300 # in seconds

server/mergin/sync/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,9 @@ class Configuration(object):
8282
)
8383
# files that should be ignored during extension and MIME type checks
8484
UPLOAD_FILES_WHITELIST = config("UPLOAD_FILES_WHITELIST", default="", cast=Csv())
85+
# extra extensions to permit beyond the default block-list
86+
UPLOAD_EXTENSIONS_WHITELIST = config(
87+
"UPLOAD_EXTENSIONS_WHITELIST", default="", cast=Csv()
88+
)
8589
# max batch size for fetch projects in batch endpoint
8690
MAX_BATCH_SIZE = config("MAX_BATCH_SIZE", default=100, cast=int)

server/mergin/sync/utils.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,10 @@ def check_skip_validation(file_path: str) -> bool:
463463
Some files are allowed even if they have forbidden extension or mime type.
464464
"""
465465
file_name = os.path.basename(file_path)
466-
return file_name in Configuration.UPLOAD_FILES_WHITELIST
466+
if file_name in Configuration.UPLOAD_FILES_WHITELIST:
467+
return True
468+
ext = os.path.splitext(file_path)[1].lower()
469+
return ext in {e.lower() for e in Configuration.UPLOAD_EXTENSIONS_WHITELIST}
467470

468471

469472
FORBIDDEN_MIME_TYPES = {

server/mergin/tests/test_utils.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,3 +402,31 @@ def test_mime_type_validation_skip():
402402

403403
# Should be forbidden
404404
assert not is_supported_type("other.js")
405+
406+
407+
def test_allowed_extensions_override():
408+
"""Extensions in UPLOAD_EXTENSIONS_WHITELIST are accepted even though they are in FORBIDDEN_EXTENSIONS."""
409+
with patch(
410+
"mergin.sync.utils.Configuration.UPLOAD_EXTENSIONS_WHITELIST", [".py", ".sh"]
411+
):
412+
# forbidden by default, now explicitly allowed
413+
assert is_supported_extension("model.py")
414+
assert is_supported_extension("scripts/deploy.sh")
415+
# match is case-insensitive
416+
assert is_supported_extension("MODEL.PY")
417+
# extensions not in the override stay blocked
418+
assert not is_supported_extension("malware.exe")
419+
assert not is_supported_extension("app.js")
420+
421+
422+
def test_extension_whitelist_skips_mime_check():
423+
"""A whitelisted extension also bypasses the MIME check via check_skip_validation."""
424+
with patch("mergin.sync.utils.get_mimetype", return_value="text/x-shellscript"):
425+
# blocked when the extension is not whitelisted
426+
with patch("mergin.sync.utils.Configuration.UPLOAD_EXTENSIONS_WHITELIST", []):
427+
assert not is_supported_type("deploy.sh")
428+
# allowed once the extension is whitelisted
429+
with patch(
430+
"mergin.sync.utils.Configuration.UPLOAD_EXTENSIONS_WHITELIST", [".sh"]
431+
):
432+
assert is_supported_type("deploy.sh")

0 commit comments

Comments
 (0)