From DJ Hanson at Smartsheet
Speaking as Director of Information Security @Smartsheet, we are grateful to Mr. Trigo for his continuing research on our platform, and the professional manner in which he conducts his responsible disclosure practices. The nature and pattern of this particular issue is such that we are able to conclude that this vector was never exploited by anyone other than Mr. Trigo, working against two accounts under his direct control. Within 4 hours of being made aware of this, our security, operations, quality assurance, and development teams deployed an update to our platform, eliminating the flaw.
We can unequivocally state that there was no disclosure or impact to any customer accounts or data. It is our view that openly rewarding and celebrating the findings of well-intentioned researchers is an essential part of a healthy and mature security program. We have been very impressed with the work and quality of the researchers @Bugcrowd and hope to continue our relationship with them and their community of professionals.
This blog post is about the vulnerability I found in Smartsheet.com as part of its private bug bounty program via Bugcrowd. The bug lies in the “import users” feature of Smartsheet which allows anyone with malicious intent to hijack and fully take over millions of Smartsheet accounts.
As according to its website, Smartsheet is a “Software as a Service” (SaaS) company which offers enterprise-ready cloud app for work management and collaboration. The company states that it has 65,000 businesses and millions of users in over 175 countries.
About and how I found the Bug:
The bug is clearly an insecure direct object references which again, allows anybody to hijack Smartsheet accounts without user interaction.
It was my first time to be invited in a Bugcrowd private program so I decided to give it a try. The time of launch is 1600 GMT on April 7 this year – that is 12:00 AM here in the Philippines.
As part of my testing methodology, access control vulnerabilities are the first on my lists. I registered two (2) accounts for testing purposes where account 1 served as the attacker while the other is the victim account.
On browsing the Smartsheet Dashboard, I observed that it allows you to Import Users in “User Management” page – Account administration. It was the erring page.
In the import process, you need a csv file and set up it with columns First Names, Last Names and Email. What was interesting is that you can also pre-select roles for the account to be imported.
The roles are:
- licensed user ( can create and own sheets )
- system admin ( can manage users and accounts )
- group admin ( can create and edit groups )
- resource viewer ( can access resource views )
During my testing, I imported a csv file with my controlled user details ( email address ) against my victim account and was given all permissions. The import was successful, and I had verified there was a bug in the “import user” feature/section.
Bug Technical Details:
The flaw resides in /b/uploadimport endpoint. While processing the POST request, it actually has multiple parameters but what caught my attention is the value of parm1, which is my user id (1071208).
POST /b/uploadimport HTTP/1.1 Host: app.smartsheet.com Connection: keep-alive Content-Length: 1009 Origin: https://app.smartsheet.com User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryQX3fAkoAQI8uwbiZ Accept: */* Referer: https://app.smartsheet.com/b/home Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.8,fil;q=0.6,zh-TW;q=0.4 Cookie: redacted fa_importOrgUsers ------WebKitFormBoundaryQX3fAkoAQI8uwbiZ Content-Disposition: form-data; name="parm1" 1071208
You only need to change the value of that parameter to your target account ( I used burp proxy during the testing ).
You will get a 200 OK response:
HTTP/1.1 200 OK Server: Apache Vary: X-Forwarded-For,Accept-Encoding x-smartsheet-instance-id: nominal.ss-app-1609 Cache-Control: max-age=0 Cache-Control: no-cache Cache-Control: must-revalidate Pragma: no-cache Expires: Thu, 01 Jan 1970 00:00:00 GMT Content-Length: 22 Connection: close Content-Type: text/plain;charset=UTF-8
It became possible because there was no check whether the user who is requesting the import has the the right privilege.
Below is the full HTTP request:
Steps to Reproduce (modified, used in my actual submission):
(Two accounts are needed, account 1 as attacker and account 2 as victim)
- Authenticate your attacker account
- Click on ” Account ” Menu in the left side of the screen
- Another form will pop up, click on ” User Management ” then ” Import Users”
- Select your excel file with user details, controlled email address
- Tick on admin permissions 1,2,3,4 for full permission of our account to be imported.
- Before hitting import, fire up your intercepting proxy ( Burp )
- Hit the import button now and you will see the request just like above
- Change the value of parm1 which is 1071208 to your victim – target account
- Forward the request
- A verification email will be sent to our imported – attacker controlled email, follow the link in the email
- Exploit successful.
Smartsheet fixed the vulnerability and awarded me the maximum bounty in its program – $2,000.
Thank you Smartsheet for the permission to disclose this bug! :)