Collective Idea

Collective Idea Logo

Steve Richert

Automatic Login Links

By Steve Richert on June 14, 2011 in authentication and rails

Scary, I know, but hear me out. Implemented correctly, an automatic login link can be just the ticket to appease those pesky, forgetful, real-world users.

Imagine a Rails application that sells fruit. The app has two kinds of users:

  1. A customer who comes to the site to buy fruit
  2. A seller who registers at the site to sell and ship fruit to customers

If you’re buying your fruit online, you’re probably pretty tech-savvy. Odds are you have accounts at a lot of sites and you do a decent job of remembering your passwords. And when memory fails, there’s the always-helpful “Forget your password?” link.

But what about the sellers? These guys are a bunch of farmers and not necessarily the most adept computer users. But every time a new order comes in, the seller gets an email prompting them to log in and ship the order.

Spoiler alert: The sellers never remember their passwords.

In this case, an automatic login link can go a long way to keep the sellers and the customers happy. However, with this approach, there are two important bases to cover in order to protect yourself from brute force attacks:

  1. The link must be secure (random)
  2. Access to the link must be temporary

In order to make the link temporary, we’ll attach each link to an order rather than to the seller. That way we can expire the link as soon as the order is shipped. Here’s the order model which automatically generates a unique login token when an order is placed and clears the login token when the order ships:

class Order < ActiveRecord::Base
  belongs_to :seller
  belongs_to :customer

  before_create :set_login_token

  scope :authenticatable, where("orders.login_token IS NOT NULL")

  def ship_it!
    # TODO Send the fruit off to the customer
    update_attribute(:login_token, nil)
  end

  private
    def set_login_token
      self.login_token = ActiveSupport::SecureRandom.urlsafe_base64
    end
end

Now we need a route for the automatic login link:

ApplesAndOranges::Application.routes.draw do
  resources :orders, :only => [:index, :show, :destroy] do
    member do
      get :authenticate
      post :ship
    end
  end
end

And in the orders controller, we can automatically log the seller in when she follows the new route:

class OrdersController < ApplicationController
  respond_to :html

  before_filter :require_current_seller, :except => :authenticate
  before_filter :load_order, :except => [:index, :authenticate]

  def index
    @orders = current_seller.orders
    respond_with @orders
  end

  def show
    respond_with @order
  end

  def destroy
    @order.destroy
    respond_with @order
  end

  def authenticate
    order = Order.authenticatable.find_by_login_token!(params[:id])
    # TODO Force-log-in order.seller
    redirect_to order
  end

  def ship
    @order.ship_it!
    respond_with @order
  end

  private
    def load_order
      @order = current_seller.orders.find(params[:id])
    end
end

And that’s it! Now, in the order notification email, we can send the automatic login link to the seller:

Dear <%= @seller.name %>,

Congratulations! You have a new order.
View your order here: <%= authenticate_order_url(@order.login_token) %>

Thank you!

There may be some hesitation with allowing direct authentication like this and in a many cases, it’s justified. This technique certainly doesn’t fit all applications. As always… proceed with extreme caution.

That said, this approach can be extremely useful in certain situations. If you’re already taking advantage of the “Forget your password?” functionality mentioned above, you’re probably sending similar, perishable, password-reset links to your users. Automatic login links are no less secure. Either way, an intruder has to either gain access to your email account or guess the random link.

It may be scary but I hope this helps shed some light on the technique and how it can be done securely. Your farmers will love it!

Update: Jeffrey Paul also wrote a blog post today on this very subject, explaining his own frustration with constant prompts to log in. You can read his post here.

By Steve Richert on June 14, 2011 in authentication and rails

