Problem with setting cookies on localhost during development - vue.js

I have nodejs express app as backend, and vue app as frontend on my server. I use session cookies for authentication and i just can't get them working on my local dev machine. Cookie is sent in the response but it is not saved by browser. I know that problem is that request origin must be same as host and i have read all the articles/questions related to the issue and i just can't solve it.
On the server, everything is proxied with nginx on https. Cookie is set there and everything works fine, because they are on same host.
My local vite dev server is running on https, on port 5173.
I use axios for api calls and i have set
axios.defaults.withCredentials = true;
Cookie properties are
sameSite:'none',
secure:true,
httpOnly:true,
In express:
app.use(
cors({
origin: ['https://localhost:5173', 'https://my.site.com'],
credentials: true,
})
);
Like i said before, cookie is sent in the response from the server and just not stored on browser because in request header:
host:my.site.com
origin:https://localhost:5173
referer:https://localhost:5173/
How can i solve this?

I followed solution in comments on https://stackoverflow.com/a/46412839/13781306.
It partialy works when i set
sameSite:'none',
secure:false,
Cookie is passed in requests but it is not stored in the browser storage/cookies. Which is fine and solves my issue.

Related

ExpressJs: Browser not sending cookies set for another domain set by api server

I have an admin dashboard react app that's running on admin.localhost.com:3000. I have an api server that's running on www.localhost.com:1337, and we have one react app for all clients, but each client uses it on a subdomain, for example, abc.localhost.com:4200, bcd.localhost.com:4200.
So from my admin dashboard I'm trying to log into abc as a client. The api server, when requested, verifies the admin, sets the cookie in the response for abc.localhost.com:4200 and responds with link for the client https://abc.localhost.com/home. The browser code passes the link to window.open().
However, if I check the browser tab for https:abc.localhost.com:4200, I don't see the cookie, so obviously the authentication fails.
res.cookie('token', token, {
secure: true,
domain: `abc.localhost.com:4200`,
sameSite: 'Lax',
maxAge: moment()
.add(10, 'minutes')
.valueOf(),
})
withCredentials is enabled for the client side agent, and the api server is configured accordingly.
It can't be done, server running on www.localhost.com:1337 can't set cookies for abc.localhost.com:4200. Allowing that would be apocalyptic.

Is it possible to set an HttpOnly Cookie from one domain to another subdomain

