HeaderHttpSessionStrategy x-auth-token is it safe? - spring-session

Is it safe to use HeaderHttpSessionStrategy? one can get hold of the x-auth-token and the same session can be simulated across browsers and machines

Note that cookies themselves are in fact HTTP headers. The header named Cookie contains your cookie, which makes your concern applicable to both session strategies Spring Session provides out of the box (although cookies can be considered safer since they are domain restricted).
Ultimately, what will make both strategies safe is the use of SSL transport, i.e. HTTPS.

Related

CSRF tokens for Rails API application

In Rails API applications we don't have out-of-box CSRF protection. In particular, storing access tokens (JWT for example) in the localStorage is not recommended, it is recommended to store in cookies (with httpOnly flag, SameSite, and etc.). But this time we're vulnerable to a potential CSRF attack. In a full-stack generated Rails app, a CSRF token is generated and embedded every time we open a form. But, I don't know and couldn't find anything how we protect against CSRF using tokens in Rails API apps. Do we have best practices or could anyone suggest an approach? I use access and refresh JWTs.
This is a usual tradeoff of API design, and you can choose from several different approaches, with different risk profiles.
You can store the access token in localStorage or sessionStorage, accessible to javascript, and accept the risk. The risk obviously is mostly around cross-site scripting (XSS), because this way javascript will have access to the token, and in case of XSS, it can be accessed by the attacker leading to session compromise. If talking about an API, responses should have the content type set to application/json, which makes the API itself protected from XSS in modern browsers. However, that does not mean the client (presumably a single page javascript app) is also protected, that can easily be vulnerable and leak the token. Some frameworks are better protected by default against XSS, some are not so much, and you might have checks like static scans in your SDLC that give you a level of assurance that might allow you to accept this risk. Also if your SPA needs to send the token to multiple origins (different api endpoints), you don't really have another option. In this case the token can be sent as a request header, and CSRF is not an issue.
Or you can exchange XSS for CSRF, by storing the token in a httpOnly cookie. This is generally considered more secure, because CSRF in general is a lower risk vulnerability (but still significant ofc). In that case you will not be able to send the token to different origins, but XSS will also not have access. This does not eliminate XSS for the whole application, but at least the token will be secure. The cost is now you will have to deal with CSRF. One way to do so is the samesite attribute to cookies. Using that for the token cookie will prevent most cases of CSRF, but it is a UX tradeoff, users of some browsers will not be protected, and some cases might be missed when using the lax option for samesite (like when a GET request changes state). Only having samesite as the protection will likely also be flagged in a penetration test for the reasons above.
If based on the above you decide to have more protection, you can implement something like double submit, and still keep it stateless, which these APIs many times aim to be. In case of double submit, you generate a random value, set it as a cookie (either directly on the client, or by a response from the server), and copy the same value from the cookie in a request header. The server only has to compare the value from the cookie to the one from the request, if they match, the request is ok. The reason this works is because an attacker on their own domain (origin) cannot set or read cookies for the victim application domain, this is ensured by the same origin policy of browsers.
A somewhat different approach might be applying a message authentication code (like HMAC) computed from the whole request and a shared secret (like the API key), and checking that on the server, but this is a can of worms, it's easy to have unprotected fields not covered by the HMAC, the server needs to have access to plaintext api keys so it can compute the hmac and so on - it's not at all straightforward to get this right).
Note that if the client app is vulnerable to XSS, that negates any CSRF protection as the attacker will have a way to get any secret from the client and with that, perform any request, with any computed field (like a valid token).

Is it possible in .Net MVC to return the JWT token for user-agent to include in subsequent requests automatically?

As captioned, is it possible to achieve this without using cookie or session,and without involving any JavaScript as well?
No, this is not possible without involving some persistence on the client that is going to make the subsequent requests. There's no such notion in the HTTP protocol (other than a cookie) that would indicate to the client to include some header on subsequent requests automatically. So basically if you don't like cookies you might find another place to store the access token on the client - the local storage in the browser seems like a good place and include it in subsequent requests that a javascript client would make. Of course if your clients are not javascript then they will have to find an appropriate place to store the access token.

FormsAuthentication.SetAuthCookie vs FormsAuthentication.Encrypt

