LinkedIn Vulnerability

LinkedIn is a business-oriented social networking site. Founded in December 2002 and launched in May 2003, it is mainly used for professional networking. As of 22 March 2011, LinkedIn reports more than 100 million registered users, spanning more than 200 countries and territories worldwide.

There exists multiple vulnerabilities in LinkedIn in which it handles the cookies and transmits them over SSL. This vulnerability if exploited, can result in hijacking of user accounts, and/or modifying the user information without the consent of the profile owner.

Executive Summary

Name: LinkedIn SSL Cookie Vulnerability (SESSION and AUTH TOKEN)
Severity: High

I received some comments recently through different mediums & channels, so, if you need any details or clarifications please contact me through Twitter and/or Mail address as mentioned above.

Background Information

LinkedIn can be accessed over HTTPS and HTTP connections. The sign-in page if accessed on HTTPS, redirects you to HTTP on successful authentication. By default the welcome page stores the following important cookies (highlighting only the SESSION and AUTH TOKEN in scope),

After successful login (over HTTPS or HTTP), the value of cookies should change, specifically, the JSESSIONID and AUTH_TOKEN. The SESSIONID remains the same no matter what or if the browser exits, the server sends a new SESSIONID. Now, lets see how leoauthtoken changes after successfully authentication and login …

JSESSIONID

Ideally this cookie is used for tracking session and thus it has an ID generated to track that session in the application and server logs. As per information available online, JSESSIONID cookie is created/sent when session is created. Session is created when your code calls request.getSession() or request.getSession(true) for the first time. If you just want get session, but not create it if it doesn’t exists, use request.getSession(false) — this will return you a session or null. In this case, new session is not created, and JSESSIONID cookie is not sent. This also means that session isn’t necessarily created on first request; you and your code is in control when the session is created.

Example: JSESSIONID="ajax:2960939797451683300" . And, the syntax for this session id is → ajax:<19 digit code>

LEO_AUTH_TOKEN

There is not much information available on this cookie in my knowledge, but I could relate some sections as following.

