Skip to main content

Penetration Testing: Cross Site Request Forgery (CSRF) and Same Origin Policy (SOP)

Firesand: End-to-End Security for your Business
Firesand: End-to-End Security for your Business

Introduction

This is our third article, again it is not directly related to either of our previous articles, though there will be some more JavaScript! So, this time we will focus on Cross Site Request Forgery (XSRF/CSRF) and Same Origin Policy (SOP). 

 


Audience

Who is this article for?

Understanding application layer security threats is important for a wide-range of professions, including:

  • Security Architects and Solution Architects, as they need to understand the potential risks and mitigations to take appropriate design decisions, such as access control.

  • Software Engineers / Developers, because they need to understand how to build their applications in a secure manner and avoid critical mistakes.

  • Security Consultants of various types as they need to understand the risks of what they may be reviewing or consulting on.

  • Penetration Testers who need to understand how to attack these systems!

 


 

What is Cross Site Request Forgery (XSRF/CSRF)?

CSRF is a somewhat dated attack these days, though, it is still most certainly possible under the right conditions! However, back in 2013 and earlier, this was a highly prevalent issue, and in fact, was one of the most common web security issues at the time [1].

CSRF is a form of cross-domain attack, where script loaded from one domain can attack another domain, this exploits the standard behaviour of the HTTP protocol and browsers, as well as the assumption that users would not attack themselves.

 

Users Attacking Themselves

The assumption that most users are unlikely to consciously attack themselves seems like reasonable assumption! So why is it then, in reality, a poor assumption to make? Well, when a user has unwittingly loaded a malicious script into their browser by visiting a malicious site (or one with other security problems, for discussion in other articles!), they may well be unwittingly attacking themselves!

 

Standard HTTP Protocol & Browser Behaviour

Next, what are the standard behaviours of browsers that are exploited by CSRF attacks? This all relates to the design of HTTP and cookies!

When a browser requests a resource from a website, e.g., a page, an image, a CSS file, etc.,  it does so whilst simultaneously passing various headers including security headers and cookies. Cookies are often somewhat misunderstood, whilst they can be used from tracking in a marketing sense (and many are), they also provide a vital function to enable many web sites, or web applications, to function. 

Every time a browser requests a resource, under the original HTTP model, a TCP connection is opened, the resource (e.g. a web page) is requested, the server responds with the desired resource, and the TCP connection is closed. What this means that that there is nothing connecting one request for one page, to a subsequent request for another page. How does a website know that the same user, in the same context, is making a set of requests? The answer, historically, has been cookies. The way cookies are utilised from site to site can vary, in some sites they may simply use a cookie to store a session id, which is then linked to state in memory, or a database, on the server-side. Other sites may use cookies to store session information directly. Or, many sites will use some kind of a combination.

Thus, without cookies, a web site will not know who is using the site from page to page, therefore, activities such as logging in and placing a bet on an iGaming site, or logging into your bank account on a banking site, or logging in and adding to basket will simply not function, in fact, most sites cannot function without these key cookies - and this is often what are referred to as 'Essential Cookies', in the common place cookie notifications.

The following diagram, shows this behaviour following a user visiting the Firesand homepage, and then subsequently clicking through to our iGaming Penetration Testing page.

 

HTTP Behaviour - TCP and Cookies

 

As discussed, first the browser opens a TCP connection to the Firesand webserver, it then submits an HTTP request over that TCP connection, requesting the homepage. The HTTP response includes the desired resource (the homepage), but also sets a cookie enabling the corelation of one request to another. When the user clicks the link for the iGaming Penetration Testing page, the browser again opens a TCP connection, submits the HTTP request (this time with the cookie), and the server sends back the HTTP response.

It is worth nothing that technically, HTTP 1.1 introduced a header (Keep-Alive) that stops the browser from continually opening and tearing down TCP connections, however, the whole message architecture of HTTP is still assuming that each request is isolated from the last, and that the primary way to maintain state and related one request to another is via these cookies.

So, what's the big deal? 

