Reputation: 5279
I have a rails app that makes web api call , the rails app by itself doesn't have any database or userstore. Every api call needs to be sent username and password for each request.
I would like to provide an authentication mechanism for the rails app. I am planning to do it this way :
Now my problem is where do I store the password ?
If I use session I cannot use cookie store obviously , I can use session_store = :active_record_store
but not sure if its safe , also I don't have any database as of now so why should I create one just for session ?
Is there any other mechanism to store passwords within a session ? (safe way obviously )
Earlier rails had :
But now both seems to be removed. So any other solution ?
Notes from answers :
I finally thought to implement custom memory store but it seems to throw stackoverflow error. I got the code from https://rails.lighthouseapp.com/projects/8994/tickets/1876-uninitialized-constant-actioncontrollersessionmemorystore
require 'action_dispatch'
module ActionDispatch
module Session
class CustomMemoryStore < ActionDispatch::Session::AbstractStore
GLOBAL_HASH_TABLE = {} #:nodoc:
private
def get_session(env, sid)
sid ||= generate_sid
session = GLOBAL_HASH_TABLE[sid] || {}
session = AbstractStore::SessionHash.new(self, env).merge(session)
[sid, session]
end
def set_session(env, sid, session_data)
GLOBAL_HASH_TABLE[sid] = session_data
return true
end
end
end
end
Steptools3::Application.config.session_store :custom_memory_store, :key => '_some_xyz'
Upvotes: 6
Views: 3007
Reputation: 4875
I will try to analysis your choices:
If Server is hacked with CustomMemoryStore
Consider the following scenario:
With CustomMemoryStore, the hacker can get passwords of all users. It’s not too hard to inject some logic into running Rails process, or dump the memory and analysis. Storing password in ActiveRecord, MongoDB, Redis has similar problem.
If Server is hacked with CookieStore?
What if the previous scenario occurs and you are using CookieStore?
Let’s review the mechanism of CookieStore:
In other words, hacker cannot get the password from the cookie or from the secret key. He needs both cookie and secret key to stole the password.
In this scenario, the passwords of A, B, C are safe. Only D’s password will be stolen by Hacker. You can minimize the damage by repairing the system ASAP.
The Problem of CustomMemoryStore
Besides the security problem, I know you are aware of that CustomMemoryStore is not scalable. However, the problem might be bigger than you think. You will send request to other web services in your controller action, it will block your entire server if the remote service is slow or down. It might be painful even if you have only concurrent 1~10 users.
Even if you decide to run your application on single server, you can start multiple rails process with Passenger or Unicorn. CustomMemoryStore denies these options.
Client Security Concern
If the concern is if cookie is stolen from browser side, you can consider EncryptedCookieStore. It encrypts the session and store in the client cookie. You cannot get password if you have only cookie or the key. You need both cookie and the key to decrypt the password.
What’s the key problem?
EncryptedCookieStore is more secure because it stores encrypted password in user’s cookie, and the secret key is only available on the server. The hacker cannot get password if he only have the cookie or the secret key -- He needs both.
Of course, you can implement similar logic with CustomMemoryStore. For example, store encrypted password in server memory and the individual key is in the cookie. If you still decide to store encrypted password on the server, I will recommend to use Redis for storage. It's simple and fast compared to MySQL and MongoDB. CustomMemoryStore is not suggested because of scaling issue.
Other suggestions
Password of other system is very sensitive data, you should be very careful to deal with security problem. If it’s a public service, you should write your Term of Service and Disclaimer agreement very carefully. Besides, you should run your services with HTTPS.
TL;DR
Upvotes: 1
Reputation: 50057
You could try using Redis as a session store. We use rails3-redis-session-store
gem. The source can be found here.
It is very easy to setup, and sessions expire automatically, which makes it safe. Example config:
YourApp::Application.config.session_store :redis_session_store,
:db => 0,
:expire_after => 10.minutes,
:key_prefix => "your_app:session:"
An alternative would be to use dalli, and thus use memcached as the backend.
Hope this helps.
Upvotes: 2
Reputation: 64363
The session cookies are encrypted using the session key. Your data should be secure as long as you keep your session key strong (128 char) and safe.
ActionController::Base.session = {
:key => '_foo_bar_session',
:http_only => true,
:secret => 'dldkdke420934indsknknkfsnh318u84e9u49832dfkdsajdsk'
}
If you want to store the authentication details beyond a browser session then you can store them in signed, permanent cookies.
cookies.permanent.signed[:user_credentials] = [login, password]
The signed cookies are accessed like regular cookies:
cookies[:user_credentials]
Make sure you set a strong cookie_verifier_secret in your initializer file.
ActionController::Base.cookie_verifier_secret ='dskjkjfdshfddsfkhkr3898398430943'
Reference
Signed and Permanent cookies in Rails 3
Upvotes: 1
Reputation: 1462
I would recommend taking the next step and setting up a simple database and save a lot of hassle for yourself and the user, what happens when the user wants to return to the site, they will have to re-register.
I find Devise is awesome for this purpose and very simple to integrate.
If there is an issue where you don't want to have a classic database server running you may want to look at MongoDB
Upvotes: 1