Example: leo_auth_token="LIM:118607520:a:1305884679:b42ee51919add89581a0b49ebe1e420dbb93a468" (Only highlighted key reference available below)

  • 118607520: This is the User ID. It can also be verified when viewing someone’s profile. It traverses in the traffic unencrypted and is also available in GET requests.
  • 1305884679: Special thanks to Julio for clarification that this is a Unix Timestamp of the time user logs in. (Refer: http://www.onlineconversion.com/unix_time.htm). This Unix Timestamp will also decide the expiry date of the cookie. (1 year from this time which is too much for an attacker)
  • b42ee51919add89581a0b49ebe1e420dbb93a468: This is a approx. 40 character long hexadecimal string. It can be smaller or larger and is not fixed in length. I am still working if this can be decrypted or can be related/tied to some part of the session.

In general these two (2) cookies are enough to verify a session, and both the cookies have to be defined in "quotes" and here is a sample POST request (used in LinkedIn status update) for reference,

POST http://www.linkedin.com/share?submitPost= HTTP/1.1 
Content-Type: application/x-www-form-urlencoded; charset=UTF-8 
Cookie: leo_auth_token="LIM:118607520:a:1305884679:b42ee51919add89581a0b49ebe1e420dbb93a468";JSESSIONID="ajax:2960939797451683300"

ajax=true&postText=TEST_STATUS&postVisibility=EVERYONE&csrfToken=ajax:2960939797451683300

This request results in changing the User Status on the profile page. So, what and where is the vulnerability here?

Vulnerability Information

There are two (2) vulnerabilities in reference to the cookies (communication channel and session lock) as explained below,

1. SSL cookie without secure flag set

It means that all the cookies including the JSESSIONID and LEO_AUTH_TOKEN are available in plain text over unencrypted channel of communication. These cookies appear to contain session tokens, which may increase the risk associated with the authentication procedure. One should review the contents of the cookies to determine their function and the need for encryption.If the secure flag is set on a cookie, then browsers will not submit the cookie in any requests that use an unencrypted HTTP connection, thereby preventing the cookie from being trivially intercepted by an attacker monitoring network traffic. If the secure flag is not set, then the cookie will be transmitted in clear-text if the user visits any HTTP URLs within the cookie’s scope.

Impact

An attacker may be able to perform an MITM attack, and thus capture these cookies from an established LinkedIn session. Even if the domain which issued the cookie does not host any content that is accessed over HTTP, an attacker may be able to use links of the form https://www.linkedin.com to perform the same attack.

Workaround

The secure flag should be set on all cookies that are used for transmitting sensitive data when accessing content over HTTPS. If cookies are used to transmit session tokens, then areas of the application that are accessed over HTTPS should employ their own session handling mechanism, and the session tokens used should never be transmitted over unencrypted communications.

2. Cookie Expiration & Session Handling

It means that the cookie for an authenticated session is available even after the session has been terminated or way beyond the date of expiry (instead compared to session logout, it is valid for 1 year). There are examples where cookies are accessible to hijack authenticated sessions. And these cookies are months old (literally). As a result, in just 15 minutes, I was successfully able to access multiple active accounts that belong to individuals from different global locations. They would have login/logged out many a times in these months but their cookie was still valid.

Even though the cookie expiry date is mentioned still the cookies are valid. Why does LinkedIn keeps the cookie active even if the user has "logged out" and closed the session? Worse, when the same has been done a hundred times!

Impact

As a result of valid cookies, an attacker can sniff the cookies from clear-text session (explained above), and then use it to authenticate its own session. He can then compromise and modify the information available at the user profile page.

Workaround

The expiry date/time should be locked with either a fixed ‘period’, or user’s session logout or IP etc. In absence of a fixed and reasonable expiration time period (1 year is not reasonable/acceptable), a cookie is active even after months and year of its authentication. Define expiration as the end of session or till the JSESSIONID is valid.

Curious case of JSESSIONID

As I mentioned about the JSESSIONID above, ideally the session should be mapped with this ID, and if tampered with, should disconnect the session. At least, I would believe it to work this way! But now, even if you change the JSESSIONID to ajax:0000000000000000000 (ajax followed by 19 digits) the session is still valid and the server continues accepting requests with this JSESSIONID.

Even if it has nothing to do with session but only tracking, tinkering with SESSION id surely will dangle the tracking at the server end.

LinkedIn Status Update Bash Script

Here is a small script to update the status at the LinkedIn profile page through command-line. It takes the input as LIM:XXXX cookie value and new status update.

#!/bin/bash
clear 
echo "" 
echo " ==================================================" 
echo " #          LinkedIN Status Update Script         #" 
echo " #                    —————————–                  #" 
echo " #               Author: Rishi Narang             #" 
echo " #              — WWW.CYBERSINS.COM –             #" 
echo " #                                                #" 
echo " ==================================================" 
echo ""
echo -en " – Auth Cookie (Format – LIM:XXXX): " 
read LIM

echo -en " – New Status: " 
read UPDATE

curl -s -b "leo_auth_token=\"${LIM}\";JSESSIONID=\"ajax:0000000000000000000\"" -d\
"ajax=true&postText=$UPDATE&postVisibility=EVERYONE&csrfToken=ajax%3A0000000000000000000"\
http://www.linkedin.com/share?submitPost= -o linKIN.tmp

echo "" 
OUT=`cat linKIN.tmp | grep "SUCCESS" | wc -l` 
DUP=`cat linKIN.tmp | grep "DUPLICATE" | wc -l`

if [ $OUT -eq 1 ] 
then 
    echo -e "MSG: Status updated successfully!\n"

elif [ $DUP -eq 1 ] 
then 
    echo -e "ERROR: Duplicate Status! Please enter a new status.\n" 
    exit 
else 
    echo -e "ERROR: Please try again later.\n" 
fi 
rm -rf linKIN.tmp 
echo ""

#EOD

This is all from my side, and use this information responsibly till LinkedIn fixes the vulnerability!

Real Scenerio

You are connected in a network at office or home and someone captures the cookies in traffic or uses Firesheep and boom! your account is hijacked. You as a user will not come to know that the cookie is stolen or there have been any parallel login by the attacker. And, LinkedIn doesn’t maintain any list of IP addresses (for a user to view at his account) that are being used to access your account as does the Gmail etc.
After some recent developments and some miscommunication, I will make it clear that the password change and then login with new password will expire the old cookie. Only the password change, will keep the old cookie alive so you need minimum 1 time login to let the old cookie expire out. Here is a working video of the vulnerability and how the change of IP address, session logout etc. doesn’t expire the cookies.

On some requests here is a process to show how the cookie validity maintains even after the password is changed (but before a user authenticates with new credentials)

Disclaimer: The author is not responsible for the misuse of the information presented in this blog or anywhere on the domain www.cybersins.com. The ideas discussed on this site are simply ideas and the site or the owner will not be held accountable for any losses or gains that one accrues, if any way linked to the ideas on the site. Examples and methods presented on this post or anywhere on www.cybersins.com pages are for educational purposes only!


❮ Social Network - A forbidden fruit

What to look for in a pentest? ❯

Rishi Narang

I'm a hacker. I find inventive/ intuitive solutions to problems. I write open-source code, help out people where I can - particularly if it involves a clever technical solution. I'm based in France.