Browsers will automatically include all relevant cookies with a request to a given domain. As such, any request to a banking site or a shopping site or an iGaming site, these would include any and all relevant cookies - including the cookies that identify the user and confirm that they are currently logged in (if they are).

Thus, if a malicious script on one site, executes a request to another, that request will be sent with all the relevant cookies for the target domain, meaning, what ever action that the malicious script triggers on the target webserver, it will be executed in the context of the victim user.

This is illustrated by the following diagram:

 

Diagram illustrating the CSRF/XSRF attack process

 

A classic illustration of CSRF is a web form, or API, that supports GET, such as e.g.:

https://www.somebank.com/transfer/?toAccount=123&amount=1000

This could be directly called by JavaScript, or even sent as a link for people to click - perhaps encoded, to mask the intentions. 

 

Protections Against CSRF? and What is SOP?

When browsers send messages from scripts, typically JavaScript these days, to a target such as a website or an API, by default it restricts the request to the 'same origin' as the script itself. For example, if script s1 is loaded from domain d1 typically, the s1 can only send messages to d1. It is actually a little more restricted than this, and we shall look at that detail soon.

However, first it is important to understand why SOP is needed in the first place. SOP is a "critical security control" [5], as in the early days of the internet there were a range of attacks that were possible, where scripts from one domain could be used to attack other domains. Typically these attacks would be based around reading data from one domain (perhaps loaded into the DOM in an HTML frame, or by directly requesting information from another site). Thus, SOP was introduced to prevent this.

SOP typically defines an origin as a tuple of: protocol (also called scheme), domain, and port. Thus, a script served from the origin (HTTPS, www.firesand.co.uk, 443) could not send requests to any other origin, including (HTTP, www.firesand.co.uk, 80), in this instance because both the scheme/protocol and port do not match the script's origin.  

Thus, SOP ensures that scripts can only read data from their same origin, or the responses from requests (e.g. GET requests sent via XmlHttpRequest.send()) to the same 'origin'. As such, this prevents attacks from reading/receiving the response.

 

Why SOP Doesn't Prevent CSRF?

Many resources online (including security vendors) suggest that SOP prevents CSRF attacks. For example [2,3], with one suggesting that SOP was designed to protect against CSRF [2] (which it was not) and another describing [3] SOP as "eliminating the possibility of a CSRF attack."

In reality the SOP concept was first introduced in Netscape 2.02, long before the concept of a CSRF attack[4], and initially it only protected the DOM, i.e., JavaScript from one domain was no longer permitted access to elements of the DOM that had been loaded from a different domain, e.g., within an HTML frame. This was later extended to include disallowing the reading of the responses of requests to different domains, e.g., those sent via XMLHttpRequest.send().

This last sentence is very important. SOP does not prevent a request from being sent, it will simply prevent the script from reading or accessing the result of such a request. 

We can demonstrate this quite easily, with a simple Python-based webserver, e.g. using the following Python3 code:

 

import http.server, ssl, socketserver

#Setup the SSL Context / settings
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)

#Load certificate, specifying: 
#  certificate file, 
#  key file, 
#  password - not a secure password, nor way of storing one, don't copy this!
context.load_cert_chain("cert.pem", "key.pem", "cert") 

#Setup server tuple (domain/address and port)
server_address = ("IP ADDRESS", 443) 

handler = http.server.SimpleHTTPRequestHandler

with socketserver.TCPServer(server_address, handler) as httpServer:

	httpServer.socket = context.wrap_socket(httpServer.socket, server_side=True)

	httpServer.serve_forever()

 

then launch the webserver, e.g.:

 

Simple Python Webserver running in Kali Linux

This screenshot, shows the simple Python-based webserver, running inside Kali Linux, waiting for requests. (For those unfamiliar, Kali Linux is an Linux-based Operating System designed for Penetration Testing etc).

If we then visit the Firesand website, and run JavaScript from the console, such as the following:

const xhr = new XMLHttpRequest();

xhr.onload = () => { console.log('Loaded') };

xhr.open("GET", "https://IP-ADDRESS");

xhr.send();

We will see that the request arrives at the Python webserver, but the response is not accessible to the script that sent the response, in fact when the response is received by the browser it throws an error.  

