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).
Related
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.
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.
I am doing development in reactjs on my localhost. I have an api written in nodejs deployed at https://bianca-service-dev0.cfapps.io
Using react i am calling an auth endpoint in the api to login my user. The auth endpoint returns a token to me in response body and a cookie name CSRF-TOKEN. When i try to view document.cookie i only see the cookies set by my localhost and dont see cookies set by the api.
Can I access cookies set by a different domain?
Not directly.
JavaScript running in the browser can only read cookies associated with the page that the JS is running on.
Requests to other origins (if sent withCredentials) will include the cookies transparently though so you can still use them to access content on the origin that set them.
We're developing a system using AngularJS and PHP. I have some concerns about the security on the matter of authentication. I wrote a basic authentication based upon multiple different examples around the web (I only started learning Angular), which uses a database via REST API calls. On some routes it checks if the user information exists before it creates a promise, but I have a few questions:
Can session information be stored in$window.sessionStorage or $cookieStorage without the client being able to modify these values or should I keep them server-side with PHP $_SESSION and fetch them from there, never storing them anywhere in JS? Session information can contain uid, role, email and name
Can I store a value, like let's say $rootScope.role or $scope.role without the client being able to modify this value? Let's say for example we have multiple levels of user accounts where super-admin is the highest. If I create a route with a resolve which would check the $rootScope.rolelevel, can a novice go change the $rootScope.role value to super-admin gaining access to restricted backend sections?
Will I have to implement a GET /session check on every route to which gets $_SESSION data to actually make sure this data stays untouched?
Or am I just paranoid?
You're not paranoid, any client-side authentication should be questioned. When it comes to security, you can't assume that the client is forbidden or unable to do anything on their own device.
Security related functions must stay on the backend, an environment you set up and control.
can a novice go change the $rootScope.role value to super-admin gaining access to restricted backend sections?
Asking questions like "can a novice..." are futile in my opinion. Do you only want security against novice malicious users? If your "restricted backend sections" can be accessed by modifying the frontend, you're doing something wrong.
Great question! Front end security requires the cooperation of the browser and your server.
Javascript is an untrusted environment, so you can’t reliably enforce any authorization there (i.e. you can’t use properties on $scope to prevent a user from doing something). Your server needs to enforce these rules by ensuring that every API request is properly authenticated and authorized.
API requests are typically authenticated with a cookie. The cookie typically contains a session identifier, which points to a row in your database which contains the authorization information (i.e. what the user is allowed to access). The user can get this cookie by logging in (presenting hard credentials like a username and password).
The cookie may also contain a signed access token, such as a JWT. Depending on your architecture you can remove the session database and rely purely on the signed token for authentication.
In either case you want to set the HttpOnly flag on the cookie when your server is sending the cookie to the browser. This will prevent the JavaScript environment from reading the cookie, this is a good security measure to yourself against XSS attacks.
You also need to protect yourself against CSRF attacks. This is a situation where another website can trigger a GET or POST request to your API, and this will send along the authentication cookies. You can guard against this by creating another cookie that does NOT have the HttpOnly flag, and storing a random value in it. The JS environment must attach this value to any request, typically as a custom HTTP header. Your server then asserts that the value is associated with the session or token.
I’ve tried to cover all the bases in this answer. If you’d like to read more, you can check out these blog posts that I’ve written, they discuss token authentication, but each has sections that cover front-end security issues:
Token Based Authentication for Single Page Apps (SPAs)
https://stormpath.com/blog/build-secure-user-interfaces-using-jwts/
Disclaimer: I work at Stormpath and we provide a secure, hosted user management solution for any application, including Angular! See https://docs.stormpath.com to learn more and find the SDK for your server.
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.