Getiing 403 forbidden in Hybris when adding to cart from carousel - spring-security

In Hybris, I am getting a 403 forbidden error in browser console while trying to add a carousel product to the cart, it is happening sometimes and only in the homesite, the rest of the page is working fine. I think it is related with the configuration of the CSRF token but I don't know how to fix it, any clue? Thanks!
Edit: When checking page source code, the hidden CSFR Token attribute is different from the current, maybe because the session is expiring but even after reloading the page and creating a new session, the value is still wrong. How can I ask for the valid token before every call?

You can check your spring-security-config.xml for csrf or configure "csrf.allowed.url.patterns" parameter in your properties file.

Related

How is it possible for a legitimate user to submit an invalid CSRF token in Rails?

Our error logs occasionally contain legitimate form submissions that cause ActionController::InvalidAuthenticityToken errors.
My hypothesis is that the CSRF token stored in the user's session cookie has changed at some point after the form was loaded but before it was submitted. This causes a mismatch between the POSTed token and the token in the cookie, leading to this error.
Given that a Rails session cookie expires only when the browsing session ends (ie when the web browser is closed), what are the ways in which this cookie (and the CSRF token it includes) can be changed without closing the browser?
We are using cookies to store session data, which is Rails' default behaviour.
The user could have logged out and back in, but had a tab with a form open from the old session. That would send the old token.
Here's what we know:
Legitimate form submissions that cause an InvalidAuthenticityToken exception have somehow lost their original CSRF token.
The token is kept in the session, which is kept in an encrypted cookie. So this error means their session cookie has changed since the form was generated.
The session cookie does not expire unless the user's browser window is closed.
I now believe there are two ways that invalid CSRF tokens can be submitted by legitimate users.
Note that these apply specifically to Rails 4.2. As I understand it, the "per-form CSRF tokens" feature in Rails 5 may mitigate them.
1. Session change in another tab
As per #crazymykl's answer, the user could open the form, then log out in another tab. This would cause the session cookie stored in the user's browser to change. When they came back to the original tab and submitted the form, the token from the form would not match the token in the session, and the error would pop.
2. Caching
As per this rails bug, Safari behaves oddly with caching under some circumstances. Telling it to reopen with the same windows as last time (via Safari > Preferences > General), opening the form and quitting Safari results in the form being redisplayed.
Submitting that cached form causes a CSRF error. As the opener of the bug concludes, it appears that Safari caches the page, but drops the session cookie. Hence the mismatch.
The solution to this problem is to set a Cache-Control header with the directive no-store. (Difference between no-cache and no-store explained here).
Further examples welcome :).
Are you using Ajax form to submit the request? Does your page has multiple forms? If so, check your code whether correct csrf token is submitted along with the request. We had similar issue that page is rendered with one csrf token and we used this token to submit form one and we would have got another csrf token but the second was sending old csrf token that result in error.
I am not sure how this is helpful but want to share similar problem faced by me
You wrote: Given that a Rails session cookie expires only when the browsing session ends (ie when the web browser is closed), what are the ways in which this cookie (and the CSRF token it includes) can be changed without closing the browser?
First off, your hypothesis is valid. How you got there might be worth considering, though.
The presumption you present needs focus on two levels.
One: a cookie stored does not get deleted when the web browsing session ends unless something has been coded that way; the cookie is likely persistent until he cookie timeout, so it's likely that the next access of the page will use the old token, but because developers generally allow the "new login" to refresh the page, they are likely to also refresh the token at that time. See #Shikhar-Mann response to better understand the sign_out_user.
Two: the cookie doesn't have to be changed for this problem, it's the mismatch of the CSRF token that is the issue.
So the root question should be: what are the ways that we can have a mismatched CSRF token, which would be easier to answer: old data on client due to a long wait, which causes a timeout on the server, which invalidates the CSRF token during the delay. If the web page is not configured/created to also time out and redirect, the client / user would never know.
Also, might I suggest that the CSRF NOT be persisted? It's really not valuable to do so if you can access form data; typically I create a hidden field with the CSRF data and use that to post back instead. CSRF doesn't live very long, and session data is made to persist.
If closing browser is not an option. Then you got to log out the user. To achieve that place the following code in ApplicationController.
rescue_from ActionController::InvalidAuthenticityToken do |exception|
sign_out_user # Example method that will destroy the user cookies
end
P.S: Above is from http://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf so refer that for more information.

