Skip to content

Commit

Permalink
Enable additional upload validators for django-attachments
Browse files Browse the repository at this point in the history
to block files which may be executed by the browser and cause an issue
with users who aren't careful.

Test with .exe file from React OS!
  • Loading branch information
atodorov committed Apr 20, 2023
1 parent 9c1f356 commit 551dff9
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 1 deletion.
15 changes: 15 additions & 0 deletions docs/source/modules/tcms.kiwi_attachments.rst
@@ -0,0 +1,15 @@
tcms.kiwi\_attachments package
==============================

.. automodule:: tcms.kiwi_attachments
:members:
:undoc-members:
:show-inheritance:

Submodules
----------

.. toctree::
:maxdepth: 4

tcms.kiwi_attachments.validators
7 changes: 7 additions & 0 deletions docs/source/modules/tcms.kiwi_attachments.validators.rst
@@ -0,0 +1,7 @@
tcms.kiwi\_attachments.validators module
========================================

.. automodule:: tcms.kiwi_attachments.validators
:members:
:undoc-members:
:show-inheritance:
1 change: 1 addition & 0 deletions docs/source/modules/tcms.rst
Expand Up @@ -15,6 +15,7 @@ Subpackages
tcms.bugs
tcms.core
tcms.issuetracker
tcms.kiwi_attachments
tcms.kiwi_auth
tcms.management
tcms.rpc
Expand Down
Empty file.
14 changes: 14 additions & 0 deletions tcms/kiwi_attachments/apps.py
@@ -0,0 +1,14 @@
from attachments.apps import AttachmentsConfig

from . import validators


class AppConfig(AttachmentsConfig):
"""
Defines custom form validators!
"""

attachment_validators = (
validators.deny_uploads_ending_in_dot_exe,
validators.deny_uploads_containing_script_tag,
)
Empty file.
29 changes: 29 additions & 0 deletions tcms/kiwi_attachments/tests/test_validators.py
@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# pylint: disable=attribute-defined-outside-init, invalid-name, objects-update-used

import base64
from xmlrpc.client import Fault

from tcms.rpc.tests.utils import APITestCase


class TestValidators(APITestCase):
def test_uploading_svg_with_inline_script_should_fail(self):
with open("tests/ui/data/inline_javascript.svg", "rb") as svg_file:
b64 = base64.b64encode(svg_file.read()).decode()

with self.assertRaisesRegex(Fault, "File contains forbidden <script> tag"):
self.rpc_client.User.add_attachment("inline_javascript.svg", b64)

def test_uploading_filename_ending_in_dot_exe_should_fail(self):
with self.assertRaisesRegex(Fault, "Uploading executable files is forbidden"):
self.rpc_client.User.add_attachment("hello.exe", "a2l3aXRjbXM=")

def test_uploading_real_exe_file_should_fail(self):
with open("tests/ui/data/reactos_csrss.exe", "rb") as exe_file:
b64 = base64.b64encode(exe_file.read()).decode()

with self.assertRaisesRegex(
Fault, "Uploading executable files is forbidden"
):
self.rpc_client.User.add_attachment("csrss.exe_from_reactos", b64)
23 changes: 23 additions & 0 deletions tcms/kiwi_attachments/validators.py
@@ -0,0 +1,23 @@
from django.forms import ValidationError
from django.utils.translation import gettext_lazy as _


def deny_uploads_containing_script_tag(uploaded_file):
for chunk in uploaded_file.chunks(2048):
if chunk.find(b"<script") > -1:
raise ValidationError(_("File contains forbidden <script> tag"))


def deny_uploads_ending_in_dot_exe(uploaded_file):
message = _("Uploading executable files is forbidden")

if uploaded_file.name.find(".exe") > -1:
raise ValidationError(message)

if uploaded_file.content_type in [
"application/vnd.microsoft.portable-executable",
"application/x-dosexec",
"application/x-ms-dos-executable",
"application/x-msdownload",
]:
raise ValidationError(message)
2 changes: 1 addition & 1 deletion tcms/settings/common.py
Expand Up @@ -294,10 +294,10 @@
TENANT_APPS = [
"django.contrib.sites",
"guardian",
"attachments",
"django_comments",
"modernrpc",
"simple_history",
"tcms.kiwi_attachments.apps.AppConfig",
"tcms.core.contrib.linkreference",
"tcms.management",
"tcms.testcases.apps.AppConfig",
Expand Down
Binary file added tests/ui/data/reactos_csrss.exe
Binary file not shown.

0 comments on commit 551dff9

Please sign in to comment.