Last Updated: May 30, 2016
·
5.024K
· danielpclark

How to Hide Your ActiveAdmin Path

I will assume you've already installed devise in your Rails app. Also lets assume you are already using your /admin route. And lets assume you've secured your admin route possibly with code like this:

app/controllers/admin_controller.rb

class AdminController < ApplicationController
  before_filter :require_permission
  private
  def require_permission
    if not current_user.try(:admin?)
      redirect_to root_path
    end
  end
end

or in your routes file

config/routes.rb

authenticated :user, lambda {|u| u.admin } do
  get 'admin', to: 'admin#index'
end

but maybe you just want to link to ActiveAdmin from a user's hompage if they're an admin. You could simply just enter in your view:

<% if current_user.admin? %>
  <%= link_to "ActiveAdmin", "/your_active_admin_url" %>
<% end %>

but then anyone could enter yourwebsite.com/your_active_admin_url if they know the directory (presuming the other security measures aren't in effect). So let's up the paranoia and make the directory randomly change with each Rails restart

First let's edit our ActiveAdmin initializer file.

config/initializers/active_admin.rb

require 'securerandom'
ActiveAdmin.setup do |config|
  config.default_namespace = SecureRandom.base64( 24
           ).gsub( /[+\/=]/, ""
           ).prepend( "aa"
           ).downcase
end

and lets make it as a subdirectory under admin. So in our routes file:

config/routes.rb

scope :admin do
  devise_for :admin_users, ActiveAdmin::Devise.config
  ActiveAdmin.routes(self)
end

Now since the namespace is random it will look something like this /admin/aanoh3viemwxppom9sxgfpdhv99c01gsf/dashboard and it will change every time Rails is restarted.

You might be thinking... well that's cool and all, but how am I going to know how to get to the ActiveAdmin page on a server where I don't see the routes? I can't guess it...

Now this is where you will need a url path helper to update your links every time the path changes. So let's create a helper method. Paste this in your file:

app/helpers/application_helper.rb

module ApplicationHelper

  def active_admin
      ObjectSpace.each_object(
          ActiveAdmin::Resource::Routes
      ).first.namespace.name
  end

end

and now every time you want to use Rail's built-in path helpers you will prepend them with an eval of this. For example:

eval("#{active_admin}_dashboard_path")

So now you can change the link on your admin users page to this:

<% if current_user.admin? %>
  <%= link_to "ActiveAdmin", eval("#{active_admin}_dashboard_path") %>
<% end %>

And you've done it! Random folder path for ActiveAdmin achieved! So for the paranoid feel free to incorporate ALL of the above methods for admin security. And make sure they work before you lock yourself out ;-)

Of course the weakest link in security is people. Everyone you give admin privileges to are an added security risk. Because people are most often susceptible to social engineering. So make sure all admin's are educated on this to help maintain your system's integrity.

God Bless! Code, Comment, Share!
-Daniel P. Clark

2 Responses
Add your response

The only problem here is that you lose the ability to bookmark the URL since it does in fact change every time rails is restarted. How does this work on a load balancer? If deployed to multiple servers would each instance not have its own URL?

over 1 year ago ·

Yes it is purposefully done so you can't bookmark it. Security in obscurity. And yes if it's on multiple servers each would have it's own url... but they would each work on their own servers. ActiveAdmin controls themselves don't have a problem with the relative url. You will often handle items/resources from outside of ActiveAdmin scope. Otherwise you can simply include the dynamic directory link helper.

If several ActiveAdmin's are running on different servers and accessing the same database resource, this obscure subdirectory has no affect on how the data is handled or processed. It will be the same as if there were no obscure subdirectory.

I'm not sure about a load balancer. It's just a link, although dynamic, so I don't believe it would be an issue.

If for some reason you wanted to access ActiveAdmin's on different servers as they may have instances where they would keep controls specific to that server, then you could design an api call to the random directory string. But then again you would want to secure and obscure the api call. ;-) Or just ensure the admin user is logged in for the remote request to get the directory string. It all depends on how far you want to go with it.

over 1 year ago ·