I am testing an application that requires a user to authenticate, and then uses a cookie to track the user session. If authentication fails, a cookie is set that identifies the session as belonging to an unidentified user.
Unfortunately, authentication is via Kerberos or NTLM, which cannot be done in JMeter 2.8. My plan is therefore as follows:
Log into website with Internet Explorer.
Copy cookie that identifies session out of IE and into JMeter cookie manager as a user-defined cookie.
Use JMeter to test application
Essentially, this is session hijacking.
What I am observing is that (1) the JMeter cookie manager does not seem to be supplying the cookie to the application in the first request, (2) after the first request the application sends a different cookie back to JMeter, and (3) subsequent requests use the application-defined cookie, not the one I supplied.
So my questions are:
Is the approach described plausible, in theory at least?
Do application-defined cookies always override user-defined cookies?
Why might the cookie manager be not sending my user-defined cookie?
Thanks in advance.
Try using JMeter nightly build, it has been reported recently that it worked with NTLM after upgrade of httpclient libraries.
http://jmeter.apache.org/nightly.html
You approach seems really weird to me and I don't think it will work or even if it does be realistic.
Related
My SPA uses React as front end and laravel API as backend.
When the user logs in (via axios and api), the api returns an access (Bearer token) as response. I use the react-cookie framework to store the access token as cookie in the Browser. This cookie will be read and used for any future request.
Is this the right way to do?
Isn't cookie data just something in the Browser that can be easily obtained by any attacker? Since it is just a file one the computer somewhere.
What is stopping an attacker from grabbing that cookie, impersonate as that user and start performing actions that requires authentication?
The token has a life span of lets say 1 year. It will only be refreshed every time the user logs in. I understand that if I set the life span shorter it will be more secure. However that will mean the user would have to log in constantly?
-----Update-----
Im not sure if any of the provided solution answered my question. A SPA app is front end based and the request can be from anywhere such as Postman, Mobile app, or any third party device that wish to talk to my backed server. So those device needs a way to store some access token locally to be used for any future request.
The only way I know this could happen is for my server to send some auth token to the requester and have it store it somewhere to be used for next request.
In this case, Im not sure if CSRF token or any other means would help my concern?
Just like facebook, if I clear my cache, I will have to re-login. That means facebook is storing something on my location computer so I can be automatically authenticated next time
I just want to add some disadvantages of storing tokens in cookies that you should also be aware of:
The max size of a cookie is only 4kb so that may be problematic if
you have many claims attached to the token.
Cookies can be vulnerable to cross-site request forgery (CSRF or
XSRF) attacks. Using a web app framework’s CSRF protection makes
cookies a secure option for storing a JWT. CSRF can also be partially
prevented by checking the HTTP Referer and Origin header. You can
also set the SameSite=strict cookie flag to prevent CSRF attacks.
Can be difficult to implement if the application requires
cross-domain access. Cookies have additional properties (Domain/Path)
that can be modified to allow you to specify where the cookie is
allowed to be sent.
------- Update -----
You can also use cookies to store the auth token, even it is better (at least in my opinion than using local storage, or some session middleware like Redis). And there are some different ways to control the lifetime of a cookie if we put aside the httpOnly and the secure flags:
Cookies can be destroyed after the browser is closed (session
cookies).
Implement a server-side check (typically done for you by
the web framework in use), and you could implement expiration or sliding window expiration.
Cookies can be persistent (not destroyed
after the browser is closed) with an expiration.
Your JS should not have access to the cookie. There are flags you can set on cookies that will help protect them and make sure they are only used for the correct purposes.
The HttpOnly flag is set on the cookie then JS will not be able to access it but it will still be sent with any request.
The SameSite flag will ensure that the cookie is only sent back to the site that gave it to you. Which prevents leakage.
The Secure flag will make it only send the cookie over a secured connection to prevent someone from sniffing it out of your web traffic.
Edit
You might want to lookup an authorization workflow but the gist of it is this:
User logs in with username and password
A JSON web token is issued upon login from the backend and sent to the browser
The JWT(JSON web token) can be stored in a cookie in the Web Storage(Session Storage) on the browser
Subsequent requests to the REST API will have the token embedded in the header or query string for authorization. With that form of authorization, your REST API understands who is making the request and what kind of resource to return based on the level of authorization
Please see #tpopov answer as he also made some really good points.
Although there are many posts about this topic (or closely related) on SO, I did not find what I am looking for.
As the title suggests I am using Django Rest Framework as a backend, and React as a frontend.
Now I implemented token authentication, and it works perfeclty. The only problem is that the token is stored in React's state, and if the user refreshes the page, he is no longer logged in (the token is lost).
So, now I want to switch to session authentication, since the problem is solved then. But that will require me to do some research, and before I go there I'd like to know if that is the best choice.
My question:
Do I need to use session authentication to have users stay logged in, even when the React's state changes. Or can I also achieve the same thing with token authentication (in a safe and responsible way?)
I figure I can save the token in a cookie, but that doesn't seem safe to me.
EDIT:
Later I realized, why not just store the token in a session?
SessionAuthentication would be the most straightforward way to achieve what you want. The configuration is described at http://www.django-rest-framework.org/api-guide/authentication/#setting-the-authentication-scheme This will set a session id in a cookie that is handled by the browser.
Alternatively you can store a token in the browser's cookie but that is vulnerable to XSS attacks and other javascript attacks. For more security you can store the token in an HttpOnly cookie. The cookie would be persisted across tab/window closes by the browser.
Also to clarify cookie handling is built into most browsers. Your react state is in userland and lives in a different memoryspace than cookie storage.
More info:
Ask HN: Cookies vs. JWT vs. OAuth
https://developer.okta.com/blog/2017/08/17/why-jwts-suck-as-session-tokens
http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/
I'm moving an ASP.NET web application away from Forms authentication to OIDC authentication through IdentityServer, with implicit flow for getting an ID token. Forms authentication has options in the client web.config such as 'timeout' and 'slidingExpiration' and I'm looking for a way to make sure the client is just as configurable when using IdentityServer.
I understand there are two separate cookie management systems in this scenario - the client's and IdentityServer's. I would like to align them as much as possible and have a single place for configuring these options. This could be either at either end, one handing responsibility to the other.
One option I've explored is setting UseTokenLifetime = true on both ends and then using the IdentityServer Client property IdentityTokenLifetime as a way to configure timeout for the client. Both cookies should then expire at the same time specified by the IdentityTokenLifetime. When the client's cookie times out it'll redirect to IdentityServer for authentication, where the login prompt will be shown because its own cookie will have expired too. However, I don't think this allows a sliding expiration option?
Another option might be to set UseTokenLifetime back to false, configure cookie options in the client cookie middleware, and ensure the client sends prompt=login when authenticating. This means even if IdentityServer has cookie settings which don't match the client (e.g. the IdentityServer cookie is still valid after client's has expired), it'll still always show the login prompt. The downside to this seems to be that it would inhibit SSO should I add more clients, because they'll always have to login for each client.
I would appreciate any thoughts on this
Thanks
I'm using the Cookie Middleware in ASP.NET Core for session cookies. The session cookie data is encrypted by the framework using the Data Protection API.
Just wanted to understand in detail what the level of protection is from this process. These are my current assumptions:
The cookie data cannot be viewed in transit or at rest in the browser and is tamper-proof
The cookie data can be replayed if sniffed over HTTP
The cookie data cannot be replayed if issued and sent only via HTTPS
If any of these assumptions are wrong or need more detail then I'd appreciate an answer.
Your assumptions are right: although authentication cookies are marked as HttpOnly by default, nothing prevents an attacker from stealing a cookie from browser's container and using it as-is to make malicious requests if he manages to install a malware on victim's machine.
In the future, ASP.NET Core will support a feature called "TLS token binding" that will make stealing authentication cookies much harder.
When supported by both the server and the user agent, this feature allows the server to bind sensitive data like authentication cookies or bearer tokens with a secret value only known by the original client (i.e by the browser).
In ASP.NET Core, this feature will be implemented at the cryptographic level: the secret transmitted by the browser will be used to derive the encryption/validation keys used by Data Protection to protect and unprotect the authentication cookies, so that no one will be able to use a stolen cookie without also sending the corresponding token.
I have a RESTful API which has annotations like #Consumes(MediaType.JSON) - in that case, would the CSRF attack still be possible on such a service? I've been tinkering with securing my services with CSRFGuard on server side or having a double submit from client side. However when I tried to POST requests using FORM with enctype="text/plain", it didn't work. The technique is explained here This works if I have MediaType.APPLICATION_FORM_URLENCODED in my consumes annotation. The content negotiation is useful when I'm using POST/PUT/DELETE verbs but GET is still accessible which might need looking into.
Any suggestions or inputs would be great, also please let me know if you need more info.
Cheers
JAX-RS is designed to create REST API which is supposed to be stateless.
The Cross Site Request Forgery is NOT a problem with stateless applications.
The way Cross Site Request Forgery works is someone may trick you to click on a link or open a link in your browser which will direct you to a site in which you are logged in, for example some online forum. Since you are already logged in on that forum the attacker can construct a url, say something like this: someforum.com/deletethread?id=23454
That forum program, being badly designed will recognize you based on the session cookie and will confirm that you have the capability to delete the thread and will in fact delete that thread.
All because the program authenticated you based on the session cookie (on even based on "remember me" cookie)
With RESTful API there is no cookie, no state is maintaned between requests, so there is no need to protect against session hijacking.
The way you usually authenticate with RESTFul api is be sending some additional headers. If someone tricks you into clicking on a url that points to restful API the browser is not going to send that extra headers, so there is no risk.
In short - if REST API is designed the way it supposed to be - stateless, then there is no risk of cross site forgery and no need to CSRF protection.
Adding another answer as Dmitri’s answer mixes serverside state and cookies.
An application is not stateless if your server stores user information in the memory over multiple requests. This decreases horizontal scalability as you need to find the "correct" server for every request.
Cookies are just a special kind of HTTP header. They are often used to identify a users session but not every cookie means server side state. The server could also use the information from the cookie without starting a session. On the other hand using other HTTP headers does not necessarily mean that your application is automatically stateless. If you store user data in your server’s memory it’s not.
The difference between cookies and other headers is the way they are handled by the browser. Most important for us is that the browser will resend them on every subsequent request. This is problematic if someone tricks a user to make a request he doesn’t want to make.
Is this a problem for an API which consumes JSON? Yes, in two cases:
The attacker makes the user submit a form with enctype=text/plain: Url encoded content is not a problem because the result can’t be valid JSON. text/plain is a problem if your server interprets the content not as plain text but as JSON. If your resource is annotated with #Consumes(MediaType.JSON) you should not have a problem because it won’t accept text/plain and should return a status 415. (Note that JSON may become a valid enctype one day and this won’t be valid any more).
The attacker makes the user submit an AJAX request: The Same Origin Policy prevents AJAX requests to other domains so you are safe as long as you don’t disable this protection by using CORS-headers like e.g. Access-Control-Allow-Origin: *.