feat(security): enforce strict file-type validation on uploads#3092
Open
ukanga wants to merge 12 commits into
Open
feat(security): enforce strict file-type validation on uploads#3092ukanga wants to merge 12 commits into
ukanga wants to merge 12 commits into
Conversation
| ``settings.id_string``. | ||
| """ | ||
| extension = os.path.splitext(os.path.split(filename)[1])[1].lower() | ||
| return os.path.join(instance.user.username, "xls", f"{uuid.uuid4().hex}{extension}") |
Contributor
There was a problem hiding this comment.
What could be the negative implications of doing this? I guess one is that downloading an XLS file now will have the random name instead of the original name?
Member
Author
There was a problem hiding this comment.
Only if accessing the storage directly, not through the API. By default, the downloaded file will now have the {id_string}.{extension} format. For example, the form Registration Form with the id_string = 'reg_form' will result in the XLSForm file reg_form.xlsx.
| except UploadValidationError as error: | ||
| raise ValidationError({"data_file": str(error)}) from error | ||
|
|
||
| data_file.name = upload.storage_basename |
Contributor
There was a problem hiding this comment.
This implementation appears similar to supporting_docs docs implementation. Can we DRY?
| return os.path.join(username, "xls", os.path.split(filename)[1]) | ||
| original_basename = os.path.split(filename)[1] | ||
| extension = os.path.splitext(original_basename)[1].lower() | ||
| return os.path.join(username, "xls", f"{uuid.uuid4().hex}{extension}") |
Contributor
There was a problem hiding this comment.
This implementation is similar to the one in xform.py, can we DRY?
0f4c038 to
8b2db81
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes / Features implemented
Deny-by-default upload validation across all entry points via a central
upload_validationmodule: per-extension MIME allowlist + magic-byte/structural content checks, configurable size caps (STRICT_UPLOAD_MAX_BYTES), and UUID storage names so client-supplied filenames never reach disk. Covers XLSForm publishing, CSV/XLS imports, form media, and supporting docs. Adds an RFC 6266Content-Dispositionparser and setsX-Content-Type-Options: nosniffon file downloads.Steps taken to verify this change does what is intended
flake8,isort,blackclean; unit tests for the validator and parser pass.Side effects of implementing this change
Stricter uploads: the legacy content-type-only allowlist (and audio/SVG/DOC-OLE/ZIP types) is removed. Operators raising a per-extension cap must also raise nginx
client_max_body_size.Before submitting this PR for review, please make sure you have:
Closes #