I have an application a the moment which for a particular set of reasons will be interacting oddly with the hosting server.
The application is to be accessed through a larger portal and can be encapsulated within the portal display, however it makes extensive use of AJAX requests which are not intercepted by the portal. These requests are made directly to the hosting server, however I am seeing a problem.
When the first ajax request is made (a little way into the application flow) the Ajax request is not carrying with it the JSessionId cookie (obviously as it's sending this to a different server than it received it from)
Is there a good grails way to find the session the AJAX call should be interacting with. I have tried setting grails.views.enable.jsessionid to true, but this only works if the browser is not accepting cookies.
Create a hidden form input value that has the jsessionid in it on the page you send back to the portal on the first request. Then read that form variable, and set the cookie in your javascript code that makes the AJAX request.
I'm guessing seeing that this already works, cross-site scripting isn't an issue? AJAX requests to domains other than that which the main page originated from will be blocked by the browser.
The most reliable way will be for you to set up your own "cookie" and pass that along with the requests.
It sounds like you are running into issues due to the portal and it's cookies and then having to continue that "session" onto a different server. Your application needs to simply handle it's own sessions itself in order to prevent getting stomped on by the "normal" cookies.
The idea is essentially to create a session token when the portal makes a request from to your application, and then the subsequent AJAX calls your application makes back to it's own server should include that token. You can then easily associate that token with the session you need to be using.
If you are looking to make it a bit more robust and handle it above the level of your application, you can leverage the fact that Grails is built on Spring MVC deep down and override the default session handler to pick up on whatever mechanism you decide to go with. I'm not sure of exactly how to do this with Grails, but I've done similar things on Spring MVC projects and it isn't too tough once you get your head wrapped around the various injection points of the framework.
It isn't ideal, since there is now a fair bit more complexity, but in theory, the benefits of the portal are outweighing the added complexity required for traditionally "handled" things like sessions and expiring them, etc.
Related
I am running an MVC site along side Umbraco. The MVC site handles its own authentication completely separate to Umbraco, and ASP.NET Forms authentication for that matter. It sets a cookie and uses that internally to keep track of things.
Everything works fine for the most part, but if I am logged into my MVC site with the aforementioned cookie set, I try to login to the Umbraco admin section using the correct Umbraco credentials, it authenticates me and redirects me to the admin section but the WebAPI calls start to fail. The first is a call to: /umbraco/backoffice/UmbracoApi/UpdateCheck/GetCheck which returns a 417 Missing token null HTTP error response.
If I delete my custom cookie and refresh the page everything works fine.
I don't understand how my cookie can interfere with Umbraco's. It's not using ASP.NET Forms authentication or anything.
This error occurs because your request is not sending up the required angular CSRF headers + cookie. I'm not sure why this would be the case but it does seems strange if it is a fault of your custom cookie. Perhaps you can tell us some more information about your issue: Cookie name/value, steps to reproduce, specific version of Umbraco, hosting environment, etc....
Some info as to what is going on, the code that returns this error is here:
https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/src/Umbraco.Web/WebApi/Filters/AngularAntiForgeryHelper.cs#L94
This is where the CSRF cookies are set:
https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/src/Umbraco.Web/WebApi/Filters/SetAngularAntiForgeryTokensAttribute.cs
and this attribute is applied to two actions, one for login and one when we retrieve the current user data:
https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/src/Umbraco.Web/Editors/AuthenticationController.cs#L103
https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/src/Umbraco.Web/Editors/AuthenticationController.cs#L84
This is where the header is set in the JS:
https://github.com/umbraco/Umbraco-CMS/blob/5b9a98ad6ae9e63322c26f7b162204e34f7fcb54/src/Umbraco.Web.UI.Client/src/init.js#L11
Depending on your hosting environment/setup there has been strange reports of some firewalls stripping/changing data, for example:
http://our.umbraco.org/forum/umbraco-7/using-umbraco-7/47340-Umbraco-7-plus-ISA-Server-2006
Hopefully given the info above you might be able to pinpoint where the problem starts.
My initial thought is that you by accident used a key value for your cookie that is reserved by Umbraco, which could result in the wrong cookie being read, causing issues. The solution to this would be to simply rename your cookie.
If this is not the case I have another theory:
HTTP requests will always include all cookies which path/domain matches the domain of the resource you are requesting. They are sorted by path length primarily, and secondarily by creation time. If Umbraco backend for some reason finds the cookie used for authentication by its index number (wouldn't even be surprised) in the list, rather than key value, your custom cookie would cause the index to shift, thus making Umbraco look at the wrong cookie
So, if renaming the cookie didn't do anything, a fun thing to try could be to set path of the cookie to the shortest possible path, which would make your browser put the cookie further down the list, so the index won't shift.
It's just a theory though, so I'm interested in hearing how it goes :)
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.
I have to implement a web site (MVC4/Single Page Application + knockout + Web.API) and I've been reading tons of articles and forums but I still can't figure out about some points in security/authentication and the way to go forward when securing the login page and the Web.API.
The site will run totally under SSL. Once the user logs on the first time, he/she will get an email with a link to confirm the register process. Password and a “salt” value will be stored encrypted in database, with no possibility to get password decrypted back. The API will be used just for this application.
I have some questions that I need to answer before to go any further:
Which method will be the best for my application in terms of security: Basic/ SimpleMembership? Any other possibilities?
The object Principal/IPrincipal is to be used just with Basic Authentication?
As far as I know, if I use SimpleMembership, because of the use of cookies, is this not breaking the RESTful paradigm? So if I build a REST Web.API, shouldn't I avoid to use SimpleMembership?
I was checking ThinkTecture.IdentityModel, with tokens. Is this a type of authentication like Basic, or Forms, or Auth, or it's something that can be added to the other authentication types?
Thank you.
Most likely this question will be closed as too localized. Even then, I will put in a few pointers. This is not an answer, but the comments section would be too small for this.
What method and how you authenticate is totally up to your subsystem. There is no one way that will work the best for everyone. A SPA is no different that any other application. You still will be giving access to certain resources based on authentication. That could be APIs, with a custom Authorization attribute, could be a header value, token based, who knows! Whatever you think is best.
I suggest you read more on this to understand how this works.
Use of cookies in no way states that it breaks REST. You will find ton of articles on this specific item itself. Cookies will be passed with your request, just the way you pass any specific information that the server needs in order for it to give you data. If sending cookies breaks REST, then sending parameters to your API should break REST too!
Now, a very common approach (and by no means the ONE AND ALL approach), is the use of a token based system for SPA. The reason though many, the easiest to explain would be that, your services (Web API or whatever) could be hosted separately and your client is working as CORS client. In which case, you authenticate in whatever form you choose, create a secure token and send it back to the client and every resource that needs an authenticated user, is checked against the token. The token will be sent as part of your header with every request. No token would result in a simple 401 (Unauthorized) or a invalid token could result in a 403 (Forbidden).
No one says an SPA needs to be all static HTML, with data binding, it could as well be your MVC site returning partials being loaded (something I have done in the past). As far as working with just HTML and JS (Durandal specifically), there are ways to secure even the client app. Ultimately, lock down the data from the server and route the client to the login screen the moment you receive a 401/403.
If your concern is more in the terms of XSS or request forging, there are ways to prevent that even with just HTML and JS (though not as easy as dropping anti-forgery token with MVC).
My two cents.
If you do "direct" authentication - meaning you can validate the passwords directly - you can use Basic Authentication.
I wrote about it here:
http://leastprivilege.com/2013/04/22/web-api-security-basic-authentication-with-thinktecture-identitymodel-authenticationhandler/
In addition you can consider using session tokens to get rid of the password on the client:
http://leastprivilege.com/2012/06/19/session-token-support-for-asp-net-web-api/
I am developing a Rails app which relies on a lot of jQuery AJAX requests to the server, in the form of JSONs. The app has no authentication (it is open to the public). The data in these requests is not sensitive in small chunks, but I want to avoid external agents from having access to the data, or automating requests (because of the server load and because of the data itself).
I would ideally like to include some kind of authentication whereby only requests can only be made from javascript in the same domain (i.e. clients on my website), but I don't how or if this can be done. I am also thinking about encrypting the query strings and/or the responses.
Thank you.
What do you mean only your app should request these JSONs? A client will eventually have to trigger an event, otherwise no request will be sent to the server.
Look at the source code of any of your app's pages. You will notice an authenticity token, generated by the protect_from_forgery method in your application controller - from the api:
Turn on request forgery protection. Bear in mind that only non-GET, HTML/JavaScript requests are checked.
By default, this is enabled and included in your application controller.
If you really need to check whether a request comes from your own IP, have a look at this great question.
I want to avoid external agents from having access to the data... because of the server load and because of the data itself.
If you're really concerned about security, this other question details how to implement an API key: What's the point of a javascript API key when it can be seen to anyone viewing the js code
You shouldn't solve problems you don't have yet, server load shouldn't be a concern until it actually is a problem. Why don't you monitor server traffic and implement this feature if you notice too much load from other agents?
I ended up passing token=$('meta[name=csrf-token]').attr("content")in the request URL and comparing with session[:_csrf_token] in the controller.
def check_api
redirect_to root_url, :alert => 'effoff' unless request.host =~ /yourdomain.com/
end
that should work to check your domain. Not sure you need the js part, but it's something.
My understanding of the session lifecycle in Ruby on Rails (specifically v3 and upwards) is that a session is created at the start of a request, for each and every request, and if that request doesn't carry an existing session cookie a new one will be created, otherwise the session cookie is deserialized and stored in the session hash.
The purpose of this, of course, supports a number of security features such as CSRF etc.
However, this poses a bit of an issue when it comes to caching of pages in a site with HTTP cache services and proxies such as Varnish, as most of the configurations tend to strip out these (generally all) cookies on both the request and response end (as the cache is usually intended for a generalized audience).
I know that it is possible to setup Varnish etc to create the object hash with the cookie details included, and this would scope the cached data to that session (and therefor that user), however I am wondering if this is completely necessary.
I have an application which is fairly 'static' in nature - content is pulled from a database, rendered into a page which can then be cached - there are a few elements (such as comment count, 'recent' items etc) which can be added in with an ESI, but for every request Rails still tends to want to setup a new session, and when a user already has a session this stuff is stripped out by the cache server.
I am wondering if it might be possible (via pre-existing functionality, or building the functionality myself) to allow the developer to control when a session is required, and only when that is specified is the back-and-forwards with cookies, session initialization/deserialization etc necessary.
That, or I am thinking about this problem the wrong way and need to address the issue from another angle...
From what I know rails sessions can be controlled fairly in-depth via ActionController::SessionManagement
http://ap.rubyonrails.org/classes/ActionController/SessionManagement/ClassMethods.html#M000070
There are examples in the API docs of disabling it per action, per controller, etc.
If your site is mostly static then you may want to use full page caching. This takes Rails out of the request entirely and let's the web server deal with it once the content has been generated. Might cause some serious headaches depending on your exact needs as far as the comment counts and user-specifics though.