Firefox not sending all Cross-Site cookies dispite CORS setup working in Chrome - cookies

I have various country domains which I wish to share cookie data with the primary domain, ie for auth purposes so that users remain logged in or identified when transitioning between these domains.
All is working as expected in Chrome, however Firefox is refusing to send non-session cookies along with cross-site requests. (session cookies are being included successfully). There are no warnings or errors within the firefox console relating to this.
When a cookie is set on the primary domain, I am setting SameSite to none and secure to true:
set-cookie: nonsessioncookie=abc1234; expires=Sun, 03-Sep-2023 13:36:26 GMT; path=/; SameSite=none; secure=true;
I then perform a jQuery request from a secondary domain to the primary domain:
$.ajax({
url: primaryHost + "/Services/AuthRequest.ashx",
data: { 'sdtoken': stoken},
xhrFields: {
withCredentials: true
},
crossDomain: true,
success: function (data) {
// Do Something
}
});
The following Request headers are sent, however notice the only cookie being sent is a session cookie; the 'nonsessioncookie' cookie is missing from the request:
Origin: https://secondary.domain
Connection: keep-alive
Referer: https://secondary.domain/
Cookie: ASP.NET_SessionId=rpchfdrzqzp5zujwi24fjll2
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
And the Response contains the following headers returned from the primary domain
access-control-allow-origin: https://secondary.domain
access-control-allow-methods: POST, GET, OPTIONS
access-control-allow-credentials: true
Chrome successfully passes the 'nonsessioncookie', however firefox doesn't, even though SameSite and secure is set.
Any thoughts what could be preventing non-session cookies from being passed?

Related

Session cookie is not getting saved from Pantheon

We are working on log in functionality with headless React and Pantheon with REST web services.
When I send login request to Drupal site in localhost, it sets a session cookie in my browser.
However, it doesn't do that for Drupal site deployed to Pantheon.
The cookie:
set-cookie: SSESS4ca8b3ff629fc50c99bed7678686=VYfXzM-S18y0n8PylU9HuHBVrEyZezRiwfirxB%2ClL; expires=Fri, 18-Nov-2022 18:14:03 GMT; Max-Age=2000000; path=/; domain=.oursitename.pantheonsite.io; secure; HttpOnly
Login request:
const body = {
name: name,
pass: pass,
};
const config = {
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": token,
},
withCredentials: true,
};
axios
.post(
`${process.env.REACT_APP_DRUPAL_URL}/user/login?_format=json`,
body,
config
)
Update:
Cookie is getting stored in Mozilla browser, but not in Chrome.
You need to append STYXKEY to the cookie's name. Cookies without that prefix are stripped from the request at the edge in Pantheon
You may find interesting as well this official documentation about pantheon and cookies
https://pantheon.io/docs/cookies

Not able to set cookie in browser with Deno Oak

I am trying to set up Authentication with Deno, Oak and JWT.
Objective:
Send cookie with jwt token in the response.
Set cookie in the browser
Use the cookie for subsequent requests.
Route: Cookie being set
export const getUsers = async ({ response, cookies }) => {
const users = await userCollection.find().toArray();
await cookies.set("token", "1234567890", {
sameSite: "lax",
});
response.body = users;
};
handling the Cors issue
app.use(
oakCors({
credentials: true,
origin: /^.+localhost:(3000|4200|8080)$/,
})
);
Response headers has the cookie but the same is not set in Application --> Cookies.
Please help me understand this issue.
using ctx.cookies.set is how you set a cookie in Oak, have in mind that by default it's httpOnly. Your browser might not show it in that case or you're looking in the wrong place.
From the screenshot we can see that Oak is setting the cookie correctly in the response headers:
token=1234567890; path=/; samesite=lax; httponly
To check that the cookie is set correctly, just add:
console.log(await ctx.cookies.get('token'));
And you'll see that in subsequent requests will log 1234567890 correctly.
Since you're mentioning CORS I suspect that you're looking the cookie to be present in the wrong domain, you should be looking for the cookie in:
localhost:8000 (server setting the cookie)
And not in your front end domain:port
So, if you issue the request from: http://localhost:3000 to http://localhost:8000, when you're in :3000 there will be no cookie present in Application > Cookies > http://localhost:3000, but it'll be in Application > Cookies > http://localhost:8000

