Intranet and Admin Security

These days the intranet is coming back. I heard it a couple of times: Our intranet is safe, there’s an authentication system and it can be accessed  by hosts from our local IP range only, but no, there are no further security measures. If someone manages to get in, he will be able to do and see a lot. And, yes, the bad guy can get in under certain circumstances.

Last year, for example, we have seen the first tailor-made Trojan which stole information from an intranet, the “Monster for employers” web site of Monster.com. These Trojans are very rare so far and the risk is quite low, but it’s certainly a possibility and an example of how the security of the client host is important, too.

 

XSS in your intranet
While special malware might be less likely for small intranets, XSS and CSRF are not. If your intranet application re-displays unsanitized user input from the extranet (user names, comments, spam reports, order addresses to name just a few uncommon places where I’ve seen malicious user input), the application will be vulnerable to XSS.
Already one single place in the intranet where the input has not been sanitized makes the entire application vulnerable. Vulnerable to what? Well, cookie stealing (YES, it’s a priviledged intranet cookie), content alteration to lure victims to a fake intranet where he might enter confidential information and so on. So I hope you have found a way to eliminate XSS everywhere in your app.

 

CSRF in your intranet
Yup, CSRF (Cross Site Request Forgery) is real, as well. It takes place in combination with XSS or the old-fashioned way: Send an HTML e-mail with CSRF to the victim or lure him to an infected web page. What is CSRF? Take a look at two examples which trigger a GET and POST action (.src is src):

<img .src=”http://intranet/project/1/delete” />

Generate this in Rails and you have a link to a POST action:

link_to(“To the survey”, “http://www.your-online-expense-tracker.com/account/delete”, :method => :post)

Now if the user views the page (for the image) or clicks the link, and he is logged in to the application (i.e. the cookie is set in the browser), the project or account will be deleted. Of course, the attacker has to know the URL structure, but most Rails URLs are quite straightforward or they’re publicly accessible like in the expense tracker application.
The attacker may even do 1,000 lucky guesses. The countermeasure in Rails is to include a token in each POST request that will be verified on the server. See the first post about this, but the csrf_killer plugin has been merged into Rails.

 

Administration
Now, you do have an administration interface for your application? How about its security? Did you take it more serious than the actual applications’ security? You should, because in most cases a security breach is more harmful here.

The common admin interface is like this: It’s located at www….com/admin, may be accessed only if the admin flag is set in the User model, re-displays user input and allows the admin to delete/add/edit a lot. Here are some thoughts about this:

  • As an admin interface is kind of an intranet, the same vulnerabilities as described above may be there. The attacker could steal an admin cookie (via XSS) or use CSRF to delete some users: www….com/admin/user/delete/2

 

  • It is always very important to think about the worst case: What if someone really got hold of my cookie or user credentials. You could introduce roles for the admin interface to limit the possibilities of the attacker.
    And how about special login credentials (other than the ones used for the public part of the app) for the admin controller and another password for very serious actions?

 

  • Does the admin really have to access the interface from everywhere in the world? Think about limiting the login to a bunch of source IP addresses.
  • Put the admin interface to a special sub-domain such as admin.application.com. This makes stealing an admin cookie from the usual domain impossible.
    This is because of the same origin policy in your browser: An injected (XSS) script on www.application.com may not read the cookie for admin.application.com and vice-versa. Of course this precaution will be useless if the attacker got hold of the cookie from www.application.com and may simply copy the cookie string to make one for the admin.application.com host. Use two session tables (if you use the :active_record_store session store) or a seperate admin application for that.