Session Password Rails

I have a rails application that makes a web api call, the rails application itself does not have a database or user store. For each api request, you must send a username and password for each request.

I would like to provide an authentication mechanism for the rails application. I plan to do it as follows:

  • Show login page
  • Get username and password
  • Save username and password
  • Perform manual authentication either through warden.authenticate or authlogic.something (or maybe itโ€™s not even necessary, you can just check if the session has something saved)
  • And then, when the user does something, I pass in the username and password that were saved earlier.

Now my problem is where can I save the password? If I use a session, I cannot use the cookie store, obviously I can use session_store = :active_record_store , but Iโ€™m not sure that it is safe, I also donโ€™t have a database, so why should I create it only for the session? Is there any other mechanism for storing passwords in a session? (obviously a safe way)

Rails used to have:

  • Memory store
  • Filestore

But now both seem to be deleted. So, any other solution?

Notes from the answers:

  • Storing encrypted passwords will not work, since I need a raw password to send to the server when making api calls.
  • I have no control over the API, so I canโ€™t change its authentication.
  • Rails does not support user profile support. Everything is controlled by API calls.

I finally decided to implement a custom memory store, but it seems to throw a stackoverflow error. I got the code 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' 
+6
source share
4 answers

You can try using Redis as a session repository. We use the rails3-redis-session-store . The source can be found here .

It is very easy to set up and sessions expire automatically, making it safe. Config example:

 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 a backend.

Hope this helps.

+2
source

I would recommend taking the next step and creating a simple database and saving a lot of trouble 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 to be awesome for this purpose and very easy to integrate.

If there is a problem when you do not want to run the classic database server, you can look at MongoDB

+1
source

Session cookies are encrypted using the session key. Your data should be protected as long as you keep the session key strong (128 char) and secure.

 ActionController::Base.session = { :key => '_foo_bar_session', :http_only => true, :secret => 'dldkdke420934indsknknkfsnh318u84e9u49832dfkdsajdsk' } 

If you want to save the authentication information behind a browser session, you can save it in signed, persistent cookies.

 cookies.permanent.signed[:user_credentials] = [login, password] 

Signed cookies are accessed like regular cookies:

 cookies[:user_credentials] 

Make sure you set a strong cookie_verifier_secret in the initialization file.

 ActionController::Base.cookie_verifier_secret ='dskjkjfdshfddsfkhkr3898398430943' 

Link

Signed and persistent cookies in Rails 3

+1
source

I will try to analyze your options:

If the server is hacked using CustomMemoryStore

Consider the following scenario:

  • 4 Users A, B, C, D are logged in.
  • Your server is hacked. Hacker takes control of the server.
  • D did some surgery.
  • You have discovered that your server has been hacked and restored your system.

Using CustomMemoryStore, a hacker can receive passwords for all users. Its not too difficult to introduce some logic into the Rails process, or dump memory and analysis. Saving a password in ActiveRecord, MongoDB, Redis has a similar problem.

If the server is hacked CookieStore?

What if the previous script occurs and you use CookieStore?

Let's look at the cookiestore mechanism:

  • The server has a secret key for signing and verifying the session.
  • Each time the browser sends a request, the server decrypts the session, modifies the data, signs the session, and sends the session to the browser in a cookie.

In other words, a hacker cannot obtain a password from a cookie or from a private key. He needs both a cookie and a secret key to steal a password.

In this case, passwords A, B, C are safe. The hacker will be stolen only Ds password. You can minimize damage by repairing the system as soon as possible.

CustomMemoryStore Problem

Besides the security issue, I know that you know that CustomMemoryStore does not scale. However, the problem may be more than you think. You will send a request for other web services to your controller, it will block your entire server if the remote service is slow or down. This can be painful even if you only have 1 ~ 10 single-user users.

Even if you decide to run the application on one server, you can run several rails using Passenger or Unicorn. CustomMemoryStore negates these options.

Customer Security Advice

If the problem is that the cookie is stolen by the browser, you can consider EncryptedCookieStore . It encrypts the session and stores it in the client cookie. You cannot get a password if you only have a cookie or key. You need both a cookie and a password decryption key.

What is the main problem?

EncryptedCookieStore is more secure because it stores the encrypted password in the cookie of users, and the secret key is available only on the server. A hacker cannot get a password if he only has a cookie or secret key. He needs both.

Of course, you can implement similar logic using CustomMemoryStore. For example, store the encrypted password in the serverโ€™s memory, and a separate key is in the cookie. If you still decide to keep the encrypted password on the server, I recommend using Redis for storage. It is simple and fast compared to MySQL and MongoDB. CustomMemoryStore is not offered due to scaling issue.

Other offers

The password of another system is very sensitive data, you must be very careful in solving the security problem. If this is a public service, you must write the service agreement and disclaimer very carefully. In addition, you must start your services using HTTPS.

TL DR

  • Use OAuth if you can (well, I know you can't)
  • EncryptedCookieStore should be simple and secure.
  • If you decide to save the password on the server, encrypt it and save the secret key on the client side (cookie).
+1
source

Source: https://habr.com/ru/post/901701/


All Articles