Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Enable additional upload validators for django-attachments
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.