Vulnerability Development mailing list archives

Myspace.com - Intricate Script Injection


From: silentproducts () gmail com
Date: 6 Apr 2006 03:15:57 -0000

Original: http://www.silent-products.com/advisory4.5.06.txt

Myspace.com - Intricate Script Injection Vulnerability
Reported April 5th, 2006

Introduction
----------------
The following article details a real vulnerability within the major social network Myspace.com.  The seriousness of 
this script injection outweighs the currently publically known LIVE holes in the social network in that it is capable 
of being injected ANYWHERE HTML is enabled (mail messages, forums, profiles); in contrast, vulnerabilities like where 
EMBED tags are NOT filtered only in users profiles and HTML-comments, ect (as to say JavaSCRIPT is not ok... but Java 
is).

The technical details of this article is beneficial not only in outlining the serious state of social network 
insecurity at Myspace.com, but also as a very rare excercise in different methods for client-side exploitation and 
protection.  The script injection vulnerability is not a normal, simplistic incident of poor filters; instead it is a 
vulnerability within the code of javascript libaries that allows malformed tag IDs to inject script.  The approach of 
the article is to detail the technicalities of the problem and how one would go about to successfully manipulate and 
exploit the vulnerability given a small quirk and a good bit of innovation.

Again I stress - this is NOT a case of poor input validation on the SERVERS side, but within the client-side ran 
javascript libraries.  This is an important note as Myspace.com apparently did NOT realize this (nor would accept any 
recommendation) and incorrectly patched the flaw.  Details of the current state of this vulnerability will be at the 
end of the article.

Script Injection Within the OnlineNow Mechanism
------------------------------------------------------------------------
The OnlineNow Mechanism:
        Within almost every page on the website there are embedded scripts that define the functions and objects 
necessary to dynamically provide online/offline status of users on Myspace.  Within the provided HTML there are 
specific <div> tags that are to be handled by the functions.  They are typically placed underneath the picture of the 
"friend" and passes the specific friendID of the the friend to the OnlineNow functions.  An example of such a tag is as 
follows:
<div style="width: 80px; height: 20px;" id="UserDataNode0" class="DataPoint=OnlineNow;UserID=17601323;"></div>
The ID of these tags follows the format of 'UserDataNodeN'  - where the value of N increases in sequential order from 0 
to (the number of tags - 1).  At the end of the HTML the OnlineNow mechanism is called which finds all the tags, parses 
out all the UserIDs specified in the class property and passes them to an iframe which calls on a web-application that 
returns a true/false value specifying whether that FriendID is found to be "online now".  The flow of code proceeds to 
then find all of these friendIDs that were found to be online and set the DIV tag's innerHTML to display an image that 
shows the user is online within the browser display.

The OnlineNow Vulnerability:
        There is a script injection vulnerability within this mechanism specifically found during the searching and 
parsing of the <div> tags.  I will be extensively referencing the function _OnlineNowNodeParser_locateNodes() found in 
OnlineNowNodeParser.js.  A copy of the function will be placed here for such reference:

function _OnlineNowNodeParser_locateNodes()
{
    var CurrentNode = null;
    var i = 0;
    while ((CurrentNode = document.getElementById("UserDataNode" + i)) != null)
    {
        NodeIndex = this.NodeArray.length;
        this.NodeArray[NodeIndex] = new Object();
        this.NodeArray[NodeIndex].NodeID = CurrentNode.id;
        var Attributes = CurrentNode.className.split(";");
        for (var AttributeIterator = 0; AttributeIterator < Attributes.length; AttributeIterator++)
        {
            var Name = Attributes[AttributeIterator].split("=")[0];
            var Value = Attributes[AttributeIterator].split("=")[1];
            if (Name != "" && Value != "") eval("this.NodeArray[" + NodeIndex + "]." + Name + "=\"" + Value + "\";");
        }
        i++;
    }
}

