Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I send any Access-Control-Allow-Origin header to non-allowed origins in the actual request following the OPTIONS request?

I have a general idea about how it works. I return the same "ORIGIN" value if the the request's "origin" header is valid (allowed)

But I don't know:

  1. For the actual request following the OPTIONS request, do I need to include the exact same Access-Control-Allow-Origin header that I returned to the client for the preflight request? Should the server code only need to do this when there is an "ORIGIN" header present in the actual request? (in the code below, I did not check whether the request is a OPTIONS/preflight request or the actual one, I assume the same code can apply to both with no harm).

(More details, because "The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'," so I need the ORIGIN value from the request to put back into the response.

  1. What should I return if the ORIGIN is not allowed?

    not including the Access-Control-Allow-Origin header at all?
    or setHeader("Access-Control-Allow-Origin", ""), or setHeader("Access-Control-Allow-Origin", "null")?

public class CORSResponseFilter implements ContainerResponseFilter {

@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
    MultivaluedMap<String, Object> headers = responseContext.getHeaders();

    String origin = requestContext.getHeaderString("Origin"); 


String origin = requestContext.getHeaderString("Origin");

    URL originUrl = null;
    try {
        if (StringUtils.hasText(origin)) {
            originUrl = new URL(origin);
            
            Pattern hostAllowedPattern = Pattern.compile("(.+\\.)*mydomain\\.com", Pattern.CASE_INSENSITIVE);

            if (hostAllowedPattern.matcher(originUrl.getHost()).matches()) {
                headers.add("Access-Control-Allow-Origin", origin);
            } else {
                headers.add("Access-Control-Allow-Origin", "");
            }
            headers.add("Vary", "Origin");
        }

        headers.add("Access-Control-Allow-Credentials", "true");
        headers.add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
        headers.add("Access-Control-Allow-Headers",
like image 650
user3277841 Avatar asked Sep 07 '17 02:09

user3277841


People also ask

Is it safe to use Access-Control allow origin?

Access-Control-Allow-Origin: * is totally safe to add to any resource, unless that resource contains private data protected by something other than standard credentials. Standard credentials are cookies, HTTP basic auth, and TLS client certificates.

Do I need to set Access-Control allow origin?

With the help of CORS, browsers allow origins to share resources amongst each other. There are a few headers that allow sharing of resources across origins, but the main one is Access-Control-Allow-Origin . This tells the browser what origins are allowed to receive requests from this server.

Can HTTP headers be used to restrict or allow access to resources from specified origins?

It is used to request restricted documents. It is a response header gives access to a resource file by defining an authorization method. It allows the proxy server to transmit the request further by authenticating it.

What does the Access-Control allow Origin header do?

What is the Access-Control-Allow-Origin response header? The Access-Control-Allow-Origin header is included in the response from one website to a request originating from another website, and identifies the permitted origin of the request.


1 Answers

For the actual request following the OPTIONS request, do I need to include the exact same Access-Control-Allow-Origin header that I returned to the client for the preflight request?

Yes—that is, if you’re sending back an actual origin value and not the "*" wildcard, and that origin value is what caused the OPTIONS request to succeed. Because if you send back a different non-wildcard origin value than what the OPTIONS succeeded with, that’ll cause the browser to block the client code from accessing the response (because the actual origin won’t match).

Should the server code only need to do this when there is an "ORIGIN" header present in the actual request?

Yes, because when frontend JavaScript code running in a browser uses XHR or the Fetch API or an Ajax method from some JavaScript library to make a cross-origin request, browsers always add an Origin header to the request. And Access-Control-Allow-Origin is only used by browsers.

So there’s no point in sending back Access-Control-Allow-Origin to non-browser tools that haven’t sent an Origin in the request—in that case, it’s just wasted bytes you’re sending out.

Of course somebody can use curl or whatever non-browser tool to send a request to the server, and manually add an Origin header to the request. But that’s OK—in that case, the response they’ll get is the same response you’d send to a browser. So that can actually be helpful for testing.

What should I return if the ORIGIN is not allowed?
not including the Access-Control-Allow-Origin header at all?

Yes. Just don’t send back the Access-Control-Allow-Origin response header at all for those cases. That’s the semantics of the header being missing: If the server sends no Access-Control-Allow-Origin response header, that means the server isn’t opting in to allowing cross-origin requests from frontend code running browsers, so the default same-origin policy applies.

That is, by not sending the Access-Control-Allow-Origin response header, the server’s telling browsers: “Please use the default same-origin policy as usual and prohibit access to this response from all frontend JavaScript code at the origin that sent this request.”

or setHeader("Access-Control-Allow-Origin", ""),

No, there’s never any need to send back an empty value like that. It doesn’t mean anything special.

or setHeader("Access-Control-Allow-Origin", "null")?

Definitely don’t do that. There are many cases where a browser will send an Origin header with the value null and unless you intentionally want to allow all requests with Origin: null to access responses from the server, don’t do that.

For details, see the When browsers must internally set origin to a value that’ll get serialized as null part of the answer at When does Firefox set the Origin header to null in POST requests?

like image 101
sideshowbarker Avatar answered Nov 15 '22 10:11

sideshowbarker