Search code examples
ruby-on-railsdeviseurl-routing

Rails routing: How to create an unguessable route


I need somehow to make my routes non-guessable.

Actually a user finish the operation cycle (order status is finish) by making a get request via a QR-CODE reading.

But is pretty easy to 'guess' the route since the id is the same in the whole order life-cycle. The users can see the id in URL when the status is acepted (before finish).

So I was thinking to add a kind of random token to the url so they can't guess the route...

My routes are like this atm:

resources :orders, only: %i(create show index destroy edit update) do
    resources :reviews, only: %i(create new show index)
    resources :payments, only: %i(new create)
    member do
      post 'accept'
    end
    member do
      get 'read_qrcode'
    end
  end

Which generates this pattern to read_qrcode route:

/orders/:id/read_qrcode

So I was thinking to add any kind of token, maybe MD5 Hash, timestamp or whatever after read_qrcode and get a url like this:

/orders/:id/read_qrcode/1a79a4d60de6718e8e5b326e338ae533

How can I achieve this result, or maybe another solution to this?


Solution

  • Make the token the md5 of the concatenation of the ID and a secret.

    So, let’s say the secret is “-no-guessing!”.

    With an ID of 1, then md5(“1-no-guessing!) is 9493F2E821BA8B1FC791A048BBCD9A19

    And with ID 2, the token would be AD17E6D3551BF0C0A2B0D5A029AEFBB2

    Those are legit MD5 hashes of the strings in the example, you should be able to verify that.

    But I would need to know the secret to be able to generate this. Your app knows the secret, but your user does not.

    When your orders#read_qrcode action is processed, pass the token as a get param (no need for it to be a path param). Then, have the controller generate the md5 of the concatenation of ID and the secret, comparing it with the token passed as a param

    What I’ve described above is essentially an HMAC, where the “message” is the ID of the order. See https://en.m.wikipedia.org/wiki/HMAC for more on HMACs