flash scope issues in grails when cookies are disabled - grails

In my application I want to have some dynamic content available to search engine bots which have cookies disabled. But I am stuck because I need to pass redirect URL via flash scope to redirect to different action and controller. When I use chain
instead of redirect then I am able to get flash scope data but I have some use cases in which I cannot use chain and have to use redirect this is also because chain (uri: '/') does not work correctly as this will redirect to index action of current controller and not to the controller that is defined for root '/'. The issue is that flash scope loses everything when cookies are disabled and doing redirect instead of chain. Is this a bug in grails or know limitation in grails?
When cookies are disabled I still see URL being rewritten with ;jessionid=some_value but according to documentation by default
url would not be rewritten with jessionid. When cookies are enabled then url is not rewritten as expected. Is this a bug in grails or expected behavior? How do I disable URL rewriting in grails when cookies disabled?
I also understand that the implication of disabling cookies and URL rewriting is that each request would result in new session object creation.

Not sure if it is the solution you are looking for, but have you tried Marc Palmer's One-Time Data plugin?

Related

Why should spring postOnly be false for Logout to work?

what does postOnly mean in below property
grails.plugin.springsecurity.logout.postOnly=false?
Why should it be false for Logout to work? Tried making the logout feature work by making it true. But it did not work. What is the reason behind making it false?
For starters, please read the plugin documentation - the 2.x docs are here and the 3.x docs are here.
The plugin defaults to requiring a POST request to logout, but using the config setting you reference you can make your application more convenient to use but less secure by allowing GET or POST requests.
GET requests (e.g. regular links) are supposed to be for actions that read data. A strict REST API requires that GET requests be read-only and also idempotent, but obviously in a regular web app this is too strict. But in general it's best to use links and GET requests to request information, and POST/PUT/DELETE/etc. requests to make changes.
If you include a logout link that uses GET to make the request, it's possible for someone using XSS or similar attacks to trick your browser into logging you out. This isn't a severe vulnerability and requiring POST doesn't make it significantly harder for an attacker but it does raise the bar.
With the default configuration all you need to do is replace a logout link with a simple form that POSTs to that same url (and you can optionally use CSS to style the submit button like a link if you want). If you're comfortable with allowing users to logout with a GET request, change the setting to false and any request to that url will work.
Once you make it true as below
grails.plugin.springsecurity.logout.postOnly=true
the request method type should be POST only i.e. you can't use GET method.
So, change the logout call to POST type in this case.
You may also look at How to customize Grails Spring Security Core 2 login / logout controller and views?
By default Spring Security requires logout to use a POST request to provide CSRF protection. For more on CSRF see Wikipedia.
what does postOnly mean in below property
I means you grails will only logout a user if you send a POST request to the logout url.
Why should it be false for Logout to work?
It's mainly for CSRF protection.
It is considered best practice to use an HTTP POST on any action that
changes state (i.e. log out) to protect against CSRF attacks. If you
really want to use an HTTP GET, you can use logoutRequestMatcher(new
AntPathRequestMatcher(logoutUrl, "GET"));
Additionally, modern browsers like chrome will preload links in a page before the user tries to access them to make them fast. This means if you make your logout link accept GET requests, chrome might log you out even if you don't want to.

Does RedirectToAction pose a security risk?

I have an HTTPS post coming in via a secure form. Without going into lengthy explanation: I need to call an action within the same controller that accepts two tokens passed as parameters. When I run Fiddler, I see that that method is being called with the parameters in the URL. My question is: Does this pose a security risk? Is there a more secure way of redirecting within the same controller?
Yes, it poses a security risk, but it is easily mitigated by simply validating that the urls you are redirecting to are within the same domain as your source destination.
In fact, this is on the OWASP top 10.
A10 - Unvalidated Redirects and Forwards
EDIT:
I just realized that I missed the "ToAction" part of the question, so no.. It's not really possible to redirect outside of the site with RedirectToAction, so there isn't a worry for that. However, if you are using direct user input to feed into your RedirectToAction (and that includes accepting post data that you generate in a different page) then it's possible that an attacker could redirect to a method you did not anticipate. However, this is no different from a user simply trying random URL's and hitting one, or knowing a url and going to it manually. You need to have authorization in place to prevent access to URL's that the user does not have authorization to view.
If the original Action is accessed via HTTPS then RedirectToAction will redirect to a relative URL on the same domain using the same protocol.
So if your original page is
https://www.example.com/Foo/Bar
and this redirects to the FooBar action with some route parameters:
https://www.example.com/Foo/FooBar/1/2/3
an attacker cannot read the parameters 1/2/3 nor the rest of the URL.
However, the things you should bear in mind are:
The URL parameters will be logged by default by the browser (history), your server, by corporate proxy servers and possibly by other devices on your network by default.
If the user follows any links from your page to other https URLs, the referer HTTP header will contain your page address including parameters. Modern browsers will not send the referer header with http links though.
If there are any other https resources on your page this will cause the browser to send the referer header with the request.
For these reasons, if your parameters (1/2/3) are private, then you may wish to POST this data to the target page rather than use RedirectToAction (which results in a GET).
Note that you should be validating that the current user has access to the resources that 1/2/3 refers to (e.g. if the parameters were an order ID, you should check that the user identified by their auth cookies allow them to see the order referenced). Keeping 1/2/3 private are only beneficial if the parameters are themselves sensitive (e.g. a social security number).
Note that the OWASP Top 10 vulnerability, "A10 - Unvalidated Redirects and Forwards" does not apply here as RedirectToAction can only redirect to another action. If the other action redirects to a user set URL, then the vulnerability would lie there instead.

