Cross-Origin Resource Sharing: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
(Created page with "=Internal= =Overview= !!!Web Applications - Same-OriginPolicy !!!Internal |[Web Applications] !!!External * [https://en.wikipedia.org/wiki/Same-origin_policy] * [https:/...")
 
No edit summary
Line 1: Line 1:
=Internal=
=External=
 
=Overview=


!!!Web Applications - Same-OriginPolicy
* https://en.wikipedia.org/wiki/Same-origin_policy
* https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
* https://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
* http://www.w3.org/TR/access-control/
* RFC 6454 https://tools.ietf.org/html/rfc6454


!!!Internal
=Internal=
 
|[Web Applications]
 
!!!External
 
* [https://en.wikipedia.org/wiki/Same-origin_policy]
* [https://en.wikipedia.org/wiki/Cross-origin_resource_sharing]
* [https://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/]
* [https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS]
* [http://www.w3.org/TR/access-control/]
* RFC 6454 [https://tools.ietf.org/html/rfc6454]


<font color=red>
=TODO=


!!!TODO
See how swagger-generated code implements in <code>io.swagger.api.ApiOriginFilter</code>:


See how swagger-generated code implements in io.swagger.api.ApiOriginFilter:
<syntaxhighlight lang='java'>
 
{{{
package io.swagger.api;
package io.swagger.api;


Line 47: Line 37:
public void init(FilterConfig filterConfig) throws ServletException {}
public void init(FilterConfig filterConfig) throws ServletException {}
}
}
}}}
</syntaxhighlight>


</font>
=Overview=
 
 
!!!Overview


Web browsers are built so they don't allow JavaScript that runs as part of web page to make HTTP requests via the XMLHttpRequest interface to other sites than the origin web site. In some cases - Chrome, for example, the HTTP request is made, but the browser will just throw out the response and log a JavaScript error:
Web browsers are built so they don't allow JavaScript that runs as part of web page to make HTTP requests via the XMLHttpRequest interface to other sites than the origin web site. In some cases - Chrome, for example, the HTTP request is made, but the browser will just throw out the response and log a JavaScript error:


{{{
XMLHttpRequest cannot load http://b.com/B.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://a.com' is therefore not allowed access.
XMLHttpRequest cannot load http://b.com/B.html. No 'Access-Control-Allow-Origin' header  
is present on the requested resource. Origin 'http://a.com' is therefore not allowed access.
}}}


The same-origin policy only applies to web fonts and AJAX (XMLHttpRequest) requests. A web page may freely embed images, stylesheets, scripts, iframes, videos and some plugin content (such as Adobe Flash) from any other domain.
The same-origin policy only applies to web fonts and AJAX (XMLHttpRequest) requests. A web page may freely embed images, stylesheets, scripts, iframes, videos and some plugin content (such as Adobe Flash) from any other domain.


!!!Why?
=Why?=


A possible explanation is that the web browser wants to prevent the situation when an unknowing user downloads malicious behavior from a web site A, which then starts to make invocations into other site B. In order for this to be allowed, site B has to explicitly allow it - and then the browser allows it too. The browser insures this by essentially asking B: "Do you allow scripts downloaded from A to invoke into you?" This invocation is called "pre-flight".
A possible explanation is that the web browser wants to prevent the situation when an unknowing user downloads malicious behavior from a web site A, which then starts to make invocations into other site B. In order for this to be allowed, site B has to explicitly allow it - and then the browser allows it too. The browser insures this by essentially asking B: "Do you allow scripts downloaded from A to invoke into you?" This invocation is called "pre-flight".


=Cross-Origin Resource Sharing=


 
Cross-origin calls can be made with the cooperation of the second server. The standard way to do it is to employ Cross-Origin Resource Sharing (CORS), which is a standardized technique. See Cross-Origin Resource Sharing http://www.w3.org/TR/access-control. It consists of a simple header exchange between the client and the second server. This standard extends HTTP with a new Origin request header and a new Access-Control-Allow-Origin response header.  
!!!Cross-Origin Resource Sharing
 
Cross-origin calls can be made with the cooperation of the second server. The standard way to do it is to employ Cross-Origin Resource Sharing (CORS), which is a standardized technique. See Cross-Origin Resource Sharing [http://www.w3.org/TR/access-control]. It consists of a simple header exchange between the client and the second server. This standard extends HTTP with a new Origin request header and a new Access-Control-Allow-Origin response header.  


The way the standard is supposed to work is the following:
The way the standard is supposed to work is the following:
Line 77: Line 59:
A browser rendering content from http://A.com wants to send a request into http://B.com so it “pre-flights” the request by inquiring the B.com server on its capabilities with an Origin header sent over an OPTIONS request:
A browser rendering content from http://A.com wants to send a request into http://B.com so it “pre-flights” the request by inquiring the B.com server on its capabilities with an Origin header sent over an OPTIONS request:


{{{
OPTIONS / HTTP/1.1
 
Host: B.com
OPTIONS / HTTP/1.1
Access-Control-Request-Method: GET
Host: B.com
Origin: http://A.com
Access-Control-Request-Method: GET
Referer: http://A.com/the-page-containinig-js.html
Origin: http://A.com
Referer: http://A.com/the-page-containinig-js.html
 
}}}


If B.com wants to allow cross-origin calls, it should respond with a pair of headers:
If B.com wants to allow cross-origin calls, it should respond with a pair of headers:


{{{
Access-Control-Allow-Origin: http://A.com
Access-Control-Allow-Origin: http://A.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
}}}


To allow general access, the second server could respond with:
To allow general access, the second server could respond with:


{{{
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
}}}


=Origin=


!!!Origin
The origin is defined by  {protol, host, port}. The algorithm to calculate the origin of a URI is specified in RFC 6454 https://tools.ietf.org/html/rfc6454/


The origin is defined by  {protol, host, port}. The algorithm to calculate the origin of a URI is specified in RFC 6454: [https://tools.ietf.org/html/rfc6454]
=Behavior in Presence of Custom Headers=
 
!!!Behavior in Presence of Custom Headers


If the cross call contains custom headers, the browser includes those custom headers in the pre-flight invocation:
If the cross call contains custom headers, the browser includes those custom headers in the pre-flight invocation:


{{{
OPTIONS /blah HTTP/1.1
 
Host: B.com
OPTIONS /blah HTTP/1.1
Access-Control-Request-Method: GET
Host: B.com
Origin: http://A.com
Access-Control-Request-Method: GET
Access-Control-Request-Headers: onecloud-adgroup, onecloud-user
Origin: http://A.com
Referer: http://A.com/the-page-containinig-js.html
Access-Control-Request-Headers: onecloud-adgroup, onecloud-user
Referer: http://A.com/the-page-containinig-js.html
 
}}}


Note "Access-Control-Request-Headers".
Note "Access-Control-Request-Headers".
Line 124: Line 93:
B.com must acknowledge the headers, otherwise we get an error message similar to:
B.com must acknowledge the headers, otherwise we get an error message similar to:


{{{
XMLHttpRequest cannot load http://B.com/blah/. Request header field OneCloud-User is not allowed by Access-Control-Allow-Headers in preflight response.
XMLHttpRequest cannot load http://B.com/blah/. Request header field OneCloud-User is not allowed by Access-Control-Allow-Headers in preflight response.
}}}


Acknowledgement is provided by returning an "Access-Control-Allow-Headers" header listing the comma-separated list of allowed headers:
Acknowledgement is provided by returning an "Access-Control-Allow-Headers" header listing the comma-separated list of allowed headers:


{{{
Access-Control-Allow-Headers: Apples, Oranges
Access-Control-Allow-Headers: Apples, Oranges
}}}
 
 
!!!Web Applications CSRF
 
 
!!!Internal
 
|[Web Applications]
 


Cookie-to-Header Token
=Cross-Site Request Forgery (CSRF)=


Cookie-to-Header Token.


Web applications that use JavaScript for the majority of their operations may use an anti-CSRF technique that relies on same-origin policy:
Web applications that use JavaScript for the majority of their operations may use an anti-CSRF technique that relies on same-origin policy:
Line 150: Line 107:
1. On login, the web application sets a cookie containing a random token that remains the same for the whole user session
1. On login, the web application sets a cookie containing a random token that remains the same for the whole user session


{{{
Set-Cookie: Csrf-token=i8XNjC4b8KVok4uw5RftR38Wgp2BFwql; expires=Thu, 23-Jul-2015 10:25:33 GMT; Max-Age=31449600; Path=/
Set-Cookie: Csrf-token=i8XNjC4b8KVok4uw5RftR38Wgp2BFwql; expires=Thu, 23-Jul-2015 10:25:33 GMT; Max-Age=31449600; Path=/
}}}


2. JavaScript operating on the client side reads its value and copies it into a custom HTTP header sent with each transactional request
2. JavaScript operating on the client side reads its value and copies it into a custom HTTP header sent with each transactional request


{{{
X-Csrf-Token: i8XNjC4b8KVok4uw5RftR38Wgp2BFwql
X-Csrf-Token: i8XNjC4b8KVok4uw5RftR38Wgp2BFwql
}}}


The server validates presence and integrity of the token
The server validates presence and integrity of the token
__Referenced by:__\\
[{INSERT com.ecyrd.jspwiki.plugin.ReferringPagesPlugin WHERE max=20, maxwidth=50}]
__Referenced by:__\\
[{INSERT com.ecyrd.jspwiki.plugin.ReferringPagesPlugin WHERE max=20, maxwidth=50}]

Revision as of 01:58, 18 November 2018

External

Internal

TODO

See how swagger-generated code implements in io.swagger.api.ApiOriginFilter:

package io.swagger.api;

import java.io.IOException;

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;

@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JaxRSServerCodegen", date = "2015-09-18T16:59:22.303Z")
public class ApiOriginFilter implements javax.servlet.Filter {
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletResponse res = (HttpServletResponse) response;
		res.addHeader("Access-Control-Allow-Origin", "*");
		res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
		res.addHeader("Access-Control-Allow-Headers", "Content-Type");
		chain.doFilter(request, response);
	}

	public void destroy() {}

	public void init(FilterConfig filterConfig) throws ServletException {}
}

Overview

Web browsers are built so they don't allow JavaScript that runs as part of web page to make HTTP requests via the XMLHttpRequest interface to other sites than the origin web site. In some cases - Chrome, for example, the HTTP request is made, but the browser will just throw out the response and log a JavaScript error:

XMLHttpRequest cannot load http://b.com/B.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://a.com' is therefore not allowed access.

The same-origin policy only applies to web fonts and AJAX (XMLHttpRequest) requests. A web page may freely embed images, stylesheets, scripts, iframes, videos and some plugin content (such as Adobe Flash) from any other domain.

Why?

A possible explanation is that the web browser wants to prevent the situation when an unknowing user downloads malicious behavior from a web site A, which then starts to make invocations into other site B. In order for this to be allowed, site B has to explicitly allow it - and then the browser allows it too. The browser insures this by essentially asking B: "Do you allow scripts downloaded from A to invoke into you?" This invocation is called "pre-flight".

Cross-Origin Resource Sharing

Cross-origin calls can be made with the cooperation of the second server. The standard way to do it is to employ Cross-Origin Resource Sharing (CORS), which is a standardized technique. See Cross-Origin Resource Sharing http://www.w3.org/TR/access-control. It consists of a simple header exchange between the client and the second server. This standard extends HTTP with a new Origin request header and a new Access-Control-Allow-Origin response header.

The way the standard is supposed to work is the following:

A browser rendering content from http://A.com wants to send a request into http://B.com so it “pre-flights” the request by inquiring the B.com server on its capabilities with an Origin header sent over an OPTIONS request:

OPTIONS / HTTP/1.1
Host: B.com
Access-Control-Request-Method: GET
Origin: http://A.com
Referer: http://A.com/the-page-containinig-js.html

If B.com wants to allow cross-origin calls, it should respond with a pair of headers:

Access-Control-Allow-Origin: http://A.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE

To allow general access, the second server could respond with:

Access-Control-Allow-Origin: *

Origin

The origin is defined by {protol, host, port}. The algorithm to calculate the origin of a URI is specified in RFC 6454 https://tools.ietf.org/html/rfc6454/

Behavior in Presence of Custom Headers

If the cross call contains custom headers, the browser includes those custom headers in the pre-flight invocation:

OPTIONS /blah HTTP/1.1
Host: B.com
Access-Control-Request-Method: GET
Origin: http://A.com
Access-Control-Request-Headers: onecloud-adgroup, onecloud-user
Referer: http://A.com/the-page-containinig-js.html

Note "Access-Control-Request-Headers".

B.com must acknowledge the headers, otherwise we get an error message similar to:

XMLHttpRequest cannot load http://B.com/blah/. Request header field OneCloud-User is not allowed by Access-Control-Allow-Headers in preflight response.

Acknowledgement is provided by returning an "Access-Control-Allow-Headers" header listing the comma-separated list of allowed headers:

Access-Control-Allow-Headers: Apples, Oranges

Cross-Site Request Forgery (CSRF)

Cookie-to-Header Token.

Web applications that use JavaScript for the majority of their operations may use an anti-CSRF technique that relies on same-origin policy:

1. On login, the web application sets a cookie containing a random token that remains the same for the whole user session

Set-Cookie: Csrf-token=i8XNjC4b8KVok4uw5RftR38Wgp2BFwql; expires=Thu, 23-Jul-2015 10:25:33 GMT; Max-Age=31449600; Path=/

2. JavaScript operating on the client side reads its value and copies it into a custom HTTP header sent with each transactional request

X-Csrf-Token: i8XNjC4b8KVok4uw5RftR38Wgp2BFwql

The server validates presence and integrity of the token