Browser not sending cookies to APIs within same domain - javascript

I have APIs deployed in 2 separate namespaces, admin.abc.com (original) and api.admin.abc.com (new). Upon completing login, a jwt cookie is set by the admin.abc.com site for .admin.abc.com. The cookie is for the Session, Secure and HttpOnly and it does not have any SameSite restrictions set. This cookie works well for all API calls to admin.abc.com.
Due to some new changes requiring some services to deployed separately, there are now services also deployed in the namespace api.admin.abc.com. I have a status page that gives me information about the services, memory, etc. and it works fine for the original namespace. But when I add in a status call to the second namespace, no cookies are passed along and the call fails authentication. However, if I open the URL in another tab in my browser, the cookies are passed to the backend and the call succeeds.
I've looked into setting my own cookies in the header during the request after retrieving the jwt's value. This fails for 2 reasons: 1) I don't believe I can access the jwt's value as the cookie is HttpOnly, and 2) I can't set a cookie in the HttpHeader options. I get a "Refused to Set Unsafe Header" error in the console if I try. If I turn on 'withAuthorization:true', it does set it (but still prints the error) and then actually gets a CORS error.
If I manually disable the HttpOnly flag on the cookie using EditThisCookie extension, the calls work successfully. I don't really think it's an option for me with my company's security, but it technically works.
I know some suggest sending the jwt as an Authorization: Bearer token, which I would do, but because the cookie is HttpOnly, I can't retrieve the value and programmatically set it. Additionally there is another site-wide cookie I'd like to send over at times that I can't really switch to some custom header.
Thoughts on what I can do? Is it not possible? My only other option is that all requests to the new namespace have to be routed through an API built in the old namespace.

Related

Why don't browsers allow [::1]:8080 to set a cookie with Domain=127.0.0.1?

I am creating a project for school, and I need to create a backend in spring boot and a frontend in vanilla JS +HTML+ CSS. Since both are on localhost but on different Origins namely on port 8080/5500 respectively ,I am having some issues with CORS in that my cookies are not saved in the browser so no session is created between backend and frontend. This leads to the problem that after login in I will not be able to access securised endpoints because it will require me to log in again since no session is established.
What solution do I have for making this work / saving the cookies?
Further I will give several details and images about the issue that I have.
The backend uses MySQL, spring boot and RestControllers. It basically is a simple CRUD that I also added spring security to. Now this is how my Spring Config looks like
and this is how my CORS config looks like
and this is how my fetch request looks like in the frontend.
Also the request to /save
The flow is as follows : I make a request to /login, than I should be able to use the /save endpoint. This works flawlessly on postman since accessing /save works only after /login was successfully otherwise I get unauthorized, but it does not work in the browser because the cookie that is send with the first response is not saved as below. In the following image the response provides the JSESSION cookie after successfully authentication.
But then when I check cookies section, the cookie is not there.
And when I make a request to the /save endpoint I get the following issue
I also tried the answer over here How to set cookie domain and path with Spring boot but cookies are still not saved.
The browser refuses to allow a URL whose host is [::1] to set a cookie with a Domain attribute of 127.0.0.1. Why? Simply because, even though [::1] is the IPv6 equivalent of 127.0.0.1, the latter doesn't domain-match the former.
Anyway, why would you want to set a cookie with an IP address for the Domain attribute? You seem to be misunderstanding the purpose of that attribute; read what the MDN Web Docs page entitled Using HTTP Cookies has to say about it:
The Domain attribute specifies which hosts can receive a cookie. If unspecified, the attribute defaults to the same host that set the cookie, excluding subdomains. If Domain is specified, then subdomains are always included. Therefore, specifying Domain is less restrictive than omitting it. However, it can be helpful when subdomains need to share information about a user.
In your case, the host of the URL that sets the cookie is an IP address and not a domain. Therefore, specifying a Domain attribute for that cookie is pointless, simply because an IP address doesn't have subdomains.

How to handle httpOnly cookie authentication in next.js with apollo client