Umbraco 7 custom cookies

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 :)

PrettyFaces redirect to RESTful url after login

I'm using PrettyFaces 3.3.3. I have a requirement that if a user tries to view a page, but is not logged in, they are sent to the login page, and then redirected to the original page they wanted to view. Just wondering what would be the best approach for this.
You probably want a security framework here. The basic idea is that you'd want to intercept the requested URL in your security filter, save it into the user's session, then once authentication is complete (e.g. user has submitted the form with their credentials, or whatever mechanism you're using) you retrieve the saved URL from the user's session and perform a 302 Redirect to it.
This is not something PrettyFaces will help you with directly, except that you can use it to capture the URL more easily using PrettyContext.getCurrentInstance(request).getRequestURL();
There is an article about this here: http://ocpsoft.org/java/jsf-java/spring-security-what-happens-after-you-log-in/
Using OCPsoft Rewrite (core of PrettyFaces 4) you can do this programatically as well, and even do the authentication directly in your security rules or annotation config: https://github.com/ocpsoft/prettyfaces/blob/master/annotations/src/test/java/org/ocpsoft/prettyfaces/annotation/jaas/JaasRolesBean.java
This is an upcoming feature but is not yet complete - we would love feedback.

ASP MVC 3 RequireHttps attribute change all links to https

I have an ASP MVC 3 website that has a Feedback form and should require SSL.
Now, I have an action called Feedback inside a controller called 'ContactUs' that is responsible for viewing and processing the feedback.
When I used the [RequireHttps] attribute on that action, it works nice and it changes the URL to "https". However, I noticed that all the links inside my page are now pointing to "https"! As if this attribute had forced the routing engine to apply the same to all links!!!
Of course, the SSL is only required for this single action and all the rest need to have normal http.
Could anyone tell me how to solve this?
In your case [RequireHttp] attribute might be OK if you clear out the login cookie - or you'll be sending it in clear-text across the wire. It might be more work than it's worth to avoid the slight cost of further HTTPS calls. SO is all about recycling questions and other users reading your question might think it's OK to drop down to HTTP after login, when it's usually the wrong thing to do.
The [RequireHttps] attribute can be used on a controller type or action method to say "this can be accessed only via SSL." Non-SSL requests to the controller or action will be redirected to the SSL version (if an HTTP GET) or rejected (if an HTTP POST). You can override the RequireHttpsAttribute and change this behavior if you wish. There's no [RequireHttp] attribute built-in that does the opposite, but you could easily make your own if you desired.
There are also overloads of Html.ActionLink() which take a protocol parameter; you can explicitly specify "http" or "https" as the protocol. Here's the MSDN documentation on one such overload. If you don't specify a protocol or if you call an overload which doesn't have a protocol parameter, it's assumed you wanted the link to have the same protocol as the current request.
The reason we don't have a [RequireHttp] attribute in MVC is that there’s not really much benefit to it. It’s not as interesting as [RequireHttps], and it encourages users to do the wrong thing. For example, many web sites log in via SSL and redirect back to HTTP after you’re logged in, which is absolutely the wrong thing to do. Your login cookie is just as secret as your username + password, and now you’re sending it in clear-text across the wire. Besides, you’ve already taken the time to perform the handshake and secure the channel (which is the bulk of what makes HTTPS slower than HTTP) before the MVC pipeline is run, so [RequireHttp] won’t make the current request or future requests much faster.
You can create another custom filter attribute to move back to http. Try solution from this question...
Why once SSL is enabled with [RequireHttps] at action level, it remains enabled forever?

Resources