From b7d80f9000fc9a435743d8d1d7d44d9a17483a9a Mon Sep 17 00:00:00 2001
From: Zoran Ilibasic <zilibasic@s7designcreative.com>
Date: Wed, 11 Dec 2019 10:17:56 +0100
Subject: [PATCH] Improved handling of the uploaded inline images.

---
 CHANGES.md                            |  1 +
 Kernel/Modules/PictureUpload.pm       | 36 +++++++++++++++++++++++
 scripts/test/Frontend/PictureUpload.t | 41 +++++++++++++++++++++++++++
 3 files changed, 78 insertions(+)

--- a/Kernel/Modules/PictureUpload.pm
+++ b/Kernel/Modules/PictureUpload.pm
@@ -85,6 +85,24 @@ sub Run {
                 );
             }
 
+            if ( $Attachment->{ContentType} =~ /xml/i ) {
+
+                # Strip out file content first, escaping script tag.
+                my %SafetyCheckResult = $Kernel::OM->Get('Kernel::System::HTMLUtils')->Safety(
+                    String       => $Attachment->{Content},
+                    NoApplet     => 1,
+                    NoObject     => 1,
+                    NoEmbed      => 1,
+                    NoSVG        => 0,
+                    NoIntSrcLoad => 0,
+                    NoExtSrcLoad => 0,
+                    NoJavaScript => 1,
+                    Debug        => $Self->{Debug},
+                );
+
+                $Attachment->{Content} = $SafetyCheckResult{String};
+            }
+
             return $LayoutObject->Attachment(
                 Type => 'inline',
                 %{$Attachment},
@@ -129,6 +147,24 @@ sub Run {
         );
     }
 
+    if ( $File{ContentType} =~ /xml/i ) {
+
+        # Strip out file content first, escaping script tag.
+        my %SafetyCheckResult = $Kernel::OM->Get('Kernel::System::HTMLUtils')->Safety(
+            String       => $File{Content},
+            NoApplet     => 1,
+            NoObject     => 1,
+            NoEmbed      => 1,
+            NoSVG        => 0,
+            NoIntSrcLoad => 0,
+            NoExtSrcLoad => 0,
+            NoJavaScript => 1,
+            Debug        => $Self->{Debug},
+        );
+
+        $File{Content} = $SafetyCheckResult{String};
+    }
+
     # check if name already exists
     my @AttachmentMeta = $UploadCacheObject->FormIDGetAllFilesMeta(
         FormID => $FormID,
--- a/scripts/test/Frontend/PictureUpload.t
+++ b/scripts/test/Frontend/PictureUpload.t
@@ -144,4 +144,45 @@ $Self->True(
     'Response check for CKEditor error handler',
 );
 
+## nofilter(TidyAll::Plugin::OTRS::Whitespace::Tabs)
+my $ContentSVG = <<'EOF',
+<?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.domain);</script></svg>
+EOF
+    ;
+
+my $EscapedContentSVG = <<'EOF',
+<?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"/>
+</svg>
+EOF
+    ;
+
+# Upload svg image with png file and script element.
+$Response = $UserAgent->post(
+    $BaseURL,
+    Content_Type => 'form-data',
+    Content      => {
+        Action => 'PictureUpload',
+        FormID => $FormID,
+        upload => [
+            undef, 'index4.png',
+            'Content-Type' => 'image/svg+xml',
+            Content        => $ContentSVG,
+        ],
+    }
+);
+
+$CheckUpload->(
+    Successful => 1,
+    Content    => $EscapedContentSVG,
+);
+
 1;
