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
4 changes: 4 additions & 0 deletions deployment/community/.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ LOCAL_PROJECTS=/data

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

# extra file types to permit beyond the default block-list (e.g. scripts)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think give there just empty value without cast.

#UPLOAD_EXTENSIONS_WHITELIST='' # cast=Csv()
#UPLOAD_MIME_TYPES_WHITELIST='' # cast=Csv()

#FILE_EXPIRATION=48 * 3600 # for clean up of old files where diffs were applied, in seconds

#LOCKFILE_EXPIRATION=300 # in seconds
Expand Down
8 changes: 8 additions & 0 deletions server/mergin/sync/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,13 @@ class Configuration(object):
)
# files that should be ignored during extension and MIME type checks
UPLOAD_FILES_WHITELIST = config("UPLOAD_FILES_WHITELIST", default="", cast=Csv())
# extra extensions to permit beyond the default block-list
UPLOAD_EXTENSIONS_WHITELIST = config(
"UPLOAD_EXTENSIONS_WHITELIST", default="", cast=Csv()
)
# extra MIME types to permit beyond the default block-list
UPLOAD_MIME_TYPES_WHITELIST = config(
"UPLOAD_MIME_TYPES_WHITELIST", default="", cast=Csv()
)
# max batch size for fetch projects in batch endpoint
MAX_BATCH_SIZE = config("MAX_BATCH_SIZE", default=100, cast=int)
4 changes: 4 additions & 0 deletions server/mergin/sync/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,8 @@ def is_supported_extension(filepath) -> bool:
if check_skip_validation(filepath):
return True
ext = os.path.splitext(filepath)[1].lower()
if ext in {e.lower() for e in Configuration.UPLOAD_EXTENSIONS_WHITELIST}:

@MarcelGeo MarcelGeo Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can use check_skip_validation function for that job to unify with files or?

return True
return ext and ext not in FORBIDDEN_EXTENSIONS


Expand Down Expand Up @@ -493,6 +495,8 @@ def is_supported_type(filepath) -> bool:
if check_skip_validation(filepath):
return True
mime_type = get_mimetype(filepath)
if mime_type in Configuration.UPLOAD_MIME_TYPES_WHITELIST:
return True
return mime_type.startswith("image/") or mime_type not in FORBIDDEN_MIME_TYPES


Expand Down
29 changes: 29 additions & 0 deletions server/mergin/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,3 +402,32 @@ def test_mime_type_validation_skip():

# Should be forbidden
assert not is_supported_type("other.js")


def test_allowed_extensions_override():
"""Extensions in UPLOAD_EXTENSIONS_WHITELIST are accepted even though they are in FORBIDDEN_EXTENSIONS."""
with patch(
"mergin.sync.utils.Configuration.UPLOAD_EXTENSIONS_WHITELIST", [".py", ".sh"]
):
# forbidden by default, now explicitly allowed
assert is_supported_extension("model.py")
assert is_supported_extension("scripts/deploy.sh")
# match is case-insensitive
assert is_supported_extension("MODEL.PY")
# extensions not in the override stay blocked
assert not is_supported_extension("malware.exe")
assert not is_supported_extension("app.js")


def test_allowed_mime_types_override():
"""MIME types in UPLOAD_MIME_TYPES_WHITELIST are accepted even though they are in FORBIDDEN_MIME_TYPES."""
with patch("mergin.sync.utils.get_mimetype", return_value="text/x-shellscript"):
# blocked by default
with patch("mergin.sync.utils.Configuration.UPLOAD_MIME_TYPES_WHITELIST", []):
assert not is_supported_type("deploy.sh")
# explicitly allowed
with patch(
"mergin.sync.utils.Configuration.UPLOAD_MIME_TYPES_WHITELIST",
["text/x-shellscript"],
):
assert is_supported_type("deploy.sh")
Loading