When we log in google. It set cookies for both Google and youtube domain.
In the network, I see two interesting get call,
https://mail.google.com/accounts/SetOSID?authuser
https://accounts.youtube.com/accounts/SetSID.
How can I achieve the same results?
I have to set a cookie for a website like youtube.com from a website like google.com.
I tried making a XMLHttpRequest(). It didn't work. But If I open my second domain in a separate tab, It set the cookie for the second domain.
My request header :
Request URL: https://mysite.ngrok.io/SetSID?params=xyz
Request Method: GET
Status Code: 302 Found
Remote Address: xx.xx.xxx.xxx:xxx
Referrer Policy: no-referrer-when-downgrade
My Response Header :
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Allow-Origin: *
Content-Length: 184
Content-Type: text/plain; charset=utf-8
Date: Wed, 09 May 2018 16:29:34 GMT
Location: https://mysite.ngrok.io/SetSID/callback?params=xyz
set-cookie: _cookie=sample; Path=/; HttpOnly
Vary: Accept
X-Powered-By: Express
If we inspect the console, the request type is binary.
Did it somehow help them achieve the current goal ?
This API is hit
https://myaccount.google.com/accounts/SetOSID?authuser=1&continue=https%3A%2F%2Faccounts.youtube.com%2Faccounts%2FSetSID
followed by the api
https://accounts.youtube.com/accounts/SetSID?ssdc=1&sidt=xxx&continue=https://mail.google.com/mail/u//?authuser
If I am not wrong, Google is loading the https://accounts.youtube.com in a split second and setting up the cookies. It then continue to mail.google.com. (see the params in continue)
Related
I'm receiving a 403 error when requesting data from the Mapbox static tiles API. This API call has been working fine until recently, and we haven't made any changes to our web server configuration, nor our URL policy.
We are accessing via a web page on one of the whitelisted domains, not a tool/CLI.
A 403 suggests that the issue is some kind of access issue. I tried removing the URL policy for the access token in question (to allow access from any domain), and this seemed to work - the API calls started succeeding again. So I think the problem only concerns tokens scoped to specific URLs/domains.
Here's an example of the 403 response headers I'm seeing;
Access-Control-Allow-Methods GET
Access-Control-Allow-Origin *
Cache-Control no-cache
Connection keep-alive
Content-Length 23
Content-Type application/json; charset=utf-8
Date Tue, 28 Sep 2021 15:41:04 GMT
ETag W/"17-bqIm6pxC4cx+ZoszvXxsClwgWw8"
Via 1.1 572270b8624c0596173ef8189682d917.cloudfront.net (CloudFront)
X-Amz-Cf-Id pxwf39dmi1zB3oFY9dvYia_dVZpcgKpYCTDJT5Vjfp85MsU8NuVeLA==
X-Amz-Cf-Pop LHR52-C1
X-Cache Error from cloudfront
X-Content-Type-Options nosniff
X-Edge-Origin-Shield-Skipped 0
X-Powered-By Express
In particular, the "X-Cache Error from cloudfront" header seems to be of interest - although not really informative enough for me to action anything off of it.
So, I have two sites http://localhost/ and http://3rdPartyLocallyHostedAPI/ (Not the real names) - both are local intranet sites, and due to the nature of 3rdPartyLocallyHostedAPI being it's namesake, localhost is having to make CORS requests to it.
These requests are working fine, data is returned or can be posted to 3rdPartyLocallyHostedAPI as would be expected, however this warning is being shown:
A cookie associated with a cross-site resource at http://3rdPartyLocallyHostedAPI/ was set without the SameSite attribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with SameSite=None and Secure. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.
Now, I've looked at multiple answers such as this one, this one and this one which state that the SameSite attribute needs to be set on the server, which doesn't make any sense as the two cookies it's taking issue with (ss-pid and ss-id) are set in the request, not returned in the response? This has confused me, as I can't figure out how or where to make a change to ensure the SameSite policy on these cookies is set to none or secure.
I think it's the jQuery that is performing the AJAX request that is at fault though:
// trimType and queryValue are determined elsewhere by some jQuery selections, their values are not important to the question being asked.
$.ajax({
url: 'http://3rdPartyLocallyHostedAPI?q=' + trimType + '?q=' + queryValue + '&resultsOnly=true',
data: {
properties: (trimType === 'Record') ? 'Title,Number,RecordRecordType' : 'NameString'
},
xhrFields: {
withCredentials: true
},
dataType: 'json'
}).done(function (data) {
if (data.Results.length > 0) {
$resultsPane.html('');
for (var i = 0; i < data.Results.length; i++) {
// Not relevant to the question being asked so removed, only some jQuery in here to display results on page.
}
} else {
$resultsPane.html('<p class="py-1 pl-1 list-group-item text-muted">No Results found.</p>');
}
}).fail(function () {
$resultsPane.html('<p class="py-1 pl-1 list-group-item text-muted">No Results found.</p>');
});
When it doesn't have the withCredentials = true property set, and therefore is authenticating anonymously against the API (which only gives limited access, hence the need to pass windows credentials), the SameSite warning does not appear. Here is the request header:
GET /CMServiceAPIAuth/Location?q=%22SDC%20*%22&resultsOnly=true&properties=NameString HTTP/1.1
Host: serverName
Connection: keep-alive
Accept: application/json, text/javascript, */*; q=0.01
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36
Origin: http://localhost:64505
Referer: http://localhost:64505/Home/DisplayRecord
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Cookie: ss-pid=OQtDrnmok62FvLlZPnZV; ss-id=cIaIcS3j0jmoouAaHHGT
The two cookies that chrome is having issues with are ss-pid and ss-id, there are no cookies being passed back by the response headers:
HTTP/1.1 200 OK
Cache-Control: private,no-cache
Content-Type: application/json; charset=utf-8
Vary: Accept
Server: Microsoft-IIS/8.5
X-Content-Type-Options: nosniff
X-Powered-By: ServiceStack/4.512 NET45 Win32NT/.NET
X-AspNet-Version: 4.0.30319
Access-Control-Allow-Origin: http://localhost:64505
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST,GET,OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Persistent-Auth: true
X-Powered-By: ASP.NET
Date: Mon, 27 Jul 2020 07:02:06 GMT
Content-Length: 1597
So, with all this in mind, can someone explain where I'm going wrong? Do I need to make changes to the jQuery AJAX to prevent this warning (and therefore prevent a future issue when the change the warning is alerting me about happens) - or, do I actually need to set an additional header on the server, I'm wondering if in the pre-flight OPTIONS request if it tries to figure out the SameSite setting for the request or something like that?
Via an IIS Module, I do have access to add additional headers to the response the server is sending, so if that is what is needed, I can do it - I just don't quite understand on which end the warning is being caused by and would appreciate any explanation people can provide.
Ok then, I think I've done enough research to figure out the issue I'm facing, so I'll answer my own question.
So, one page that really helped me to actually understand what SameSite is about was this one, so to anyone else having issues with SameSite, take a read so that you understand the reason behind it and how it works.
Having done some reading and seeing this answer to another post helped me to connect the dots. I deployed the web site I'm working on to an actual web server, and found that the following was the response header:
HTTP/1.1 200 OK
Cache-Control: private,no-cache
Content-Type: application/json; charset=utf-8
Vary: Accept
Server: Microsoft-IIS/10.0
X-Content-Type-Options: nosniff
X-Powered-By: ServiceStack/4.512 NET45 Win32NT/.NET
X-AspNet-Version: 4.0.30319
Set-Cookie: ss-pid=0QyVIKf4edkAKd2h4be5; expires=Fri, 27-Jul-2040 09:58:39 GMT; path=/; HttpOnly
Set-Cookie: ss-id=fmM1WQsDxXGfR8q9GL6e; path=/; HttpOnly
Access-Control-Allow-Origin: http://server
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST,GET,OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Persistent-Auth: true
WWW-Authenticate: Negotiate oYG2MIGzoAMKAQChCwYJKoZIgvcSAQICooGeBIGbYIGYBgkqhkiG9xIBAgICAG+BiDCBhaADAgEFoQMCAQ+ieTB3oAMCARKicARusah2q1K2ACHwoq1n6DCNq5rx/HFdbK5sU9EohnxrRSpzmelskTTa9xmW8wgeUdwRNQCqMsD/dZ/pUjhdl2CVWjmFZZAfnKl6JEker+s79E9uFXThZZKnqfpqEgSvvqSYpp1KMkaYBYd1uf5mRyE=
Date: Mon, 27 Jul 2020 09:58:40 GMT
Content-Length: 1597
There are two Set-Cookie headers being issued by the server to store values for ss-id and ss-pid. These cookies apparently stand for permanant session ID and session ID, and are issued by ASP.NET for tracking sessions. The browser does not accept and set these two cookies as they lack the SameSite=none setting and the Secure setting - these are the two cookies mentioned in the post above that I was talking about.
So to fix this issue, first off I need to switch to using https for the API (and potentially the site itself) - which I have already done, and somehow figure out how to get the 3rd party API to set SameSite attributes in it's session related cookies.
So for others who hopefully have complete control of your API's etc, you should just be able to set these attributes whenever you are creating/sending cookies in responses, and therefore send cookies from the site to other domains by setting SameSite=None and Secure.
I'm accessing nasa pictures with their public api, but i get this error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at
[nasa api website] (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
But when i inspect their response header, the ‘Access-Control-Allow-Origin’ is present and set to '*', here you can see it:
RESPONSE HEADERS:
Access-Control-Allow-Origin *
Age 0
Cache-Control max-age=0, private, must-revalidate
Content-Encoding gzip
Content-Type application/json; charset=utf-8
Date Sat, 28 Mar 2020 14:37:13 GMT
Etag W/"e26hidden..."
Referrer-Policy strict-origin-when-cross-origin
Server openresty
Strict-Transport-Security max-age=31536000; includeSubDomains
Vary Origin
Via https/1.1 api-umbrella (ApacheTrafficServer [cMsSf ]), 1.1 vegur
X-Cache MISS
X-Content-Type-Options nosniff
X-Download-Options noopen
X-Frame-Options SAMEORIGIN
X-Permitted-Cross-Domain-Policies none
X-RateLimit-Limit 1000
X-RateLimit-Remaining 999
X-Request-Id 00c8c415-37ad-474b-bfbd-8e968d60f37f
X-Runtime 0.125778
X-Xss-Protection 1; mode=block
REQUEST HEADERS:
Accept text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding gzip, deflate, br
Accept-Language en-US,en;q=0.5
Connection keep-alive
Host api.nasa.gov
If-None-Match W/"e26chidden.."
Upgrade-Insecure-Requests 1
User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:74.0) Gecko/999991 Firefox/74.0
There’s a common mistake that can happen when specifying a URL for a cross-origin request in code, and the mistake can cause browsers to end up reporting a CORS error when in fact the problem is simply an easy-to-overlook mistake in the request URL itself.
The mistake is just a missing "s": using "http" as the URL protocol part instead of "https".
That missing "s" causes the server you sent the request to respond with a 3xx redirect to the equivalent https location of that URL. But the problem is: by default, many/most servers won’t include the Access-Control-Allow-Origin header in 3xx responses. So the browser gets that 3xx, but because it lacks the Access-Control-Allow-Origin header, the browser refuses to let your code follow the redirect; instead the browser stops right there and emits a CORS error.
So when you encounter a case like this, the way to troubleshoot it is: Open the Network pane in devtools and inspect the response. Check the response status code shown there and check the response headers. If the cause is the mistake described in this answer, you’ll see a Location response header. That value is the URL to which the server is trying to redirect the request.
And when you look at the Location value, you might initially think it’s exactly the same as the request URL you have in your code, because it’s easy to overlook that the difference is just that single missing "s". But of course if you take the URL in that Location value and replace the request URL in your frontend code with it, and it works, then the difference becomes apparent.
So in the case of the URL in this question, the problem was just, the frontend code specified a http://mars.jpl.nasa.gov URL that should instead be a https://mars.jpl.nasa.gov URL.
I'm trying to make request from client-side javascript to the google oauth endpoint (https://accounts.google.com/o/oauth2/v2/auth) with a google calendar scope. Thing is, I can't use google's javascript client, because I'm actually using webpack, and I don't want to have separately include a javascript script outside of my bundle.js.
So instead, I'm using axios (https://github.com/mzabriskie/axios) to make the HTTP GET to the aforementioned token endpoint. Here's what my request looks like:
https://accounts.google.com/o/oauth2/v2/auth?response_type=token&client_id={client id here}&nonce=c8ef445540186351d9108ad64d7a5b65&scope=https:%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar
I generated the nonce using the crypto-js library's MD5 function. Here are the request headers:
Accept:application/json, text/plain, */*
Origin:http://localhost:8000
Referer:http://localhost:8000/admin
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36
The response I get from google looks like this:
alt-svc:quic=":443"; ma=2592000; v="32,31,30,29,28,27,26,25"
alternate-protocol:443:quic
cache-control:no-cache, no-store, max-age=0, must-revalidate
content-encoding:gzip
content-type:text/html; charset=utf-8
date:Mon, 18 Apr 2016 07:16:21 GMT
expires:Fri, 01 Jan 1990 00:00:00 GMT
pragma:no-cache
server:GSE
status:400
x-content-type-options:nosniff
x-frame-options:SAMEORIGIN
x-xss-protection:1; mode=block
And I see this log in my chrome devtools console:
XMLHttpRequest cannot load https://accounts.google.com/o/oauth2/v2/auth?response_type=token&client_id={client id here}&scope=https:%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. The response had HTTP status code 400.
I've made sure that in my google app console, under the corresponding client id, I've added http://localhost:8000 to the "Authorized Javascript Origins" field, and I've made sure to enable authorization for the google calendar api. I've read that the web client implicit auth flow doesn't use the redirect uri, but I've tried filling that out regardless (I've tried the values http://localhost:8000 and http://localhost:8000/admin, which is the page I'm sending my request from). Having spent hours googling this, I've found nothing to suggest that what I'm doing shouldn't work.
So my question is, if I've allowed http://localhost:8000 as an authorized origin for my client ID, why am I still not able to send a request (albeit via javascript) to that auth endpoint?
I believe you should redirect the browser to this oauth2 endpoint rather than just trying to make an ajax request to it.
https://developers.google.com/identity/protocols/OAuth2UserAgent#overview
(Note: This is a follow up to my question Can jQuery.getJSON put a domain's cookies in the header of the request it makes? and covers the XSS case of Setting a cookie in an AJAX request?)
I've been told I'm unable to set cookies to be read by other domains that are not subdomains of the current domain using $.cookie(..., ..., {domain: ...}). But in a comment on a response to my last question, #zanlok said "The server's reply, however, can definitely set a cookie" and it got two upvotes.
So I thought I'd try using a service which was created for the explicit purpose of setting cookies called Freebase's "touch" API. The call looks like:
$.getJSON("http://api.sandbox-freebase.com/api/service/touch",
{}, // URL parameters
afterCookieIsSetCallback); // Callback function
Looking in FireBug at the response header it's like this:
Date Wed, 24 Nov 2010 03:35:28 GMT
Server Apache
X-Metaweb-Cost [...]
Etag [...]
Expires Wed, 24 Nov 2010 03:35:29 GMT
Cache-Control no-store
Vary Accept-Encoding
Content-Encoding gzip
Set-Cookie mwLastWriteTime=1290569730|10325_9202a8c04000641f80000000199eff96|sandbox; expires=Thu, 25-Nov-2010 03:35:28 GMT; Path=/
Last-Modified Wed, 24 Nov 2010 03:35:28 GMT
Content-Length 134
Content-Type text/plain; charset=utf-8
X-Cache MISS from cache01.sandbox.sjc1.metaweb.com
Connection keep-alive
X-Metaweb-TID cache;cache01.sandbox.sjc1:8101;2010-11-24T03:35:28Z;0001
So there's definitely a Set-Cookie in there, and the script runs the response handler. Yet the cookie is not present in the request headers for later JSON requests this script makes to .sandbox-freebase.com.
(By contrast, simply typing the touch api URL into the address bar and loading it that way does set the cookie for future requests. That applies even in other tabs.)
This seems to be a deviation from a prior "expected behavior", because there was a toolkit published by MetaWeb circa "2007-2009" which seemed to think such an approach could work:
http://www.google.com/codesearch/p?hl=en#v099O4eZ5cA/trunk/src/freebase/api.js&q=touch%20package:http://mjt%5C.googlecode%5C.com&l=340
Without knowing much about it, I'm wondering if it was a recent change that Firefox adopted and then WebKit followed suit. Perhaps the one mentioned here:
http://trac.webkit.org/browser/trunk/WebCore/xml/XMLHttpRequest.cpp#L856
So is there any canonical documentation on this particular issue?
The AJAX call you are making, is making a request to a domain outside of the domain of the top level url(the url in the address bar). This results in it being a 3rd party cookie, by default Internet explorer won't persist a 3rd party cookie. Meaning that the cookie will come back in the Set-Cookie header on the first request, but subsequent requests that you make to that server will not have that cookie sent in the request.
Like you said, if you go directly to the url in your browser it works. This is because in this case it's a first party cookie.
In order for IE to accept 3rd party cookie's the server that is sending the SET-COOKIE header on it's response, must also have a P3P Policy Header set.
Here is an example, when you navigate to CNN, you will notice one of the requests it makes is to a domain name of b.scorecardresearch.com, scorecardresearch is dropping a tracking cookie, but this cookie is considered a 3rd party cookie. So in order to make it work they had to also in include a p3p header, see headers below:
HTTP/1.1 200 OK
Content-Length: 43
Content-Type: image/gif
Date: Thu, 02 Dec 2010 19:57:16 GMT
Connection: keep-alive
Set-Cookie: UID=133a68a4-63.217.184.91-1288107038; expires=Sat, 01-Dec-2012 19:57:16 GMT; path=/; domain=.scorecardresearch.com
P3P: policyref="/w3c/p3p.xml", CP="NOI DSP COR NID OUR IND COM STA OTC"
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Pragma: no-cache
Cache-Control: private, no-cache, no-cache=Set-Cookie, no-store, proxy-revalidate
Server: CS
If you were to copy this header and add it to the response, you would notice that the cookie's start working,
P3P: policyref="/w3c/p3p.xml", CP="NOI DSP COR NID OUR IND COM STA OTC"
It's best that you craft a P3P header specific for your business, but the above should work for testing purposes.
If I correctly understand you, you are wondering why the server sends Set-Cookie only on the first request. If that is true, then it's by design - take a look here:
http://en.wikipedia.org/wiki/HTTP_cookie
Set-Cookie is like a setter - the server sends it for the browser to cache it locally. It can send every time, but there is no need to do that, so it will send it again only if it needs to change the value stored locally.
Browser, on the other hand, will send Cookie header every time with the contents set by the last issued Set-Cookie from the server.