The following screenshot shows exactly that, the request has been successfully received by the webserver, despite the browser throwing an SOP access control error:

Cross Domain Request Reaching Server, Despite SOP Rules

So, script running in the context of https://www.firesand.co.uk (or in terms of SOP origin definitions: (HTTPS, www.firesand.co.uk, 443)), has successfully sent a message to a webserver on a different origin. 

This ensures that CSRF attacks continue to function, actions can be triggered by malicious scripts on behalf of an unwitting victim.

 

Actual Preventions for CSRF

There are common pieces of advice:

  1. Web Forms should not support GET as the method, instead they should support POST (thus the parameters will be sent in the HTTP body and not in the URL, as such a simple link won't suffice for an attack, but still a piece of JavaScript can absolutely attack a POST request).
  2. A unique token / nonce (number-once) often called a CSRF token, or anti-CSRF token. This should be generated ideally when a form is requested, but can be per session. When forms are submitted, this value must be validated.

A lot more detail is provided in the OWASP's Cross-Site Request Forgery Prevention Cheat Sheet [6]. It should be noted that many modern web application development frameworks, such as .NET, have inbuilt anti-CSRF tokens and associated validation. 

 

Conclusion

CSRF is a fairly old web application attack, and whilst not common these days, it is technically possible, depending on web frameworks being used.

SOP is a very useful control, but provides read protection only, and not write.

Further, CSRF and this article demonstrate the danger of seemingly obvious assumptions in the security domain!

 

References

[1]  - OWASP, 'The OWASP Top 10 - 2013', https://owasp.org/www-pdf-archive/OWASP_Top_10_-_2013.pdf, accessed on 29th December 2023

[2] - Securium Solutions, 'Same-Origin Policy(SOP) & Cross-Origin Resource Sharing(CORS)', https://securiumsolutions.com/same-origin-policysop-cross-origin-resource-sharingcors/, accessed on 29th December 2023

[3] - VeraCode, 'Prevent Cross-Site Request Forgery (CSRF) attacks'https://docs.veracode.com/r/cross-site-request-forgery, accessed on 29th December 2023

[4] - Netscape, 'Advanced topics', https://web.archive.org/web/20020808153106/http://wp.netscape.com:80/eng/mozilla/3.0/handbook/javascript/advtopic.htm#1009533, accessed on 29th December 2023   

[5] - Mozilla, 'Same-origin policy', https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy, accessed on 29th December 2023.

[6] - OWASP, 'Cross-Site Request Forgery Prevention Cheat Sheet', https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html, accessed on 30th December 2023

Chris Blake

About the author

https://www.linkedin.com/in/chrisblake/

Chris Blake has over 20 years of experience in the information and cyber security field, and is a passionate and qualified Enterprise Security Architect and Privacy Professional who leads and delivers innovative solutions at Firesand Limited, a company he co-founded in 2016. His specialities include application security, enterprise security architecture, and privacy, with a strong track record of building and implementing ISO 27001 compliant and certified information security practices, application security programmes, and enterprise security architectures. He has a thirst for continual learning and a commitment to excellence, as demonstrated by his academic and professional credentials from prestigious institutions such as the University of Oxford, (ISC)², IAPP, SABSA, The Open Group, and ISACA.

Chris holds an MSc in Software and Systems Security at the University of Oxford, and an array of professional certifications: CISSP, ISSAP, CSSLP, CCSP, SSP.NET, SSP.JAVA, CISA, CISM, CIPP/E, CIPM, CIPT, FIP, SCF, TOGAF, CPSA, and CEH.

Chris' experience spans multiple sectors: Retail & eCommerce; Financial Services, Banking, & Payments; i-Gaming; Energy (Oil & Gas); Property Management & PropTech; and Data Science; as well as Defence. 

His areas of interests include: penetration testing; regulation & privacy, including the impact on society; access control in software; security automation in development; application of cryptography; security architecture; risk modelling & analysis; HTTP architecture & web security; IoT Security.

Cookie Notice

We use cookies to ensure that we give you the best experience on our website. Please confirm you are happy to continue.

Back to top