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
- Access-Control-Allow-Origin
- Access-Control-Allow-Credential
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
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: *
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