Header-Bar

May 22, 2013

Stored Cross-site Scripting in Linkedin





Hello all,


Since Linkedin has no bug bounty program, all you need to do when finding one is to inform them about the vulnerability and you can post away.

The following vulnerability was found while I was using Linkedin's customer support, submitting a question regarding my account.


This request created a Ticket in the system with the form's details.
As you probably haven't noticed yet, the form has a [Browse] option to upload files regarding the form.
A smart move from Linkedin will be to send the attached file to an inaccessible directory within the application's server. for instance:
/var/www/help.linkedin.com/TheWebSite/upload-a-file-with-form --> user uploads file

/var/www/uploads/files/ --> file will be saved here

Instead of doing that, Linkedin created the ability for the user to watch his file after upload.

At first I didn't believe the possibility of this happening so I haven't even tried to upload a file.
Instead I went to the "Support History" Just to check that my ticket is Open.


Now after opening the ticket to review. I noticed an odd feature - Update your ticket.
So I thought to myself: "Well if I'm updating my ticket.. I will be able to view the update, right?"
The update includes a file.. so...


As you can see, after a quick exploit of that upload module I tried some more variants.

Furthermore, the blue marker  on the files names is of course a link to its path on the server.
Pressing that link will take you to the malicious Javascript.

Here is the path: http://help.linkedin.com/ci/fattach/get/2430905/1369216961/filename/ticket.html
**Don't worry, the script is only <script>alert(document.cookie)</script>



Let's fix that:

In order to prevent a malicious user from executing malicious scripts we first want to create a secured environment for the script to execute from. Away from the users permissions.
So first solution will be to store the file "behind" the application, and apply the right permission on that directory and files.

2nd solution will be to create a WhiteList of file extensions saying: "Hi dude, This file you're trying to upload is not registered in our list of permitted files, so please stop making a fool out of yourself!"
The code should look something like that:
---------------------------------------------------------------------------------------------------------------
if(file.extension(equals(jpg) || file.extension(equals(doc) || file.extension(equals(pdf)){
//upload the file
}
else {
 print("Hi dude, only the following are allowed: jpg, doc, pdf");
}
----------------------------------------------------------------------------------------------------------------

Consider restricting the size of the file to prevent exhausting the server resources and maybe also set the Content-type: HTTP header to render the page as text, preventing unrestricted executions.

I can think of more solutions, but I'll leave you to it.

Hope you enjoyed reading.

Ido Naor



No comments:

Post a Comment