I originally posted this question here: https://security.stackexchange.com/questions/255737/is-it-possible-to-set-an-httponly-cookie-from-one-domain-to-another-subdomain
Please keep in mind that this question is specific to cookies with the HttpOnly flag set to true.
I am pretty sure that the answer to my question is no, but I have been have a hard time finding an answer through official documentation or other posts here. Here is simple use case for some context:
Python backend web application (api.domain.com)
Frontend JavaScript SPA (app.domain.com)
post requests to api.domain.com/api/auth/login/ made from app.domain.com using axios with the correct username and password return a response with an access JWT token in the body and the response sets a refresh cookie with an HttpOnly flag [should fail, since I believe that the cookie cannot be set on app.domain.com from an API request to api.domain.com? -- this is my question]
the access token is stored in memory and passed with each API request
requests made to api.domain.com/api/auth/refresh/ are sent on a schedule to refresh the short-lived access token.
I typically host the frontend app and backend app on the same subdomain (app.domain.com) and do path-based routing with something like CloudFront or nginx, and this works well. For example, all requests starting with /api/* are sent to the backend, and all other requests are sent to the frontend app. Trying to use a separate subdomain for the API seems to fail no matter what options I use for setting the cookie on the server.
Can someone help me confirm that it is in fact not possible to set an HttpOnly cookie on a subdomain like app.domain.com from an API request hosted on api.domain.com? It would be great if anyone can also help me find where this could possibly be found in official documentation.
Searching for set httpOnly cookie across subdomains, I haven't found anything directly relevant. I also didn't find anything in these resources that directly answers my question:
https://owasp.org/www-community/HttpOnly
https://learn.microsoft.com/en-us/previous-versions//ms533046(v=vs.85)?redirectedfrom=MSDN
This is possible. In fact I just did it.
On your frontend, using Axios:
const baseURL = 'https://api.example.com';
const api = axios.create({
baseURL,
withCredentials: true,
});
On your backend, using Express:
app.use(
cors({
origin: 'https://www.example.com',
credentials: true,
}),
);
app.post('/login', async (req, res) => {
res.cookie('someCookie', someCookieValue, {
secure: true,
domain: 'example.com',
httpOnly: true,
});
});

Postman set-cookie not working with the domain

I want to controll authentication with cookies. And In my browser working successfully.
But When I tried to test with postman, Postman doesn't add cookie to new request.
step - I login and response header like that:
But the response cookies tab like that:
And manage cookies window like that:
step - I send a request to unprotected router and I get unauthorized error.
This error started today. I don't remember making any changes to the settings.
Why Im getting this type error. How can I solve this?
I also had this problem, the fix is to remove the secure flag in the cookie when sending cookies from localhost as cookies set as secure can only be sent over HTTPS.
I had this issue when testing a local Laravel Sanctum request to /login.
I had the following .env values set
SESSION_DOMAIN=docker-api-service-name
SANCTUM_STATEFUL_DOMAINS=docker-api-service-name
However these needed to be set to localhost to match the domain of the APP_URL. After this, everything was working fine.
SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost
Someone mentioned that setting the secure flag to false will solve it, and it will. The explanation however was not entirely correct.
Secure will indeed only work over secure connections (HTTPS). However, it will also work over HTTP if it's done in localhost: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies

Disabling ngrok authentication

This question might be stupid, but I'm a beginner and I can't disable authentication on ngrok. I was having problems with CORS PUTs so, following this https://github.com/inconshreveable/ngrok/issues/196, I decided to use "disable_options_auth" but I can't seem to figure out how. I tried this on the configuration file:
tunnels:
demo:
proto: http
addr: 8080
inspect: false
auth: disable_options_auth
The linked GitHub issue mentions that ngrok didn't alter its config file auth parameter to accept a value of disable_options_auth:
... if this [accepting CORS preflight requests without auth while enforcing auth on all other requests] is the behavior you want, that you should implement the authentication yourself in your application.
If you just want to disable auth entirely that should make CORS preflight requests work, and you can do that by simply removing the auth parameter from your config altogether.

Strategy for CORS - issue with IE10 : xhr status returns 0 for HTTP 401

I have the following setup on my server:
Apache HTTP Server is serving a BackboneJS frontend application
Apache Tomcat is serving a Java based backend (CORS enabled).
Everything is running on a single server that I have full control over.
I'm currently using com.thetransactioncompany.cors.CORSFilter in the Java based backend to enable CORS. Everything seens to be working fine.
My frontend has the following code to redirect the user to the login page in case an un-authenticated REST call occurred:
$.ajaxSetup({
statusCode: {
401: function(){
window.location.replace('/#login');
},
403: function() {
window.location.replace('/#denied');
}
},
cache: false
});
Everything works fine on all major browsers except for IE10.
In IE10, when the non-authenticated users calls the REST serverm the server returns an HTTP 401 (as it should). The XHR object I'm seeing in the IE debugger hoewever seems to have translated this into status = 0. (On chrome you can cleary see that it has status = 401.
This appears to be a bug in IE10 where IE10 is treating HTTP status 401 as a network error. The console shows:
SCRIPT7002: XMLHttpRequest: Network Error 0x80070005, Access is denied
Is there a way to workaround this ?
I can add handling for statusCode 0 in the ajaxSetup but that seems more of a hack.
Is there a way to disable CORS altogether through some kind of Apache / Tomcat configuration ?
Currently my apache configuration is setup using vhosts so that the following public URLs map their corresponding internal hostname / ports.
http://mywebapp.com -> http://myrealservername:8080/ -> /var/www/http
http://myrestapi.com -> http://myrealservername:8088/ -> /usr/local/tomcat/webapps/restapi
Would it be possible / advisable to have Apache
continue serving the static webapp from http://mywebapp.com/restapi
exposing the REST API on http://mywebapp.com/restapi (keeping it "inside" the webapp).
If such a setup were possible I wouldn't need CORS anymore ? It would keep things a lot simpler while increasing browser support ?