What is going on here is the function initiates a loop starting from i = 0 which checks for the existence of an element 
with an ID with the format "UserDataNode" + i.  It then splits the semicolon delimited class property and extracts a 
Name and Value combination from the format Name=Value (i.e. 
class="DataPoint=OnlineNow;UserID=17601323;" will create two Name and Value variable combinations Datapoint & OnlineNow 
and UserID & 17601323).  These variables are then passed to an eval() function which creates the property of the object 
this.NodeArray[i].Name and sets it to the Value (i.e. eval('this.NodeArray[0].DataPoint="OnlineNow";');  There is no 
sanitization of the variables 'Name' and 'Value' passed to the eval() function within the locateNodes() function beyond 
that of semicolon and equal sign which is consequence of the way the delimitation works.  Most importantly - one can 
pass quotes to the eval function and due to the nature of javascript one can execute arbitrary functions.  To show how 
this can be done in exploit consider the following tag:
<div id="UserDataNode0" class='UserID=17601323"+String.fromCharCode(59)+";'></div>
This will generate a call to the eval() function in the following manner:
eval('this.NodeArray[0].UserID="17601323"+String.fromCharCode(59)+"";')
Which one can easily see will set this.NodeArray[0].UserID to the value of 17601323; (the function 
String.fromCharCode(59) returns a semicolon).  The function specified is not limited to string-type functions, it would 
be valid javascript being any function; however, without semicolons nor quotes there is not a terrible amount one can 
do without any trick.  It follows then that one can call on an additional eval() function which uses the 
String.fromCharCode() function to generate filtered characters.  The following shows a line of javascript that does 
exactly this.
The function - String.fromCharCode(118,97,114,32,119,61,51,59,97,108,101,114,116,40,119,41,59) returns the string "var 
w=3;alert(w);"
By compounding this with eval() as so:
eval(String.fromCharCode(118,97,114,32,119,61,51,59,97,108,101,114,116,40,119,41,59));
A variable 'w' will be defined with value 3 and a messagebox will display it's value.  The following tag - when passed 
to our locateNodes() function - will execute the aforementioned line of code:
<div id="UserDataNode0" 
class='UserID=17601323"+eval(String.fromCharCode(118,97,114,32,119,61,51,59,97,108,101,114,116,40,119,41,59))+";'></div>
The string generated by fromCharCode(); can be any script the exploiter specifies.  It is composed only of numbers and 
commas so no filters affect it.  Our exploit is almost complete.  One last obstacle remains in order to exploit this 
script injection vulnerability.  The web-application filters of Myspace filter specific tags and words to hamper the 
possibility of script injection (for example the <script> tag would be filtered).  Among this extensive list of 
filtered words - eval is one of them.  If one tries to actually put the above tag into Myspace the eval will be 
stripped out and the exploit will fail.  We require one last trick.  The eval() function is not the only javascript 
function that will evaluate a string as javascript code.  A less-intuitive method is using the setTimeout function 
which evaluates a string after a specified amount of time has elapsed.  setTimeout("expression",0); is nearly identical 
to eval("expression"); in functionality (the difference being 
 in that the timer function has a seperate thread it executes in which is important in considering race-type 
conditions) and is NOT filtered by Myspace.  The following tag when placed within the realms of Myspace will execute 
the line
document.location="http://www.google.com";; (the actual script to be injected with this exploit is completely arbitrary 
and without limitations):

<div id="UserDataNode0" 
class='UserID=17601323"+setTimeout(String.fromCharCode(100,111,99,117,109,101,110,116,46,108,111,99,97,116,105,111,110,61,34,104,116,116,112,58,47,47,119,119,119,46,103,111,111,103,108,101,46,99,111,109,34,59),0)+";'></div>

The only possible limitation to the script to be injected is field length - which a knowing exploit-writer should have 
no problems subverting.  The content in this advisory is a little harder to swallow than your everyday bad filter 
script-injection vulnerability, but should not be too big of a problem for anyone with a history of working with 
javascript and web-application vulnerabilities.

Additional Commentary On Exploit Development:
        I'd like to make additional notes about exploit development.  Even though I've stuck with using the <div> 
element in describing the vulnerability and writing the exploit - it should  be apparent by those who look at the 
function that the element is not found by the the type of tag but solely by the ID property (using getElementByID).  
Knowing this - the exploit can use ANY element tag (not <div> alone) for they only need to specify the ID as having the 
"UserDataNodeN" tag.  If Myspace were to start filtering <div> tags in the face of this vulnerability - it would not 
correctly patch it.  One can just as easily used the allowed <img> tag to exploit the vulnerability like so:
<img id="UserDataNode0" 
class='UserID=17601323"+setTimeout(String.fromCharCode(100,111,99,117,109,101,110,116,46,108,111,99,97,116,105,111,110,61,34,104,116,116,112,58,47,47,119,119,119,46,103,111,111,103,108,101,46,99,111,109,34,59),0)+";'
 src="blah.jpg">
        I also expect that it is understood that there are other means (some probably more efficient) for exploiting 
this vulnerability.  For example - if the service begins to filter out fromCharCode then one would just have to use 
another means of encrypting/decrypting the data to pass the filters such as using unescape() (which would give room to 
far more efficiency in regards to payload length).  The vulnerability is not within the WEB-APPLICATIONS filters, but 
instead in the JAVASCRIPT APPLICATIONS filters.  This is the point to be stressed in this article in regards to the 
nature of the exploits.  A proper patch would not create anymore filters server-side on Myspace, but rather a change in 
the .js library.

Conclusion and Overview
------------------------------------
The current described exploit will not work on Myspace.com to date; however, the patch employed did not correctly 
address the issue as had been mentioned earlier.  Instead of fixing the flawed javascript function, Myspace 
incorporated a filter on it's fields for UserDataNode.  Any input with 'UserDataNode' is replaced with a double dot.  
This leaves a vulnerable layer, but can hold up assuming the servers filters can completely hold up with the input.  
Unfourtnately, this is not the case and there are a good number of active, live vulnerabilities within the social 
network and some for the specific ability to circumvent filters that have been revealed with my own short auditing and 
others being passed around in the underground community.

The security consciousness within Myspace.com appears to be poor to say to the least.  In my own experiences of trying 
to touchbase with the right people and trying to work with them in strengthening security - my motions were not 
accepted with any kindness most times and at others had not been acknowledged at all.  It would seem that very few 
people on staff have any degree of understanding of the seriousness of vulnerabilities within a social network that 
stores information on millions of people, with millions of active users, and a huge YOUNG demographic - and any that do 
seem to make themselves out of reach.

It is my own opinion that, esspecially amidst the attention they have been getting in the media with predators using 
Myspace as a tool to target children and incidents of child pornography found within the domain, they would have an 
exceptional interest and concern for the security of it's users.  If security cannot be addressed within Myspace there 
are a great number of just as good clones that provide more attention to this issue.  Such alternatives as Tagworld.com 
have been getting an increase in popularity due to its integrity and better model.  I do not know of reports in 
auditing Tagworld or others, but it would be worth it to look into these alternatives to find a company that could 
provide a social experience without providing a security threat.

Justin Lavoie
silentproducts () gmail com


Current thread: