Access-Control-Allow-Origin header is present but Browser deny XMLHttpRequest - javascript

I have a really strange problem. I have a Webservice build with a simple Perl CGI Script as a Wrapper to an API (to allow restricted Cross Origin Control).
Anyway, to allow Cross-Origin Requests I set these headers:
Content-Type: text/plain
Access-Control-Allow-Origin: $origin
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-Requested-With, Content-Type, Accept, Accept-Language, Content-Language
Content-Security-Policy: connect-src *
X-Content-Security-Policy: connect-src *
X-WebKit-CSP: connect-src *
Access-Control-Max-Age: 1728000
Vary: Accept-Encoding, Origin
where my $origin = $ENV{HTTP_ORIGIN} // '*';.
When the Script Requests the expected Ressource, the Response from the Wrapper is the followed (copied from Firefox):
HTTP/1.1 200 OK
Date: Wed, 20 Jan 2016 12:54:48 GMT
Server: Apache
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-Requested-With, Content-Type, Accept, Accept-Language, Content-Language
content-security-policy: connect-src *, frame-ancestors 'self'
X-Content-Security-Policy: connect-src *
X-WebKit-CSP: connect-src *
Access-Control-Max-Age: 1728000
Vary: Accept-Encoding,Origin
Content-Length: 0
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/plain
The Browser gives me the following error:
XMLHttpRequest cannot load http://www.example.com/cgi-bin/wrapper.pl. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://example2.com' is therefore not allowed access.`
I also tested the call with curl and Postman, but this worked as expected.
The problem is that all Browser seem to ignore the Access-Control-Allow-Origin header, even when he is set.

Okay I found the problem. The Error was that I send the Access-Control-Allow-Origin and Access-Control-Allow-Headers only in the OPTIONS Request, not in the normal POST.

Related

Why are sometimes XMLHttpRequest blocked from CORS with my local IP address in access-control-allow-origin?

