articles tagged with tips

Configuring subdomains in development with lvh.me

3 comments

I do a lot of work with subdomains, managing them locally on my development and test machines has always been a bit of a pain. Going way back, I can remember manually editing the hosts file in system32\drivers\etc\ on Windows! On the Unix we have /etc/hosts.

Unfortunately /etc/hosts doesn’t allow wildcard definitions for subdomains, so you have to manually specify each one. For a while I used this simple bash script to append a new domain (or subdomain) to the /etc/hosts file;

#!/bin/bash

SUBDOMAIN=$1
TLD=$2

if [ $# -lt 1 ]
then
  echo "which subdomain?"
  read SUBDOMAIN
  if [ -n "$SUBDOMAIN" ]
  then
    SUBDOMAIN="$SUBDOMAIN."
  fi
fi

if [ $# -lt 2 ]
then
  echo "which tld?"
  read TLD
fi

echo "127.0.0.1 $SUBDOMAIN$TLD" >> /etc/hosts
echo "OK, added 127.0.0.1 $SUBDOMAIN$TLD to /etc/hosts"

Save this script as executable somewhere in your PATH, call it something like addhost then run it from anywhere like so;

> addhost # will prompt for subdomain, tld (leave blank for no subdomain)
> addhost www test.com

This soon became tiresome, with some apps requiring 10’s or 100’s of subdomains to be tested and available locally. So I took to writing a simple rake task that would automatically pull subdomain names from an applications database and append them to my local /etc/hosts file (here’s that script).

Time passed and my script worked well, but had a some disadvantages. I had to re-run it every-time my subdomain data changed, and across apps it required modified since I had different ways and means of defining subdomain sites.

Enter the most excellent suggestion from Tim Pope. Using DNS to solve this problem means no more hassle! He set up a localhost wildcard, pointing *.smackaho.st at 127.0.0.1. Essentially this means that [anything].smackaho.st will point to your local machine. Not happy with smackaho.st? lvh.me does the same thing (lvh, as in local virtual host). Or since most developers have a couple of old domains lying dormant, why not use one for this? I learned of Tim’s technique through the Subdomains in Rails 3 screen-cast from Ryan Bates.

So I think that wraps up all my posts on subdomains, whats that? four now!? Here are the other three.

January 10, 2011 17:54 by

Yet another Rails security checklist

3 comments

I recently spent some time looking at application security on an old and new (Rails 3) app. Below is short (rather long) summary of my findings.

Quick caveat, this is by no means meant to be an exhaustive post on Rails security (for that I’d recommend you read the official Ruby On Rails Security Guide)

I’ve basically highlighted what I think are the bare minimum of checks you should be doing before throwing an application into the wild. And i’m focusing more on the actual preventative measures. Also I should point out that (unless your app is very small) security is not something you can retro-fit at the end of a project. To avoid holes you really need to be thinking about these things as you go.

Do not trust logged in users! (Authentication != Authorisation)

‘Change-affecting’ actions create/update/delete (and their corresponding views new/edit) need to be protected. So always check the current logged user is allowed to perform the requested action.

One way to do this, is to have the concept of a user owning a model and scoping find’s on these actions by the user. Or consider adding a before filter to the controller, that validates the logged in user against the action being performed on the object. For instance, create methods like can_edit?(by_user) or can_destroy?(by_user)

Remember too, that the most popular Rails plugins, Clearance, Devise and Restful Authentication only authenticate users, and provide no helpers or methods for authorisation. Also, I’d advise against building your own authentication system from scratch!

Mass assignment

A params hash can contain anything, so protect all sensitive attributes from re-assignment. The best way to do this is through disabling mass assignment by using attr_accessible (or attr_protected)in your models. Attributes like counter caches, account_id’s and user_id’s are prime examples for protection.

Un-editable attributes

Disable updates on protected attributes. Using attr_readonly in ActiveRecord allows the attribute to be set on create, but never edited on update. E.g. In many cases an account_id should be set once and never change.

SQL Injection

Don’t include user submitted strings in database queries! Check all model scopes and find conditions that include params or interpolated strings. E.g. LIKE searches should have the keyword passed in this form;

posts.where('posts.title LIKE ?', "%#{keyword}%")

Prevent executable files from being uploaded

Consider validating the content type on all attachments, and place uploaded files in protected directories or on another server/service e.g. S3/Cloudfront. Content-types can easily be faked, so check file extensions and be sure to disable your web server from executing scripts in the upload directory.

Also, beware of plugins creating or writing in tmp directories during file upload creation. They may create files or directories from user submitted params without checking the file path. In general be familiar with your gems and plugin code.

Filter sensitive params from logs

Use filter_parameter_logging or config.filter_parameters (Rails 3) to remove sensitive data from your logs (:password, :password_confirmation, :credit_card_number etc.)

CSRF

Enable protect_from_forgery and use form helpers to include the Rails authenticity token in all form submissions. In Rails 3 ensure the HTML head tag includes the csrf_meta_tag helper.

XSS

Prevent XSS and javascript injection by escaping all rendered user content (use the ‘h’ helper). In Rails 3 this happens by default so be careful what you whitelist for rendering (with raw, or html_safe!) If you are using something like Textile or Markdown, make use of the whitelist filtering methods their libraries provide.

Session Hijacks

Sessions are open to a number of vulnerabilities. Hijacking, replaying cookies, session fixation etc. Check the Ruby On Rails Security Guide for all the details. Here are some general tips;

If storing login information e.g. a remember_me cookie for authentication use CookieStore with a digest and reasonably complex server-side secret.

Be careful what data you decide to store and use in your sessions. Don’t store ActiveRecord objects, future code changes or migrations may change an objects behaviour/attributes and clients with old session data will be out of sync. Better to store only id’s for records in the session and load model objects server-side.

Other things to NOT store in your session include; money balances, user access privileges or sensitive state based information etc. These are open to session replay attacks.

Finally, to avoid session fixation attacks, call reset_session after a successful login.

Redirecting

Avoid using redirect_to(params[:some_param]). When the arguments for a redirect come from params, you are open to redirects to unintended URLs.

Downloading files, raw data

Avoid using params or user content in the send_file method. Consider having these as absolute filenames stored in the database, or validate the path to the file before calling send_file.

Make non-action controller methods private.

Remember that any methods you declare in a controller could be accessible to the public depending on your routes.

Gems and plugins

Remember to check your dependencies for security updates and patches. If possible subscribe to the GitHub issues list or (any mailing list) for the gems or plugins your using.

Passwords

Don’t store passwords in the database as clear text! Maybe that one goes without saying :) Encourage strong alphanumeric passwords and if necessary follow other strong password practices (throttle multiple failed logins, password expiry/reset etc.)

Also, you really should use BCrypt to discourage rainbow table attacks. Read this to find out more.

Further reading

Most of this checklist has been compiled from the following links.

October 21, 2010 22:10 by

Rails 3 preparation

no comments yet, post one now

Here’s a few links on Rails 3 I’ve collected in preparation for its release. I haven’t read these all through yet, or started using Rails 3 in any way, but I have a couple of production apps primed and waiting to be upgraded as soon as it launches.

Start with this one from RubyInside, 36 links to get you going

And finally some official release notes;

April 15, 2010 14:27 by
← (k) prev | next (j) →