30

I'm diving deeper into developing RESTful APIs and have so far worked with a few different frameworks to achieve this. Of course I've run into the same-origin policy, and now I'm wondering how web servers (rather than web browsers) enforce it. From what I understand, some enforcing seems to happen in the browser's end (e.g., honoring an Access-Control-Allow-Origin header received from a server). But what about the server?

For example, let's say a web server is hosting a Javascript web app that accesses an API, also hosted on that server. I assume that the server would enforce the same-origin policy --- so that only the javascript that is hosted on that server would be allowed to access the API. This would prevent someone else from writing a javascript client for that API and hosting it on another site, right? So how would a web server be able to stop a malicious client that would try to make AJAX requests to its API endpoints while claiming to be running javascript that originated from that same web server? What's the way most popular servers (Apache, nginx) protect against this kind of attack? Or is my understanding of this somehow off the mark?

Or is the cross-origin policy only enforced on the client end?

1
  • really a nice question
    – Benny
    May 10, 2015 at 9:00

5 Answers 5

55
+250

The same origin policy is a wholly client-based restriction, and is primarily engineered to protect users, not services. All or most browsers include a command-line switch or configuration option to to turn it off. The SOP is like seat belts in a car: they protect the rider in the car, but anyone can freely choose not to use them. Certainly don't expect a person's seat belt to stop them from getting out of their car and attacking you (or accessing your Web service).

Suppose I write a program that accesses your Web service. It's just a program that sends TCP messages that include HTTP requests. You're asking for a server-side mechanism to distinguish between requests made by my program (which can send anything) and requests made by a browser that has a page loaded from a permitted origin. It simply can't be done; my program can always send a request identical to one formed by a Web page.

The same-origin policy was invented because it prevents code from one website from accessing credential-restricted content on another site. Ajax requests are by default sent with any auth cookies granted by the target site. For example, suppose I accidentally load http://evil.com/, which sends a request for http://mail.google.com/. If the SOP were not in place, and I was signed into Gmail, the script at evil.com could see my inbox. If the site at evil.com wants to load mail.google.com without my cookies, it can just use a proxy server; the public contents of mail.google.com are not a secret (but the contents of mail.google.com when accessed with my cookies are a secret).

8

The same-origin policy is enforced on the client-side. If the browser supports CORS, the server can send back headers that tell the browser to make exceptions to the same-origin policy. For example, sending the header

 Access-Control-Allow-Origin: www.example.com

would tell the browser to allow cross-origin requests from www.example.com.

 Access-Control-Allow-Origin: *

tells the browser to allow all cross-origin requests to that resource.

4

Web servers generally prevent attacks of this sort by checking the (infamously misspelled) Referer line in the HTTP header, to ensure that a request is coming from a page on their own site. There's no good way to guard against a malicious client, but that's not how XSRF attacks work.

The client isn't malicious; it's generally an ordinary user who's been tricked by a malicious third-party into opening a document that silently makes a HTTP request using the client's stored cookies. So if the server can verify via the Referer that the HTTP request is coming from gmail.com, and not MyAwesomeWebsite.com, it can shut the attack down.

2
  • what if the the referrer line is forged maliciously?
    – Benny
    May 10, 2015 at 9:09
  • @Benny: That's highly unlikely. The Referer line is generated by the user's web browser, and the user is the victim here, not the attacker. He has no reason to forge the Referer, and the attacker doesn't have the opportunity to do so. May 10, 2015 at 10:10
1

How do web servers enforce the same-origin policy?

In short, they do not, as apsillers and Dirk pointed out.
One important reason is that the ACAO header protects the servers themselves from rampant DDOS, - Distributed Denial of Service- attacks.

Who:

The ACAO as a HTTP response-header is meant for the web client to be interpreted, operating under the assumption that the majority of human internet users are browsing the web through major browser vendors who adhere and implement the W3C recommended draft. They should, after all most of them benefit from a fast, accessible internet.

How:

Otherwise anyone, could just copy and paste a few lines of javascript code into a malicious website that runs a simple loop, which makes an Ajax GET's or POST's request to a foreign domain. Without user interaction, and the ability to multithread.

That is why you have to opt-in to access a cross-origin site, through the ACAO HTTP header. You, the user, can access said site any time through a user-aware interaction, i.e. an internet link. Just like you can user-aware copy or paste content from or to your clipboard, but not any other way - plugins aside.

Future:

At that point, heed the web-browser maker's direction of:

Security restrictions can be decently established using a combination of TSL 2/3, strong session-IDs, TANs, two factor authentication etc..

'Google' has this to show and say about DDOS

Lastly, anyone is free to proxy any web content and add a desired ACAO header to access proxied cross-site content. Likewise, this proxy is then as open to a DDOS attack, as the ACAO setting allows it to be. I actually don't know of a single, free public service offering. Please correct me if I am wrong.

0

As others said, it's up to the client. But the server may need to deal with XSS, which bypasses SOP.

Supopse your server allows users to upload content, which is displayed when other users browse your site. This page is a good example - I just uploaded content, and it's displayed to you.
If my content contains the <script> tag, and the server just copies it into the HTML it generates, then the script I uploaded will run.
Since the script was found in HTML from your file, it has all the permissions of your site's script. It can, for example, upvote this answer. And this is why this answer has so many upvotes.

A good web server (like, alas, the one StackExchange uses), won't let this happen. It can remove the <script> tag, or escape it, so it will be seen but not executed (warning - this answer is far from a reliable recipe to prevent XSS).

So it's the client side that enforces SOP, but in some cases the server should work to prevent bypassing it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.