getting session data when uploading files using fancyupload - ruby-on-rails

I am using fancyupload and paperclip to upload files, everything was working perfectly fine until I added authentication and account validation inside the controller.
I am just using my normal current_user nothing special about that, the rest of the application is dealing with it just fine.
how can I get sesssion data working with fancyupload.
B.T.W I am using activerecord_store in my session_store.rb file.
appreciate you help

The issue here is that Flash requests lack the cookies in their headers. This is true for any uploader that uses Flash (or has Flash as an option, like plupload).
What you need to do in this case, is to tell FancyUpload to append the cookie data to the request with the option appendCookieData set to true and then reconstruct the session in the server based on that (cookie data goes as part of the GET or POST request, not as headers, so most frameworks won't automatically handle this way of authentication).
Do note that using that option appends all your cookies to the request, so if your app is heavy on cookie usage it would be better to extract the cookie you need (MooTools has a built-in Cookie helper) and add it to the request with the data option.

Related

Why Rails change Set-Cookie header every request for the same session

I'm using Rails 4 with cookie based session store, found that Rails 4 will give me a different cookie every time I refresh the page, but it can still identify me.
Compare it to another rack app which uses Rack::Session::Cookie, it will only send Set-Cookie for the first request, until some changes to session data were made.
Why are they designed differently? Is there any reason behind?
It's because of the way Rails handles session storage and cookie encryption:
the default session store will try to write the session data to an encrypted cookie on any request that has accessed the session (either to read from it or write to it),
the encrypted value changes even when the plain text value hasn't,
the encryption happens before it reaches the code that's responsible for checking if a cookie value has changed to avoid redundant Set-Cookie headers.
I go into much more detail in answering this question: Why is rails constantly sending back a Set-Cookie header?
Rails cookie_store default use the EncryptedKeyRotatingCookieJar, and generate the encrypt_and_sign value. That value use MessageEncryptor#_encrypt method, which use the Random 【cipher.random_iv】. So, every time the same value will generate a different encrypt_and_sign result.

Is it Secure to Use Token Authentication and Let Users Execute Custom Javascript Code on Subdomains

I am helping to create a Rails app that uses Ember for a front end MVC. For the app, it is hosting user content accessed via subdomains. On the subdomains, the user can upload custom JS and CSS. What I'm wondering about is if token authentication on the root domain will be safe if stored in Ember from the custom JS people could upload and run on their subdomains?
Provided the following:
Don't use cookies on *.domain.com or use cookies at all.
They can't run (or really display it unescaped in any way) the JS/CSS on your main site.
The ember app with your token doesn't run on their sub-domain (obviously).
They can't put HTML in a file with a different extension or even Content-Type on your subdomain (or you aren't using cookies). They could direct a user's web browser there and it'd display the HTML. Be wary of phishing though (looks like it's your secure content). I can't imagine you could prevent this easily other than not using cookies -- without 100% ensuring properly formatted JS/CSS which would present all kinds of problems.
You can limit cookies to domain.com and www.domain.com, but I don't recommend it (prone to mistakes). If you don't somebody can make a GET request through CSS or ie. an image tag (not to mention JavaScript) and it'll send the authenticated cookies to your server. Remember unescaped input in their app can leave holes too.
If your token is stored in ember, and they have access to custom JS where the app is running of course it'll leave your token vulnerable. If you run your ember app only on the www.domain.com, avoid cookies, storing the token only locally/in JS, you might be okay.
If they just put HTML code in a file with another extension and direct people there it'll be interpreted as HTML.

Angular reuse session after refresh/browser closed

How do you work with Angular.js to reuse a session at a webserver (rails) after browser refresh/restart? I'm using RestAngular but I don't know how to store the session? The angular.js app is in my Rails app as a View (with the assets of course) and I have csrf protection fixed.
I want it to work like a regular webpage, where you don't have to log in each time.
I believe you need to reuse the session objects which is already available in the webserver.
What I would suggest is that, You could use the browser cookie to retrieve the session objects or else you could store a key in the browser DB which you can send to the server via RestAngular and check whether the session is already available.
If the session is already there then you can send the relevant data through RestAngular to the browser.
Hope this might help.

How can I transfer some data between ActionMethods without using TempData or the Db

I have a controller action which returns a password protected zip file to the user when the click a link. The password is generated randomly.
If the download is successful, I'd like to then call another action method on the controller to get the password and display it on the screen. I'd be happy to do it all in one request but it doesn't feel possibly in a non horrible way.
I'm using this library to download the file jquery download library
I can't use tempdata or session state and hitting the database feels a little bit like using a hammer to crack a nut. I've thought about storing it in the response or a cookie but that feels a bit wrong too.
URL or hidden field should do (that is, they are both user-stored either as part of POST or GET request).
The question is, how can you return the password to the client and start the download at the same time. If there's no server storage you can't do it, since they are separate HTTP requests (unless you use cookie). I think this is the best way to do it:
Open your download page, and generate the password at that time,
so you can put it in hidden field (for successCallback of jquery
download library)
When calling your server to download the file,
pass the password as get or post to the download URL, and use this
password to compress
Once download finishes, you know what the
password was, so you can redirect to another page and show it.
Actually, since you already have it on the page, you can show it
right after download using javascript. Or maybe you can just show
the password right away, while download is still happening.
So, this is probably reversal of your architecture. And possibly this is not acceptable (you may want to generate secure passwords and guarantee users don't mess with them - that's possible if you pass the password in the download request). But that's the only way without server or cookie storage.
use
return RedirectToAction("Action", new { id = 99 });

Rails cross-domain requests security concerns

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.

Resources