In my usual experience all single page apps I worked on used JWT as authentication mechanism. I came across api that uses httpOnly cookies for this.
Since we can't access such cookie via javascript to know if it is present or not, how does one handle this in react app?
My initial idea was to track this by setting some sessionStorage upon successful sign in and removing it if I receive an error related to authentication.
But this doesn't work well with next.js server side rendering I believe? We have it set up with apollo client which allows setting custom headers and cache.
Is there a common way to handle this authentication process with set up above?
httpOnly just means that the value can't be read by JavaScript.
So you make an HTTP request to the server and it will return a response with a Set-Cookie header.
Then any future requests will automatically include the cookie.
(Just make sure that you set withCredentials or the equivalent.)

Where to store the access token so it cannot be vulnerable to XSS

I am developing a web app and I am on a process of handling the Authentication of user. I am able to get the access token by initially making HTTP POST call to the API.
The idea know is where to store it so that it is not vulnerable to XSS.
Have heard of HttpOnly Cookie which makes it possible that the cookie is readable by the client (javascript), but the thing is why would I need something to store on my end when I cannot access it. How do I sent back to the backend (API) access token stored into coockie with http only since I cant get it so I am unable to attach it into headers of my http request.
Also, can I add a coockie with flag HttpOnly using javascript?
HttpOnly means you cannot read it from Javascript on the client but the browser is still aware of that cookie and it is being added to any subsequent request you are making to the server.
It can be useful for an auth session cookie for example.
Session cookies are usually opaque tokens that are meaningless to the user and are meaningful only to the server. Thus there's no real reason why the client code would need to read them
Also, can I add a cookie with flag HttpOnly using javascript?
No

Query about accessing HttpOnly Cookie & Secure cookie

I am working on RESTful SPA app using angularJS. Currently initial REST call is setting a "token" cookie on xyz.com ( secured response cookie) after successful user login. I am not able to read this cookie in Javascript/angular as I am working on localhost.
What I understood here , unless I run this app from xyz.com , i wont be able to access this cookie OR do I need a secured connection ?
Is my Understanding correct ?
Secondly, my understanding about "httponly" cookie is that , it wont be accessible from javascript even though you are on same host.
Please correct my understanding.
As the author of a website:
You cannot read a cookie for a different site (ever)
You cannot read an HTTP Only cookie with JavaScript
You cannot read a Secure cookie unless it is served over HTTPS
That's three separate conditions, with independent effects, and none, some or all of them can apply to any given cookie.
Therefore if a cookie is secure and for a different site then you can't read it no matter if you use HTTPS or not (since different site blocks you even if secure does not).

Deleting a cookie from a different domain when running locally

Per cookie specification this is not allowed (same principle as Same Origin Policy for ajax calls). As far as SOP is concerned, it does not apply, when you are running your javascript from file:/// (for example inside of a UIWebView). This is well documented and working in my example too. What about cookies though?
I have an app that makes a request to a server via javascript running, for all intends and purposes, locally (file:///). The authentication request sets a cookie with name let's say 'alpha', path: '/' and domain 'serverdomain.com'. During logout I need to clear the aforementioned cookie but I get the feeling that my attempts fail because I don't have access to it because it is considered to be from a different domain. Does that sound familiar? Or am I way off here? Is there a way to accomplish such a feat?
EXAMPLE
I am running my javascript on Chrome (using file:/// as the URI). I initiate a login and soon enough I can see the following cookie in the cookie manager plugin (this is not the actual cookie but it looks the same except for the name which we can say it is 'alpha'). The cookie is not marked http only but it has the 'session' and 'secure' checkboxes checked (unlike the screenshot below).
Now keep in mind that if I use the 'inspect element' feature of Chrome and go to 'Cookies', I get a 'There are no cookies for this site'.
During logoff I need to delete that cookie. So I do this in javascript:
document.cookie="alpha=; expires=Thu, 10 May 2000 15:07:07 GMT"
The cookie does not go away. The only way I can make it go away is by deleting it from the cookie manager. Should I be able to delete this cookie (while running from file:///)? If so how?
If the cookie was created on a different domain, this cookie won't be sent by the client to the server on the second domain, so you cannot remove it. You can set a cookie with the same name on this domain but that won't be the same cookie as the one that exists on the first domain.

Categories