Why would CSRF errors appear overnight in a Rails app? - ruby-on-rails

I know what CSRF protection is, I know how it works in the context of a Rails app, and I know how to "solve" my problem, e.g., by disabling it.
However, I'd like to keep CSRF protection turned on. My question is, what would cause the error:
Can't verify CSRF token authenticity
To appear overnight? Nothing has been pushed to production (i.e., not a code issue, and FYI I'm not using Devise). Still using the same browser (Chrome on desktop) which has not been updated. Using the same form (a template that every user uses). Literally yesterday it was all working fine, and today it suddenly isn't.

Only guessing possible here I guess.
Precondition: There is no bug ;-) Guess: A real CSRF attack is going on.
Precondition: Not yet checked twice. Guess: Something had been modified on production. Maybe it was not even pushed, but directly changed.
Precondition: Production site is not heavily used. Guess: It was broken since longer than the night before. Nobody noticed, since all they did was logging in and triggering some 'GET' requests, and not the template form.
"csrf-token" or "csrf_token"? Sometimes GET and POST requests modify the variable name. Especially if you disable Javascript and the original post becomes a get. Of course that would be a different route, but still might throw the csrf error.

Related

Missing ASP.Net cookies from iOS

I'm experiencing some trouble with an ASP.NET MVC 5 application that has been buggering me for a few days.
The application is using Forms Authentication to control whether a user is Authenticated, and Session to keep track of the user's data.
A few of our users are unable to log in, and I have been able to recreate the problem on a collegue's device. We don't know much about the devices with the problems, except that they all seem to be running iOS. I can't seem to nail down the pattern, though, as one user who reported the problem was running 11.2.5, which I am also running myself without trouble. The collegue's device is running 11.3 beta, but I haven't yet heard of any other users with this version, so I'm unable to pin point that as the problem - which also seems unlikely when one of the users with the problem is running 11.2.5.
The issue happens after the users try logging in. After a successful login, the user is redirected to a specific section of the site, where Authentication is required. Requesting any page in this section redirects you to the login page if you are not Authenticated.
Some of the resources that are requested on this page expect to retrieve some data from Session. For some reason, the Session cookie may sometimes be missing, and other times the Authorization cookie is missing.
For the past few days while I have been hunting this, my collegue's device happened to leave out the Session cookie when requesting our Cachemanifest, in which we expect to be able to generate a specific part based on some data from the Session. This caused the generation to fail, which in turn caused the request to fail.
After changing the generation logic to work around this, with a different solution if the Session cookie is missing, my collegue's device has changed its approach; Now, it includes the Session cookie when requesting this resource, but instead leaves out the Authorization cookie in a subsequent request to a different resource, which is still in the section that requires Authorization. This resource happens to be mentioned in the Cachemanifest, and because this next request does not include the Authorizaiton cookie, that request is redirected to the login page, which is interpreted by the Cachemanifest as an error.
As far as I recall, I haven't changed anything else, so I'm really at a loss as to why this devices' behaviour has changed.
Both of these cookies are included in other requests before and after the failing request, and there doesn't seem to be a pattern between what requests is chooses to leave these two cookies out of, or which cookies to leave out. The only thing that is consistent is that the behaviour doesn't change when retrying after clearing the browser data (only after I made my change, which I still don't see how could result in this behaviour).
The site is forcing HTTPS, so I tried setting the Session cookie to Secure, but that didn't seem to make a difference.
I still need to try setting the Authorization cookie to Secure, but I'm not very optimistic there. I also still need to try reverting my changes to see if the old behaviour reappears.
Has anybody experienced similar problems before, or does anybody have any further suggestions? I know I might be a bit sparse on the details, I'd be happy to provide any further details if I'm able.
Thank you in advance :)

Weird issue with CSRF token on custom post action

For a couple of months now I've been using an action called update_snapshot in my controller.
Essentially this action tells the server to connect to a webcam and capture/save a jpeg from it that someone uses to visually review a remote location is fully operating as expected.
But anyhow...
Today I started seeing WARNING: Can't verify CSRF token authenticity in my logs and the user get's logged out
Now I understand that you need to send a CSRF token with a request, but the issue here is that I am.
This is definitely a brand new issue that happened today and I'm not sure why it's suddenly an issue.
In order to resolve the issue for now I am skipping the before_filter for :verify_authenticity_token for this action (and only this action).
I think I can keep it like this without any real issue, but any idea as to why it would suddenly start happening, and why only on this action?
Figured out the issue here.
I'd somewhat recently added action caching for my show action.
The link that does the post is in this cached view.
The CSRF meta-tag needs to be updated by making a separate ajax request to another, uncached controller that just serves this tag.

Authentication loss with IE8 and MVC FileContentResult