Since a few days I'm getting sometimes in my browsers the error
Access to XMLHttpRequest at 'https://websiteB.com/file.zlip' from origin 'https://websiteA.com' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'http://192.168.0.200' that is not equal to the supplied origin.
As I understand usually SOP (Same Origin Policy) is valid and can bypassed by CORS in the way that all participants are informed. This concerns only dynamic server request like XHR.
My aim is to use data from websiteB in websiteA. Therefore I saved a .htacces in the root of websiteB.
RewriteEngine on
RewriteBase /
# allow request from multiple domains (domain1.com|domain2.com|...)
<IfModule mod_headers.c>
SetEnvIf Origin "http(s)?://(www\.)?(websiteA.com)$" AccessControlAllowOrigin=$0
Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
</IfModule>
The point is that this error occurs only sometimes. I always clear completely the cache from the browsers before I test.
Results from Mozilla Firefox:
Response header
HTTP/2 200 OK
date: Mon, 31 Aug 2020 12:31:55 GMT
server: Apache
etag: "1d1cf8-58ffd72bc6380"
last-modified: Tue, 13 Aug 2019 10:53:18 GMT
content-length: 1907960
access-control-allow-origin: http://192.168.0.200
age: 698
accept-ranges: bytes
strict-transport-security: max-age=15768000
X-Firefox-Spdy: h2
Request header
GET /file.zlip HTTP/2
Host: websiteB.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0
Accept: */*
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate, br
Origin: https://websiteA.com
Connection: keep-alive
Referer: https://websiteA.com/
TE: Trailers
As I understand in access-control-allow-origin should be websiteA.com, how is it possible that there is my IP-Adresse from my local network? Is there a way to clear the header before sending it?
Update:
I just found that if I deselect in the browse debug mode the enable "http cache" it works correctly. So I inserted in my website
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
and in my .htaccess
<IfModule mod_headers.c>
Header set Cache-Control "no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires 0
</IfModule>
but nothing helped. Has anyone an idea what's going wrong here?
This is because your CORS header does not match the origin.
From your response header:
access-control-allow-origin: http://192.168.0.200
From your request header:
Origin: https://websiteA.com
Since http://192.168.0.200 is not https://websiteA.com it is a CORS violation and the browser rightfully blocks the request. The correct CORS header for the response should be:
access-control-allow-origin: https://websiteA.com

Chrome does not see Access-Control-Expose-Headers header

I have a problem with Chrome - in the network tab it only displays an empty Access-Control-Exposed-Headers header.
In postman the header's value is visible:
When trying to access the ETag header through the getResponseHeader('ETag') method of the XMLHttpRequest I'm getting a Refused to get unsafe header "etag" error. I already ran out of ideas how to fix this. Does anybody know what could be wrong?
EDIT: Apparently that behaviour is caused by the Origin header - when it is present in the request, the Access-Control-Expose-Headers in the response is empty. Unfortunately, I don't have access to the backend code, so I can't provide an example. All response headers:
HTTP/1.1 200 OK
Server: openresty/1.9.7.5
Date: Sun, 03 Sep 2017 13:02:55 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Expose-Headers:
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: *,x-requested-with,Content-Type,If-Modified-Since,If-None-Match,latest_time
Access-Control-Max-Age: 1728000
ETag: "eef3e52bc505031d93da42098f32cc60"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: eb5c7353-0b4b-43c8-b2ff-4763d56d9ec9
X-Runtime: 0.015680
Access-Control-Allow-Credentials: true
Vary: Origin

ElasticSearch Access-Control-Allow-Headers header is not present

I am making a POST request from a local https server to an ElasticSearch endpoint which has been configured as follows
http.cors.enabled: true
http.cors.allow-credentials: true
http.cors.allow-origin: "*"
http.cors.allow-methods: OPTIONS, HEAD, GET, POST, PUT, DELETE
http.cors.allow-headers: X-Requested-With, X-Auth-Token, Content-Type, Content-Length, Authorization, Access-Control-Allow-Headers, Accept
The request has headers:
Access-Control-Allow-Headers: Accept, Access-Control-Allow-Headers, Authorization, Content-Type
Content-Type: application/json; charset=utf-8
Accept: application/json; charset=utf-8
Access-Control-Allow-Credentials: true
Authorization: (basic authentication token)
On a POST request, the following error appears: Request header field Access-Control-Allow-Headers is not allowed by Access-Control-Allow-Headers in preflight response.
The network debugger indeed shows that the Access-Control-Allow-Headers header is not present in the response header. The response header:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://dl.dropboxusercontent.com
Vary: Origin
Access-Control-Allow-Methods:
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 1728000
content-length: 0
date: Fri, 29 Apr 2016 14:08:14 GMT
Note that Access-Control-Allow-Headers is not present and Access-Control-Allow-Methods is blank. All possible string formats have been tested, and these headers do not appear.
You should add following signs to your elasticsearch.yml:
http.cors.allow-methods : OPTIONS, HEAD, GET, POST, PUT, DELETE
http.cors.allow-headers : Authorization, X-Requested-With,X-Auth-Token,Content-Type, Content-Length
and then restart the es, enjoy!
I finally solved the problem with these config lines in elasticsearch.yml:
http.cors.enabled: true
http.cors.allow-origin: /https?:\/\/(localhost)?(127.0.0.1)?(:[0-9]+)?/
http.cors.allow-methods: OPTIONS, HEAD, GET, POST, PUT, DELETE
http.cors.allow-headers: Authorization, X-Requested-With,X-Auth-Token,Content-Type, Content-Length
As of 2022, according to https://docs.elastic.co/search-ui/tutorials/elasticsearch
try include all headers below
http.cors.allow-origin: "*"
http.cors.enabled: true
http.cors.allow-credentials: true
http.cors.allow-methods: OPTIONS, HEAD, GET, POST, PUT, DELETE
http.cors.allow-headers: X-Requested-With, X-Auth-Token, Content-Type, Content-Length, Authorization, Access-Control-Allow-Headers, Accept, x-elastic-client-meta
In my case, I forget to wrap the end of the line and thus get missing header error.
And this is the top search I got, so just put it here in case anyone made same mistake.

CORS works in chrome but not firefox, angularjs

I'm trying to use angularJS with a Jetty backend.
Preflight CORS requests are working fine in chrome but in firefox I get this CORS error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://remote.machine:8080/api/v1/provisioning/users/current-user. This can be fixed by moving the resource to the same domain or enabling CORS.
The Headers for the options request are as follows:
HTTP/1.1 200 OK
Date: Wed, 24 Sep 2014 16:06:12 GMT
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
X-Frame-Options: DENY
Access-Control-Allow-Methods: GET, PUT, POST, OPTIONS, DELETE
Access-Control-Max-Age: 3600
Access-Control-Allow-Headers: Access-Control-Allow-Headers: Origin, Authorization, X-Requested-With, Content-Type, Accept
Access-Control-Allow-Credentials: true
Set-Cookie: JSESSIONID=eyv8cpnnfphy1b0121uzt293y;Path=/
Content-Length: 0
Server: Jetty(9.2.2.v20140723)
The angular request is set up as follows:
$http.get(AS_API_URL + '/provisioning/users/current-user', {
headers: {
'Authorization': 'Basic ' + base64EncodedAuth
}
});
For some reason these headers work fine in Chrome but not in Firefox, does anyone have a clue as to why? Do I need to provide more info?
EDIT:
Musa was right about the Access-Control-Allow-Headers being malformed.
I edited the Jetty Server so the header now reads:
Access-Control-Allow-Headers: Origin, Authorization, X-Requested-With, Content-Type, Accept
I give my thanks to you Musa, you just saved my day :)
To expand upon Musa's answer in the comments, Firefox is blocking the request because the following header has the header twice instead of once:
Access-Control-Allow-Headers: Access-Control-Allow-Headers: Origin, Authorization, X-Requested-With, Content-Type, Accept
should be changed to
Access-Control-Allow-Headers: Origin, Authorization, X-Requested-With, Content-Type, Accept

XSS Problems with Ajax GET Request

I have the following coffee script which performs some sort of login:
signIn: (url, completion) ->
$.ajax
method: 'GET'
url: url
dataType: 'json'
error: (jqXHR, status, errorThrown) ->
completion false, errorThrown
success: (data)->
completion true, data.Identifier
When I check the given URL in the browser I get a valid JSON Response back.
However, when this call is executed using JavaScript I get the following error in the console . Please note that I have changed the URLs for obfuscation:
XMLHttpRequest cannot load http://my.servicedomain.com/session/someIdentifier?access_token=secret.
Origin http://html.server.net is not allowed by Access-Control-Allow-Origin.
These are my headers, which I get from the my.servicedomain.com server:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 1417
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Authorization
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
X-Powered-By: ASP.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Authorization
Date: Wed, 10 Jul 2013 14:24:35 GMT
Vary: Accept-Encoding
Content-Encoding: gzip
Connection: Keep-Alive
Why do I get this error, even though I have Access-Control-Allow-Origin: * in the response header?
I have just figured out the answer myself. I knew that I had duplicated headers in my response, but I was assuming this would not be a problem.
It looks like this is a Problem according to the CORS Spec:
If the response includes zero or more than one Access-Control-Allow-Origin header values, return fail and terminate this algorithm.
This is also described in this SO Thread:
Will duplicate "Access-Control-Allow-Origin: *" headers break CORS?

Categories

Resources