16 Comments

  1. Rodrigo Dellacqua

    Rodrigo Dellacqua June 14, 2011

    current_seller would be nil, wouldn’t it?

  2. Steve Richert

    Steve Richert June 14, 2011 http://collectiveidea.com

    Nice catch! Fixed. Thank you.

  3. Dave Paola

    Dave Paola June 14, 2011 http://davezor.net

    At Kontagent, we have a system where we are able to “morph” into user accounts, thereby receiving all the same permissions and abilities of that user.  This helps us debug for support stuff, mostly.  But it also includes the ability to send someone else a link to that account and hence the ability to also morph. 

    It’s a similar system, and I bet more things will start utilizing this paradigm.

  4. Philip Tellis

    Philip Tellis June 14, 2011 http://tech.bluesmoon.info/

    This kind of URL is called a “capabilities URL” in security circles.  It’s a common pattern, and often considered more secure than username/password pairs, though its security depends on how the user protects it.

    You can find more details here: http://en.wikipedia.org/wiki/Capability-based_security

  5. Dan McGrath

    Dan McGrath June 14, 2011 http://u2tech.wordpress.com

    This makes me sad :(

    @Phillip, no, it is not more secure. It is equivalent to storing your username/password in an email that will be forward on to someone else.

    That means if you forward the email to anyone within the [insert expiry period here] they have full access you your account.

    Please don’t be a Sony.

    If you really want to do something like this, PLEASE implement some form of out of band 2FA. For example, SMS a PIN to a mobile number once the link has been clicked. This gives the benefit of not needing to remember your password, but requiring more than just a forwarded email to sign in.

  6. grosser

    grosser June 14, 2011 http://grosser.it

    You dont even need the column if you use url_store https://github.com/grosser/url_store

  7. Brad

    Brad June 14, 2011 http://igodigital.com

    @Dan or you could disable the link after being clicked once?  Not as efficient for the consumer, but more secure.

  8. Dan McGrath

    Dan McGrath June 14, 2011 http://u2tech.wordpress.com

    @Brad. That helps, but do you click every link you receive via email? I know I don’t.

    The other assumption that is bad in terms of comparing it to the forget password link is in frequency.

    If someone is intercepting traffic at the MTA, they will have a much lower strike rate than if you were sending auto login links in every email, as opposed to only when the user specifically requests it. Auto-login links = Guaranteed compromise vs Forgot password link = Potential Compromise.

    PS: I’m not advocating the forgot password links either, though :)

  9. Tyr Grisfal

    Tyr Grisfal June 14, 2011

    Multi-factor is always better…and not that hard today. Go, go, gadget SMS API.

    Main gotchas with URI tokens are that it must expire and that you should use the same practices as for other login attempts. It shouldn’t be happy hour on brute force attempts simply because there’s not a web form involved.

  10. Mysterious

    Mysterious June 14, 2011

    Yea, I am not sure I like this.

    If you need to login with username / password then the bad guy has to have access to your computer to keylog.

    With the above method all he needs is access to your email account. And with things like auto-forwarding on gmail…

  11. Philip Tellis

    Philip Tellis June 14, 2011 http://tech.bluesmoon.info/

    @Dan actually that’s exactly the point of capabilities URLs, anyone who has the URL has access to the page.  You’d email it to anyone who you wanted to give access to the site.  Another example of this in the wild is flickr’s secret URLs to a private photo set, or skitch’s secret URLs to a photo.

  12. Dan McGrath

    Dan McGrath June 15, 2011 http://u2tech.wordpress.com

    @Philip, no argument on that.

    The topic here, however, is slightly different. We are talking about account sign in and the level of security auto-login links provides.

    Unless you are arguing that it is a common use case to have someone want to forward on access to their account (as opposed to access to view stuff they set up through their account), my point still stands.

  13. ja,es

    ja,es June 16, 2011 http://southindianfood4.blogspot.com/

    it is ablicble for bloger and wordpress also?

  14. Amol Hatwar

    Amol Hatwar June 20, 2011 http://hatwar.org/epilogue/

    @Dan I agree with Philip. In real life it is equivalent to giving the keys of your pad to someone else, possibly someone you trust.

    Now the someone you trust is free to abuse it. Either by doing something nasty in your house, or worse by copying the key; or maybe even giving it to someone else without your knowledge. Yes. The practice is inherently insecure. But we do it all the time with the people we trust or when the damages of a breach affect both the parties.

    That said, if one doesn’t want the user to do the sign in, forget password and confirmation dance for a getting a small action done, I don’t see a comparable easy-to-use solution than using single-use links. In such cases, sharing the link is really a “feature”; and a much better solution than sharing actual account passwords.

    Also, application designers rely on certain assumptions – like the user would follow instructions in English (or some other language), the screen-resolution would be a certain minimum and the likes… The assumption that a user is able to secure his/her email account is central in this scheme of things.

    At the end of the day, all the application designer has done is to give the user the keys to his own account. If the user can’t secure his email account, or doesn’t know better about whom to trust with the links – I don’t think it is a mistake on the application designer’s part at all.

    From a security standpoint, what an application designer should do must really depend on the value at risk. Best practices aren’t for everyone…

  15. jonblock

    jonblock June 21, 2011

    @Amol, it’s probably not a good idea to trust the user to secure his/her email account.  In addition to the possibility that at least one (and probably most, in this scenario) seller will not take the appropriate steps to secure the account itself, the global email infrastructure is not designed to keep messages secure in transit.  At least one hop along the way from sending system to receiving account is likely to allow for the possibility of snooping.

    Reading these comments brings to mind another possibility that might better balance the account security concerns with the desire for user convenience.  With a bit more developer effort, you could implement a two-tier access system.  Automatic login links would give you access to the specific task at hand, and possibly other related tasks.  But attempting to access core account functions (bank info, seller contact information and password, full customer list, etc.) would prompt for the account’s password first.

    It’s also worth considering that, even if you are willing to accept the reduced security of automatic login links, some of your customers may not.  You can address this with a user preference setting (“Allow automatic login from email links”).

  16. Anubhav

    Anubhav January 26, 2013 http://www.brickwin.com

    @Dan, Adding one point to your post, You have mentioned the case of forwarded mail, My point is if suppose seller1 do not have enough fruits and wants to forward that email to  seller2, in that case none of the above solution works. In that case can we ask something like Not Seller1, Log out. But I am biased if the user needs did not get conflicted by doing this? After all security is very important concern for me.

    Well currently,I am using Capability URLs.

Post a Comment

Contact Us

Find us on Google Maps
Collective Idea
44 East 8th Street, Suite 410
Holland, Michigan 49423 USA 42.790334-86.105251

Follow us on the Interwebs

We are currently available for medium and long term projects. Please get in touch if we can be of service.