Bin
2025-12-17 2e6c955be321cefd7e0c4a3031eab805e0a5a303
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
"""This file and its contents are licensed under the Apache License 2.0. Please see the included NOTICE for copyright information and LICENSE for a copy of the license.
"""
import io
 
import pytest
from data_import.models import FileUpload
from django.conf import settings
 
 
@pytest.mark.django_db
def test_svg_upload_sanitize(setup_project_dialog):
    """Upload malicious SVG file - remove harmful content"""
    settings.SVG_SECURITY_CLEANUP = True
 
    xml_dirty = """<?xml version="1.0" standalone="no"?>
                <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
                <svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
                <polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
                <script type="text/javascript">alert(document.cookie);</script>
                </svg>"""
 
    f = io.StringIO(xml_dirty)
 
    endpoint = f'/api/projects/{setup_project_dialog.project.id}/import?commit_to_project=true'
    r = setup_project_dialog.post(endpoint, {'xss_svg.svg': f})
 
    assert r.status_code == 201
 
    expected = """<svg version="1.1" baseprofile="full" xmlns="http://www.w3.org/2000/svg">
    <polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"></polygon>\n
    </svg>\n"""
 
    actual = FileUpload.objects.filter(id=r.data['file_upload_ids'][0]).last().file.read()
 
    assert len(''.join(actual.decode('UTF-8').split())) > 100   # confirm not empty
 
    assert ''.join(expected.split()) == ''.join(actual.decode('UTF-8').split())
 
 
@pytest.mark.django_db
def test_svg_upload_invalid_format(setup_project_dialog):
    """Upload invalid SVG file - still accepted"""
    settings.SVG_SECURITY_CLEANUP = True
 
    xml_dirty = """<?xml version="1.0" standalone="no"?>
                <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
                <svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">gibberish</svg>"""
    f = io.StringIO(xml_dirty)
 
    endpoint = f'/api/projects/{setup_project_dialog.project.id}/import?commit_to_project=true'
    r = setup_project_dialog.post(endpoint, {'xss_svg.svg': f})
 
    assert r.status_code == 201
 
    expected = """
    <svgversion="1.1"baseprofile="full"xmlns="http://www.w3.org/2000/svg">gibberish</svg>
    """
 
    actual = FileUpload.objects.filter(id=r.data['file_upload_ids'][0]).last().file.read()
 
    assert ''.join(expected.split()) == ''.join(actual.decode('UTF-8').split())
 
 
@pytest.mark.django_db
def test_svg_upload_do_not_sanitize(setup_project_dialog):
    """Upload SVG file - do not sanitize file content"""
    settings.SVG_SECURITY_CLEANUP = False
 
    xml_dirty = """<?xml version="1.0" standalone="no"?>
                <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
                <svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
                <polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
                <script type="text/javascript">alert(document.cookie);</script>
                </svg>"""
 
    f = io.StringIO(xml_dirty)
 
    endpoint = f'/api/projects/{setup_project_dialog.project.id}/import?commit_to_project=true'
    r = setup_project_dialog.post(endpoint, {'xss_svg.svg': f})
 
    assert r.status_code == 201
 
    actual = FileUpload.objects.filter(id=r.data['file_upload_ids'][0]).last().file.read()
 
    assert ''.join(xml_dirty.split()) == ''.join(actual.decode('UTF-8').replace('\n', '').split())