Question #1:
Is setAuthCookie any less safe than FormsAuthentication.Encrypt(ticketVariable)?
I mean if anyone tries to modify the cookie created by setAuthCookie, by modifying the username, I suppose that'll violate the authentication on subsequent calls?
Question #2:
for those using iphones and tablets to access the site, I suppose FormsAuthentication will fail? Given that I don't want to use cookieless option, is there another approach to make the site secure on both smart phones web browsers and ummm none-smartphone web browsers?
cheers
SetAuthCookie basically creates a new FormsAuthenticationTicket with the supplied username & persistence options, serializes it, FormsAuthentication.Encrypt()'s it, and sets it in the Response.Cookies collection. SetAuthCookie and GetAuthCookie both call FormsAuthentication.Encrypt indirectly.
On subsequent requests, the FormsAuthentiationModule handles the AuthenticateRequest event. If it sees a cookie (it may have expired), it attempts to decrypt it's value with the machineKey (it may have been tampered with) and deserialize it back into a FormsAuthenticationTicket (it may be corrupt). If none of that (bad stuff) happens, the ticket contains the username, issue date, expiration info, etc.. If the ticket hasn't expired, an IIdentity and IPrincipal are created and assigned to HttpContext.Current.User and Thread.CurrentThread.Principal. In .NET 4.5 and later (I think), this is Claims-based (ClaimsIdentity, ClaimsPrincipal). Prior to that, it was a (GenericPrincipal, FormsIdentity) I think.
Any tampering at all on the user side will cause the request to be treated as anonymous. It will fail to decrypt. The only things that would compromise this validation would be if the machineKey in web.config/machine.config somehow got into the hands of an attacker or if there was a bug in the framework code (search for Padding Oracle for a historical example of this).
Aside from that, the other thing to watch out for would be session hijacking. If someone steals your cookie on a public wifi for example, they can present it to the server and the server will behave as if it's you. This generally involves network traffic sniffing. For these reasons, best practice is to use SSL for your entire site and set the cookie to HTTP only and Secure (only presented over https connections) in web.config/system.web/authorization/forms. HTTP only means that it will not be available to client-side Javascript. HTTP Only and Secure effectively means HTTPS only. This will only work if you use SSL on your entire site.
FormsAuthentication will work fine on mobile web browsers. It simply requires the client to accept cookies. As far as I know, all mobile devices will allow this.

In MVC what does the httpOnlyCookies attribute actually do?

I'm confused as to what this setting actually does.
According to MSDN, "Gets or sets a value indicating whether the support for the browser's HttpOnly cookie is enabled."
But I'm struggling to understand what this actually means.
The problem I am having is that in my MVC application, the session cookie is not being sent with the secure flag. I've put the RequireSSL="True" attribute in both forms and cookies sections of the web config, but the session ID cookie is still not sent under SSL. I was wondering if this other attribute was connected with it.
If you've implemented requireSSL="true", your cookies should only be transmitted over the HTTPS protocol. Nothing more should be required for that. The HttpOnly flag tells the browser that the cookie should only be accessed by the server -- not by any client-side script. This prevents certain XSS attacks in modern browsers that respect this flag (should be pretty much all at this point).

HttpServer HttpRequest session creation

Dart HttpServer.listen returns an HttpRequest. There is also a timeout associated with the server which controls how long the HttpRequest remains active. How does the HttpServer identify what has generated the request (for retrieval), and how does it store the requests, and why does it save them?
In the situation that I encountered, accessing the same server from different tabbed pages of the browser used the same server request. If different browsers were used however, it appears that different requests are created. Is it possible to force the server to create different requests for tabbed pages?
I believe that your question mixes requests and sessions. If I misunderstood it, please ignore.
The timeout associated with the HttpServer (I assume you mean HttpServer.sessionTimeout) controls the lifetime of the session, not the request.
The sessions are based on cookies. The server writes session identifier into a cookie. This cookie is then used in communication between browser and server, so server checks the cookie, an gives you the appropriate session to use. This is a typical implementation, some frameworks allow storing the whole session in the cookie, but that has many drawbacks, I won't go into. Dart's HttpSession is just an in-memory map, which is internally mapped to the session cookie value.
Since browser tabs (at least for most of the browsers, I am not an expert on that) share the cookies, request done from any tab to the same domain will result in the same session being used. Naturally, another browser uses its own cookie store, so you have different session there.
This problem is sometimes solved by encoding the session ID in the URL (google for 'URL encoded session IDs' as implementations are specific for the chosen backend), but I don't see any supported way to plug that approach into HttpServer class. The session creation is implemented in _HttpSessionManager type which is private to dart:io library, and doesn't provide any public extension points, so you would most likely need to wrap your own support.

Resources