CORS (cross origin resource sharing)

Cross-Origin Resource Sharing (CORS) is a security concept that allows restricting the resources implemented in web browsers. It prevents the Javascript code producing or consuming the requests against different origin.

The CORS standard describes new HTTP headers which provide browsers a way to request remote URLs only when they have permission

Limiting the possible Access-Control-Allow-Origin values to a set of allowed origins requires code on the server side to check the value of the Origin request header, compare that to a list of allowed origins, and then if the Origin value is in the list, to set the Access-Control-Allow-Origin value to the same value as the Origin value

Headers

Response headers

PHP example

read.example.org/index.php

   1 <?php
   2 header("Content-type:application/json");
   3 header("Cache-Control: no-cache");
   4 header("Pragma: no-cache"); 
   5 header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']  ); 
   6 header("Access-Control-Allow-Credentials: true");
   7 session_start();
   8 $user = $_SESSION["user"];
   9 
  10 echo("{\"key\":\"readData\" , \"user\": \"" . $user . "\" }");
  11 ?>

auth.example.org/index.php

   1 <?php
   2 header("Content-type:application/json");
   3 header("Cache-Control: no-cache");
   4 header("Pragma: no-cache"); 
   5 header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
   6 header("Access-Control-Allow-Credentials: true");
   7 
   8 session_set_cookie_params(0, '/', '.example.org');
   9 session_start(); 
  10 
  11 $_SESSION["user"] = "userx " .  time();
  12 
  13 echo("{\"key\":\"authData\"}");
  14 ?>

app.example.org/index.html

   1 <html>
   2 <head>
   3 <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
   4 
   5 <script>
   6 $(document).ready(function(){
   7   console.log('Iooo');
   8 
   9   $.ajax({
  10   url: "http://auth.example.org/",
  11   xhrFields: { withCredentials: true  },
  12   success:  function(data, textStatus,jqXHR ){ $("#auth").text(data.key); },
  13   error: function( jqXHR, textStatus, errorThrown ){console.log(textStatus);}
  14   });
  15 
  16   $.ajax({
  17   url: "http://read.example.org/",
  18   xhrFields: {withCredentials: true},
  19   success: function(data,textStatus,jqXHR){ $("#read").text(data.key + ' ' + data.user  ); },
  20   error: function( jqXHR, textStatus, errorThrown ){console.log(textStatus);}
  21   });
  22 
  23 });
  24 
  25 </script>
  26 </head>
  27 <body>
  28 <p id="auth"></p>
  29 <p id="read"></p>
  30 </body>
  31 </html>

Apache vhosts configuration

<VirtualHost *:80>
    ServerName app.example.org
    DocumentRoot "/var/www/htdocs/app.example.org"
    <Directory "/var/www/htdocs/app.example.org">
      Require local
      AllowOverride All
    </Directory>
</VirtualHost>

<VirtualHost *:80>
    ServerName auth.example.org       
    DocumentRoot "/var/www/htdocs/auth.example.org"
    <Directory "/var/www/htdocs/auth.example.org">
      Require local
      AllowOverride All
    </Directory>
</VirtualHost>

<VirtualHost *:80>
    ServerName read.example.org       
    DocumentRoot "/var/www/htdocs/read.example.org"
    <Directory "/var/www/htdocs/read.example.org">
      Require local
      AllowOverride All
    </Directory>
</VirtualHost>

Spring pointers

Just adding the annotation @CrossOrigin on an endpoint makes it accept all origins,

Firefox browser tests

The URL in the tab where the test is made must be different than the URL called in window.fetch().

No CORS support on server side

   1 window.fetch('http://localhost:8080/').then( (response)=>{ 
   2   response.text().then( (data)=>{ console.log(data); } );
   3 });

Outputs something like

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 200.
Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource. 

CORS support on server side

Returns header Access-Control-Allow-Origin: *

   1 window.fetch('http://localhost:8080/').then( (response)=>{ 
   2   response.text().then( (data)=>{ console.log(data); } );
   3 });

Outputs something like

Hello world

curl output

   1 curl http://localhost:8080/ -vvv
   2 *   Trying ::1:8080...
   3 * Connected to localhost (::1) port 8080 (#0)
   4 > GET / HTTP/1.1
   5 > Host: localhost:8080
   6 > User-Agent: curl/7.74.0
   7 > Accept: */*
   8 > 
   9 * Mark bundle as not supporting multiuse
  10 < HTTP/1.1 200 OK
  11 < X-Powered-By: Stuff
  12 < Access-Control-Allow-Origin: *
  13 < Content-Type: text/html; charset=utf-8
  14 < Content-Length: 12
  15 < ETag: W/"c-6eJ/8x1yhzVLKoaKtBjtX4fCBSk"
  16 < Date: Thu, 27 Oct 2022 20:41:15 GMT
  17 < Connection: keep-alive
  18 < Keep-Alive: timeout=5
  19 < 
  20 * Connection #0 to host localhost left intact
  21 Hello world

CORS (last edited 2022-10-27 10:32:47 by localhost)