7

As an example case let's take this url: http://api.duckduckgo.com/?q=computer&format=json (CORS not enabled on this server!)

  1. We can access the contents from this URL from any popular browser as a normal URL, browser has no issues opening this URL nor the server returns any error.

  2. A server-side language like PHP/RoR can fetch the contents from this URL without adding any additional headers or special server settings. I used following PHP code and it simply worked.

    $url='http://api.duckduckgo.com/?q=computer&format=json';
    $json = file_get_contents($url);
    echo $json;
    
  3. I just started working in javascript framework, AngularJS. I used following code...

    delete $http.defaults.headers.common['X-Requested-With'];
    var url="http://api.duckduckgo.com/?q=computer&format=json";
    $http.get(url)
         .success(function(data) {
             $scope.results=data;
          })
    

    With above AngularJS code, I received following error:

    XMLHttpRequest cannot load http://api.duckduckgo.com/?q=computer&format=json. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.

  4. AngularJS uses JQuery so I tried the same in JQuery with following code:

    var url="http://api.duckduckgo.com/?q=computer&format=json";
    $.getJSON(url , function( data ) {
        console.log(data);
    });
    

    This also produced the same error as did AngularJS code.

  5. Then my further research brought me to the point that it's actually not specific to JQuery and AngularJS. Both of these inherit this issue from Javascript!



So my question is not what CORS is. My question is

  1. My understanding is that whether it is a web browser or it is PHP/RoR or it is Javascript frameworks, all make requests to a URL via the same http or https, right? Certainly, yes. Then why http has to be more secure when requests come from javascript? How does http and server know that request is coming from javascript?

  2. When a web browser can open a URL and PHP/RoR (or any server-side language) can access that URL without any extra settings/headers, why can't AngularJS, JQuery (or in a single word javascript) access that URL unless the server has set Access-Control-Allow-Origin header for requesting root?

  3. What's that special feature (that PHP/RoR have and) that is missing in Javascript so that it can't access the same URL in the same browsers that can open that URL without any issue from their address bars?

Just to mention that I am basically an iOS developer and recently started to learn web development, specially AngularJS. So I am curious about what's all this going on and why!

gen_Eric
  • 223,194
  • 41
  • 299
  • 337
Atif Azad
  • 1,294
  • 1
  • 16
  • 30
  • 7
    "*Then why http has to be more secure when requests come from javascript?*" Because Ajax requests are made *as* the user, with their cookies, including any for sessions, etc. So, a malicious web application could make an Ajax request for your bank balance and statement and succeed if you were logged in and cross-origin was allowed by default. – Jonathan Lonowski Feb 19 '14 at 16:01
  • One possible reason could be script injections, if you are a standard user, and go to a webpage, you trust **that** page. If that page tries to involve another domain then it would require you to trust it, by default it is denied rather than asking for permission. (This is my personal understanding, correct me if I'm wrong) – Nunners Feb 19 '14 at 16:07
  • @Nunners As a user, you have no idea if domain A is allowed to talk to Domain B, you have no say in that handshake [CORS]. – epascarello Feb 19 '14 at 16:12
  • @JonathanLonowski, it's amazing to know :) Thanks for this quick hint on Ajax! – Atif Azad Feb 19 '14 at 16:29

3 Answers3

7

It's disabled from javascript for security reasons. Here's one scenario:

  • Assume Facebook has a "post message on timeline" api that requires the user to be authenticated.
  • You are logged into Facebook when you visit badsite.com.
  • badsite.com uses javascript to call the Facebook api. Since the browser is making a valid request to Facebook, your authentication cookie is sent, and Facebook accepts the message and posts badsite's ad on your timeline.

This isn't an issue from a server, because badsite.com's server doesn't have access to your Facebook authentication cookie and it can't forge a valid request on your behalf.

Jason P
  • 26,984
  • 3
  • 31
  • 45
  • So knowing that JS has access to cookies and sessions on client machine, are there any other HTTP features except CORS that have been disabled for javascript? Are there any other possible security vulnerabilities? – Atif Azad Feb 19 '14 at 16:42
  • 1
    Not sure quite what you're asking, but there are LOTS of possible security vulnerabilities. Look over the [OWASP Top 10](https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project). – Jason P Feb 19 '14 at 17:00
1

You remember that all javascript request is handled by browser. So browser detect cross-origin request is easy.

Request from javascript has no difference with PHP/RoR, it is only rejected by browser.

Server code can accept cross-origin javascript request by header "Access-Control-Allow-Origin" because before reject javascript request, browser will send a request "OPTIONS" to server to ask header "Access-Control-Allow-Origin" on response. If value is match with current origin, browser will accept javascript request and send to server.

All browser are implement this policy Same Origin Policy

1

Please read http://en.wikipedia.org/wiki/Cross-site_scripting, you will get the reason why its prohibited for JavaScript.

murtza gondal
  • 997
  • 2
  • 12
  • 26