Safari browser not keeping my cookie in memory

On my website, I'm using a http only cookie to do the authentification. It works perfectly in all browser, except Safari. Whenever the app close and reopen, it changes the cookie value to new_value.
Here's how the cookie is setup using the response object from express:
response.cookie('authToken', authToken, {
expires: date, // date 5 days from now
sameSite: 'strict',
httpOnly: true,
secure: true
});

Sveltekit newly created cookie is not showing in the hook's handle function

Summary
Once set-cookie header is sent in a response it takes another request before the cookie is visible in handle() function in the hooks.ts file.
Example
User POSTs username & password to the login endpoint;
Enpoint responds with set access_token cookie header;
User should be redirected to a protected page. (FAILS)
It fails because auth guard checks if the cookie exists, but it can't be seen from a code side at this point, only in the browser end.
Refresh the page
User is now able to be redirected to a protected page.
Minimal reproduction
It has dummy login/logout functionality & protected user profile. There are also server side console logs which shows that cookie lags to be recognised in a hook.
As mentioned in the comments, your server returns the HTTP status code 200 which does not redirect the Client after the Login. The browser assumes it is already at its final destination due to the status code.
In this case, best practice is to use the status code 302: Wikipedia
Modified /src/routes/auth/login.ts
import * as cookie from 'cookie';
export const post = (request) => {
return {
status: 302,
headers: {
location: '/',
'set-cookie': `${cookie.serialize('token', 'VALUE_OF_THE_COOKIE')}; path=/; HttpOnly`
}
}
};
export const del = (request) => {
return {
status: 302,
headers: {
location: '/',
'set-cookie': `${cookie.serialize('token', '')}; path=/; HttpOnly; maxAge: 0`
}
}
};

Accessing cookie with Angular or Javascript

I created an API /user/auth where I can send using POST a Json object like:
var user = {"username":"alex", "password":"m"}
$http(
{
method: 'POST',
url: '/api/v1/user/auth',
data: user,
}
).
success(function(data, status, headers, config) {
console.log(data)
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
The response from Django is the following:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Content-Type,*
Access-Control-Allow-Methods:POST,GET,OPTIONS,PUT,DELETE
Access-Control-Allow-Origin:*
Content-Language:fr
Content-Type:application/json
Date:Fri, 30 Aug 2013 15:22:01 GMT
Server:WSGIServer/0.1 Python/2.7.5
Set-Cookie:sessionid=w63m0aoo8m3vfmvv0vk5d6w1708ftsrk; Path=/
Vary:Accept, Accept-Language, Cookie
So Django returns a good cookie but I don't know why, Chrome doesn't set this cookie in Resource.
The request is sent from 127.0.0.1:8000 to 127.0.0.1:8080; I use this middleware to handle CROS requests and I also set:
SESSION_COOKIE_HTTPONLY = False
The problematic line is:
Access-Control-Allow-Origin: *
The credential request doesn't work with a wildcard allow origin. You have to specifically set the name, like :
Access-Control-Allow-Origin: http://127.0.0.1:8080
You can find more information here:
https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS?redirectlocale=en-US&redirectslug=HTTP_access_control#Requests_with_credentials
Ok thanks to Bqm link to mozilla I finally found why the cookie was not set.
Indeed you need to set in the header you sent:
Access-Control-Allow-Credentials: true
In Angular this is done with this method:
$http(
{
method: 'POST',
url: '/api/v1/user/auth',
data: user,
withCredentials: true
}
)
Once your backend will answer with a setCookie, the browser will then be able to set the cookie in your browser.