Thursday, 21 June 2012

test test test...

As I'm working on PNTSTR,I get more and more afraid of mistakes... Mistakes happen and I don't want a bug to break the production and especially if I got a bug I want to only fix it once... That's why I'm using unit tests.

Furthermore, I'm using unit tests to ensure the security of my application, I write a good part of my security checks as test cases:

For example, can a user access a given page without being logged in?

class TestConsole < Test::Unit::TestCase
  include Rack::Test::Methods


  def app
    Console
  end


  def assert_redirect_to_login
    assert last_response.header["Location"] =~ /\/login$/
    assert last_response.status == 302
  end

  def test_redirect_interviewees_without_login
    get "/interviewees"
    assert_redirect_to_login
  end
end




In the same way, I use it to check that once I'm logged in, I can get to the page:

  def test_access_interviewees_with_login
    login("louis@pentesterlab.com", "secret")
    get "/interviewees"
    assert last_response.status == 200
  end

It can be used to ensure I cannot log in with a wrong password, a null password (remember LDAP anonymous bind??) or a blank password:

  def test_cannot_login_with_blank_password
    get "/login"
    login("louis@pentesterlab.com", "")
    assert_redirect_to_login
  end
  
  def test_cannot_login_with_nil_password
    # typical LDAP bug
    get "/login"
    post("/login", {:email => "louis@pentesterlab.com"} )
    assert_redirect_to_login
  end
  
  def test_cannot_login_with_wrong_password
    get "/login"
    login("louis@pentesterlab.com", "wrong")
    assert_redirect_to_login
  end


You can even use it to check for cross authorisation checks, here I check if i can access someone else (the first user) interviewee:

  def test_can_access_someone_else_interviewee
    # user first is not me
    id = User.first.interviewees[0].id.to_s
    login("louis@pentesterlab.com", "secret")
    get "/interviewees/#{id}"
    assert_redirect_to_login
  end




Or for SQL injection (silly example above, but still make sure it's not here):



  def test_cant_sqli_login
    # user first is not me
    login("louis@pentesterlab.com' or 1=1 -- ", "")
    assert_redirect_to_login
  end
  
or Cross Site Scripting (simple but it covers the basics):

  def test_cant_xss_login
   ["'", "\"", "<", ">" ].each do |c|
    login("louis@pentesterlab.com#{c}", "")
    assert last_response.body !~ /#{"louis@pentesterlab.com"+c}/  
   end
  end

If everyone was doing that, I think the security of web applications will be far better... Anyone else doing something similar?








No comments: