One more thing to add to your security portfolio

I recently implemented a system which stores DNS names, and writes out DNS zone files. I found these to be rather useful tests:

  def test_name_with_newline_fails     z = Zone.new(:name => "test\nzone")     assert !z.valid?     assert z.errors.on(:name)   end

  def test_name_with_space_fails     z = Zone.new(:name => "test zone")     assert !z.valid?     assert z.errors.on(:name)   end

When I use these zone names, I _always_ append a specific string, e.g. '.example.com.'

If someone creates a zone called "foo" I will call it "foo.example.com." So, when I write out an A record, it would be something like:

  puts "#{zone}.example.com. A #{address}"

If the user happened to submit: "hacker\n@ NS hacker-nameserver.example.com." -- we would have problems.

I thought this regular expression would catch it:

    /^[a-zA-Z0-9\-\_\.]$/

and indeed it does catch spaces, random control characters... but not newlines! Much to my surprise, I needed to use \A instead of ^ and \Z instead of $. ^ matches the beginning of a _line_ and $ the end. \A and \Z match the beginning and ends of STRINGS.

Just a FYI, perhaps I am the only one out there who did not know this.

--Michael

Michael, Thanks for that. I did just read about this exact problem in the rails guide on security:

Chas Lemley