Random "The anti-forgery cookie token and form field token do not match" in Azure

We are getting random "The anti-forgery cookie token and form field token do not match" errors showing up in the error log in with our site hosted in Azure. After realizing that we needed a static machine key, we added to that to the web.config with the validationKey and decryptionKey attributes, however, we still have the random error popping up.
Just to define my use of "random" here, out of every ~200-300 form submissions, this happens once or twice. It just feels like too much to have happen and it's a real interruption to our clients that trust our services.
One other thought that crossed my mind is whether this is happening on machines that don't have cookies enabled. I haven't been able to verify that one way or another, but I didn't know if cookies are a requirement for the ValidateAntiForgeryToken to work. If it does require cookies, then should we pop up a message to our users letting them know that cookies are required for proper use?
I could use help coming up with ways to diagnose this or other ideas of how to handle this.
Thank you in advance.
[UPDATE] I just heard from a user where I saw this error popup. It turns out that they loaded the page and walked away for a while causing the error. That's great news since that means that the validation is just doing its job and nothing crazy was happening...I just need to verify if that data point is indicative of the rest of the users. So given that, how do you all handle situations where the token expires? Do you notify the user in some clean way?
Do you have a server farm ? i.e. do you have an App Service with auto-scaling enabled ? or a cloud service with several machines ?
If yes, check that all your machinekeys are defined with the same value in all your web.config files. The machinekey is used to generate AntiForgery tokens.
Could you log the headers of the failed requests ? You can add some code in your global.asax on Application_Error like :
foreach (string header in request.Headers)
{
// header <== header name
// request.Headers[header]) <== header value
}

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

Session Struts2 SSL

I have created a Login Application with struts 2 and integrated with SSL. When I click on the back button after logging out, I am still able to see the page though it shows session expired when I try to perform any action on the page. But, when I refresh the page, I am able to perform all the actions on the page. I have removed the cookies using an Interceptor on the event of LogOut. Can anyone help me out.
This is not much information that you give us here.
I think the problem might stem from the URL of the page that you are refreshing. Please take a look at that and what action that URLs gets called, and all the GET and POST data that is appended when reloading the page. You might want to use a debugger for this. Maybe this information regenerates the cookie or the logged-in information in the session.
You can use the SessionAware interceptor to store data based on the uses's session. If you don't find the error, you can put a boolean loggedIn flag into the session, check at the beginning of your actions if the user is really logged in, and set the value to false when the user logs out.

How to handle pages with stale CSRF authenticity tokens in Rails

In our Rails application, it is common for users to keep multiple browser tabs open for hours or days at a time. The problem occurs when in one of these tabs, the user logs out then logs back in (or the session expires and a new session is created).
This causes the CSRF authenticity tokens on all the other tabs to become invalid. If they try to submit any form or make any ajax request on those tabs without refreshing, they will get an error (and in fact get logged out because that is the default Rails behavior when a bad authenticity token is passed).
This behavior is clearly undesirable. I was wondering what people do to gracefully handle situations where a user has a window open to your site but the authenticity token is out of date.
What I don't want to do is just redirect them to the login page, because then they might lose their work, if for example they have been writng a long blog post or something.
The solution that comes to mind is to have some javascript that either polls the server to check whether the authenticity token has changed, or polls the user's cookies to check whether the session has changed. I have never heard of anyone doing either of these, so I wanted to see what the community thought.
First of: logging in/out/in won't lead to appearing a new csrf-token. It still will be saved in the user's cookie. Next time it logs in via the same browser it'll get the same token.
In latest versions of Rails no errors will be thrown in the case of incorrect token: all the Rails does -- just resets the session before passing it to a controller.
So, update your Rails and you'll get one pain less.
Are you sure you are talking about CSRF token and not session token? It does not make any sense at all to redirect to login on a CSRF token mismatch. You just tell the user to repeat whatever he tried to do. (In a traditional web application this typically comes up when a form is submitted; you can treat the CSRF mismatch as a validation error, and show the form again, keeping all the field values, and ask the user to resubmit. In a more AJAX-heavy application you can use some sort of generic CSRF flag in the response, and if it is set, ask the user to do whatever he did (press the button etc) once more, or even automate the whole thing without bothering the user.

Resources