Book Image

Mastering Modern Web Penetration Testing

By : Prakhar Prasad, Rafay Baloch
Book Image

Mastering Modern Web Penetration Testing

By: Prakhar Prasad, Rafay Baloch

Overview of this book

Web penetration testing is a growing, fast-moving, and absolutely critical field in information security. This book executes modern web application attacks and utilises cutting-edge hacking techniques with an enhanced knowledge of web application security. We will cover web hacking techniques so you can explore the attack vectors during penetration tests. The book encompasses the latest technologies such as OAuth 2.0, Web API testing methodologies and XML vectors used by hackers. Some lesser discussed attack vectors such as RPO (relative path overwrite), DOM clobbering, PHP Object Injection and etc. has been covered in this book. We'll explain various old school techniques in depth such as XSS, CSRF, SQL Injection through the ever-dependable SQLMap and reconnaissance. Websites nowadays provide APIs to allow integration with third party applications, thereby exposing a lot of attack surface, we cover testing of these APIs using real-life examples. This pragmatic guide will be a great benefit and will help you prepare fully secure applications.
Table of Contents (18 chapters)
Mastering Modern Web Penetration Testing
Credits
About the Author
About the Reviewer
www.PacktPub.com
Preface
Index

SOP


Same-origin policy is a security enforcement found in most common browsers that restricts the way a document or script (or other data) that gets loaded from one origin can communicate and associate with properties of another origin. It's a crucial concept of security which runs web applications of various kinds.

To understand the same-origin policy better, let us consider an example. Imagine that you're logged into your webmail, such as Gmail, in one browser tab. You open a page in another browser tab that has some pieces of JavaScript (JS) that attempts to read your Gmail messages. This is when the same-origin policy kicks in: as soon as an attempt is made to access Gmail from some other domain that is not Gmail then the same-origin policy will prevent this interaction from happening. So, basically, the same-origin policy prevented a random web page which was not a part of Gmail from performing actions on your behalf on an actual Gmail web page.

Allow me to explain more specifically what origin actually means. Origin is considered on the basis of protocol, port number, and, more importantly, the hostname of the webpage. Please note that the path of the page does not matter as long as the rest of the mentioned things are satisfied.

Keep in mind that the same-origin policy is not only for JS but for cookies, AJAX, Flash, and so on. Data stored inside localStorage is also governed by this policy, that is, origin-separated.

The following table exhibits different same-origin policy results based on hostname, port number, and protocol when compared with the origin: http://example.com/meme/derp.html.

URL

Result

Explanation

http://example.com/random/derp.html

Pass

Path does not matter

http://example.com/other/meme/derp.html

Pass

Path does not matter

http://www.example.com/meme/derp.html

Fail

Different domain

http://example.com:8081/meme/derp.html

Fail

Different ports

ftp://example.com/meme/derp.html

Fail

Different protocol

http://demo.example.com/meme/derp.html

Fail

Different domain

http://packtpub.com/meme/derp.html

Fail

Different domain

Demonstration of the same-origin policy in Google Chrome

Now we've geared up with the basics of the same-origin policy, let me try to demonstrate an example in which I'll try to violate the same-origin policy and trigger the security mechanism:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>SOP Demo</title>
</head>
<body>
  <iframe src="http://example.com" name="demo"></iframe>

  <script>
  document.getElementsByName('demo')[0].onload = function() {
    try {
      console(frames[0].hostname)
    } catch(e) {
      console.log(e);
    }
  }
  </script>
</body>
</html>

As soon as this code runs inside the Chrome browser, it throws the following message in the console.log() output:

I ran the script from output.jsbin.com and Chrome's same-origin policy effectively kicked in and prevented output.jsbin.com from accessing the contents of the example.com iframe.

Switching origins

JS provides a way to change origins if certain conditions are met. The document.domain property allows the origin of the current page to change into a different origin, for example origin A can switch to origin B; this will only work if the current page is the subset of the main domain.

Let me explain the mentioned concept with an example. Consider a page running under example.com, which has two iframes, abc.example.com and xyz.example.com. If either of these iframes issues document.domain = 'example.com' then further same origin checks will be based on example.com. However, as I mentioned, a page can't misuse this functionality to impersonate a completely different domain. So, malicious.com cannot issue an origin to change to bankofamerica.com and access the data of it:

This screenshot shows the error thrown by the Google Chrome browser when example.com attempts to impersonate bankofamerica.com by changing its document.domain property.

Quirks with Internet Explorer

As expected, Microsoft Internet Explorer (IE) has its own exceptions to the same-origin policy; it skips the policy checks if the following situations are encountered:

  • IE skips the origin check if the origin falls under the Trust Zone, for example, internal corporate websites.

  • IE doesn't give any importance to port numbers, so http://example.com:8081 and http://example.com:8000 will be considered as the same origin; however, this is won't be true for other browsers. For example, there are browser bugs which can lead to SOP bypass; one such example is an SOP bypass in Firefox abusing the PDF reader – https://www.mozilla.org/en-US/security/advisories/mfsa2015-78/.

Cross-domain messaging

Sometimes, there exists a need to communicate across different origins. For a long time, exchanging messages between different domains was restricted by the same-origin policy. Cross-domain messaging (CDM) was introduced with HTML5; it provides the postMessage() method, which allows sending messages or data across different origins.

Suppose there is an origin A on www.example.com which, using postMessage(), can pass messages to origin B at www.prakharprasad.com.

The postMessage() method accepts two parameters:

  • message: This is the data that has to be passed to the receiving window

  • targetDomain: The URL of the receiving window

Sending a postMessage():

receiver.postMessage('Hello','http://example.com')

Receiving a postMessage():

window.addEventListener('message',function(event) {
  if(event.origin != 'http://sender.com') return;
  console.log('Received:  ' + event.data,event);
  },false);

AJAX and the same-origin policy

As of today, all interactive web applications make use of AJAX, which is a powerful technique that allows the browser to silently exchange data with the server without reloading the page. A very common example of AJAX in use is different online chat applications or functionality, such as Facebook Chat or Google Hangouts.

AJAX works using the XMLHTTPRequest() method of JS. This allows a URL to be loaded without issuing a page refresh, as mentioned. This works pretty decently till the same-origin policy is encountered, but fetching or sending data to a server or URL which is at a different origin is a different story altogether. Let us attempt to load the home page of packtpub.com using a web page located at output.jsbin.com through an XMLHTTPRequest() call. We'll use the following code:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>AJAX</title>
</head>
<body>
  <script>
    var request = new XMLHTTPRequest();
    request.open('GET', 'http://packtpub.com', true);
    request.send();
  </script>
</body>
</html>

As soon as this code runs, we get the following security error inside the Google Chrome browser:

This error looks interesting as it mentions the 'Access-Control-Allow-Origin' header and tells us that packtpub.com effectively lacks this header, hence the cross-domain XMLHTTPRequest() will drop as per security enforcement. Consider an example in which a web page running at origin A sends an HTTP request to origin B impersonating the user and loads up the page, which may include Cross-Site Request Forgery (CSRF) tokens, and then they can be used to mount a CSRF attack.

So the same-origin policy basically makes calling separate origin documents through AJAX functions a problem. However, in the next section, we'll attempt to dig deeper into this.