ASP.NET MVC2
.NET 3.5
FormsAuthentication
URL: domain.com/myapp
Problem area: Dynamically created PDFs returned as FileContentResult
Everything was working fine until IE8. With IE8, when the user opens a PDF and then returns to the app, he has lost his authentication. I added an expiry on the forms auth cookie and the problem appeared to be resolved. However, I later discovered that the same problem occurs in the parent app. With the persistent cookie, when the user continues in my app (domain.com/myapp), everything is fine, but when he returns to the parent app (domain.com) window he has lost his authentication. The parent app uses a proprietary authentication and authorization architecture that relies on session state.
So my understanding of the problem is that the FileSystemResult does not carry any session information and thus the session is lost. I understand that by adding an expiration to the cookie, the cookie is persisted and that enables the authorization to persist in my app, even when docs were opened.
I don't quite understand why adding an expiry to my cookie transferred the problem to the parent app. So, I was wrong, this has been happening all along in the parent. Interestingly, when I hooked up Fiddler to watch what was going on, the problem went away.
Do you have suggestions to resolve this? I can't think of anything other than something really ugly like writing the file to the server and returning a page with a link to open the file directly.
Based on this question I think I am hosed.
There's some changes to the way IE8 handles persistance cookies which could be the route of your problems. There's an interesting post here that describes a possible solution.
The solution took us quite a while to find online believe it or not,
and when we found it we wanted to kick ourselves for not finding it
sooner. It all stems from the domain attribute of the forms
authentication settings within the web.config file of your
application. We typically left that attribute blank in our apps to
make it easier to develop. Further, none of the other browsers above
cared about that setting and functioned just fine. However, that
changed in IE8 and now that attribute is required.

Rails - Session not saving

I have a session that is set but it does not appear to carry over to other pages. I'm on Rails 2.3.5 and Ruby 1.8.7. Has anyone else experienced this issue?
I've had this issue in Rails 3.1 when CSRF verification fails. This can happen if you use a tag manually rather than generate it via one of the built-in methods provided by Rails.
Search your log file for "csrf" (case insensitive search). If you see a log entry showing a csrf failure, it's likely Rails is resetting your session.
You may be losing your session between requests which can happen if it's not established properly in the first place. If you examine your cookies you may see the session identifier changing, being re-assigned, because of a validation failure.
It's also possible that it's being assigned to a domain that the browser subsequently rejects. This happens if an application is configured to use a specific domain, and is then re-hosted under a different one, even localhost.
You might have not used csrf meta tag in your layout. Try removing ' protect from forgery ' in application_controller.rb in controllers folder. Then try running the app again, if it works then you didn't add tags to your layout.

Cookies being preserved despite app telling them to expire

While the problem happens almost always to users in Internet Explorer, it has happened in Firefox and Chrome a few times as well.
The issue is in which users attempt to login and either get a 422 error or are simply re-directed back to the login screen. We have a wildcard cookie, but we recently switched it to targeting www (about 3 months ago) and the previous cookie was set to expire at the end of the session.
We also recently switched to Devise authentication from Restful_athentication in hopes that it would fix the issue, but it doesn't seem to be helping. However, I don't see how these are related as they don't really manage the cookies, Rails does, they just put things in the cookies. I thought maybe the issue was that restful-auth was putting something in that got corrupt under weird conditions, but that apparently was not the case at all
UPDATE
After we switched to Devise, users encountering this problem no longer got a 422 error, but now the page just refreshes and nothing happens. I should also mention that when they enter in their email to retrieve their password (as they think they're entering their password in wrong), it returns that the email is not found in the system.
When they clear their cookies, particularly in IE, they still run into the same problem. I've walked a few users through searching for the individual cookies in Firefox and that has solved the problem. However, simply just going to clear cookies the normal way didn't work. The issue was mainly effecting IE7 users, but seems to be all across the map, with users reporting the issue on Chrome, IE8, Firefox, Safari and Safari for the Ipad.
Also, here's a link to the code for the session_store.rb here and here the host is set in def ensure_domain, which is here
UPDATE 2
I just made a very minor adjustment and it changed it so it always sends a host. I tried logging in every different way on every browser and didn't run into any issues. I'm hoping this helps
UPDATE 3 (LAST UPDATE)
We tried a combination of a few different things, so while I'm not exactly sure what fixed it, my best guess is removing the cache from 4 days to when the session ends/browser closes. While I'm not thrilled about this as I personally dislike having to login every time, I'd rather have the problem fixed (and this issue didn't start occurring until after we changed the cache length to 4 days.)
Sending a host was a mistake and actually made the problem worse for everyone as no one was able to login. Another strange thing was that when looking at the cookies created there were two Session ID cookies, which I would guess were causing the conflict, particularly with IE7. Some users are having to clear their cookies to get logged in still, but at least that seems to be working most of the time.
To any having a similar issue, sorry I couldn't be of more help!
If an HTTPS cookie is set to "secure", it WILL NOT be sent out on HTTP protocal. It is as if it doesn't exist. This sounds like what is likely "stripping out" your cookie.
Cookie basics: If something is worth protecting via HTTPS and you need to track that info afterward (ie, authentication token), it is best to keep it in the HTTPS cookie and only access it from HTTPS.
This is a cookie security issue, and is better discussed at: Secure cookies and mixed https/http site usage

Resources