SlideShare a Scribd company logo
Security Testing through Automated Software Tests Stephen de Vries, Principal Consultant, Corsaire [email_address]
Sub bullet Typical Iterative development life cycle Correcting issues is costly The people who understand the code best, don’t perform the security tests No buy-in from developers into the security process
Typical Iterative development life cycle
Typical Iterative development life cycle Integrating Security Tests in the process:  A shorter security testing phase More robust applications because testing is deep Developer involvement in security
Outline A taxonomy and description of testing types  An introduction to JUnit and examples of its use Testing compliance to a security standard  Testing security in Unit Tests Testing security in Integration Tests Testing security in Acceptance Tests Conclusion Q & A
Use cases and Abuse cases Use cases Expected behaviour Normal input Functional requirements Abuse cases Unexpected behaviour By Malicious agents Derived from risk assessment Developers should  think evil  which leads to… Defensive programming
Taxonomy of Automated Software Tests Unit Tests Integration Tests Acceptance Tests
Taxonomy of Automated Software Tests Unit Tests Operate at the method and class level High test coverage Test in isolation - stubs and mocks Executed the most frequently Written by developers
Taxonomy of Automated Software Tests Integration Tests Integration between classes and modules Integration between tiers In-container tests or Mock objects Executed often, but not as often as unit tests Written by developers
Taxonomy of Automated Software Tests Acceptance Tests Performed on the external API Low test coverage Executed the least frequently Performed by QA testers
Introducing JUnit “ Never in the field of software development was so much owed by so many to so few lines of code.” - Martin Fowler
Introducing JUnit Example: A single method from a shopping cart class public void addItem(Item item, boolean inStock) { CartItem cartItem = (CartItem) itemMap.get(item.getItemId()); if (cartItem == null) { cartItem = new CartItem(); cartItem.setItem(item); cartItem.setQuantity(0);   cartItem.setInStock(inStock);   itemMap.put(item.getItemId(), cartItem); itemList.getSource().add(cartItem); } cartItem.incrementQuantity(); }
Introducing JUnit Test that:   a new cart has 0 items in it adding a single item results in that item being present in the cart adding a single item results in the cart having a total of 1 items in it adding two items results in both items being present in the cart adding two items results in the cart having a total of 2 items in it Test whether adding a null item results in an exception and nothing being set in the cart
Introducing JUnit public class CartTest extends TestCase { public CartTest(String testName) { super(testName); } protected void setUp() throws Exception { //Code here will be executed before every testXXX method } protected void tearDown() throws Exception { //Code here will be executed after every testXXX method } public void testNewCartHasZeroItems() { // Test code goes here } public void testAddSingleItem() { // Test code goes here } public void testAddTwoItems() { // Test code goes here } public void testAddNullItem() { // Test code goes here } }
Introducing JUnit public void testAddTwoItems() { Cart instance = new Cart(); boolean isInStock = true; //First add an item Item item = new Item(); item.setItemId("item01"); instance.addItem(item, isInStock); //Test adding a second item Item item2 = new Item(); item2.setItemId("item02"); instance.addItem(item2, isInStock); //Check whether item01 is in the cart boolean result = instance.containsItemId("item01"); assertTrue("First item is in cart", result); //Check whether item02 is in the cart result = instance.containsItemId("item02"); assertTrue("Second item is in cart", result); //Check that there are 2 items in the cart assertEquals("2 items in cart", instance.getNumberOfItems(), 2); } USE CASE  TEst
Introducing JUnit public void testAddNullItem() { Cart instance = new Cart(); boolean isInStock = true; try { instance.addItem(null, isInStock); fail("Adding a null item did not throw an exception"); } catch (RuntimeException expected) { assertTrue("null Item caught",true); assertEquals("Null not in cart", instance.getNumberOfItems(), 0); } } ABUSE CASE TEST
Introducing JUnit Using JUnit Supported in all Java IDE’s Ant and Maven support Part of the code-debug cycle
Introducing JUnit Other Unit testing frameworks Java – JUnit, ( www.junit.org ), TestNG ( http:// beust.com/testng / ), JTiger (www.jtiger.org) Microsoft .NET – NUnit ( www.nunit.org ), .NETUnit ( http:// sourceforge.net/projects/dotnetunit / ), ASPUnit ( http:// aspunit.sourceforge.net / ), CSUnit ( www.csunit.org ) and MS Visual Studio Team Edition and many more. PHP – PHPUnit ( http:// pear.php.net/package/PHPUnit ), SimpleTest ( www.simpletest.org ) Coldfusion – CFUnit ( http:// cfunit.sf.net ), cfcUnit ( www.cfcunit.org ) Perl – PerlUnit ( http:// perlunit.sf.net ), Test::More (included with Perl) Python – PyUnit ( http:// pyunit.sf.net ), doctest (included in standard library) Ruby – Test::Unit (included in the standard library)  C – CUnit ( http:// cunit.sf.net ), check ( http:// check.sf.net ) C++ – CPPUnit ( http:// cppunit.sf.net ), cxxtest ( http:// cxxtest.sf.net )
Web Application Security Standards What is a Web Application Security Standard? Derived from an organisation’s Security Policy Similar to an Operating System Build Standard Defines how the application should behave from a security point of view Should include functional and non-functional security aspects
Web Application Security Standards Example:
Web Application Security Standard
Testing Security in Unit Tests Test Valid Input public void testValidPhoneNumbers() {  //Test valid input String number = "232321"; acc.setPhone(number);  validator.validate(acc, errors);  assertFalse(number+" caused a validation error.",  errors.hasFieldErrors("phone")); number = "+23 232321"; acc.setPhone(number); validator.validate(acc, errors);  assertFalse(number+" caused a validation error.",  errors.hasFieldErrors("phone")); number = "(44) 32321"; acc.setPhone(number); validator.validate(acc, errors);  assertFalse(number+" caused a validation error.",  errors.hasFieldErrors("phone"));   //etc…  }
Testing Security in Unit Tests Test Invalid Input: public void testIllegalCharactersInPhoneNumber() { String number = "+(23)';[]232 - 321"; acc.setPhone(number); validator.validate(acc, errors);  assertTrue(number+" did not cause a validation error.",  errors.hasFieldErrors("phone")); }  public void testAlphabeticInPhoneNumber() { String number = "12a12121"; acc.setPhone(number); validator.validate(acc, errors);  assertTrue(number+" did not cause a validation error.",  errors.hasFieldErrors("phone"));   }
Testing Security in Unit Tests Advantages of testing at this layer Tests are run very frequently - issues are identified quickly Most granular form of test - high test coverage Disadvantages Not many security vulnerabilities can be tested at this layer
Testing Security in Integration Tests In-container testing Realistic and complete Requires specific tools Overhead in starting container Mock Objects Server API is faked Generic solution No container overhead
Testing Security in Integration Tests In-container testing with Apache Cactus Popular tool for testing J2EE applications Can test EJB and Web tiers Plugin’s for Jetty, Eclipse, Ant and Maven
Testing Security in Integration Tests Lifecycle of a single cactus test beginXXX() - setup the client side setUp() - common server side code testXXX() - server side test tearDown() - common server side code endXXX() - client side tests
Testing Security in Integration Tests public class TestAccessControl extends ServletTestCase { public void beginUnprivilegedUserAccessControl(WebRequest  theRequest) {   theRequest.setAuthentication(new    BasicAuthentication("user", "password")); } public void testUnprivilegedUserAccessControl() throws  IOException, javax.servlet.ServletException { AdminServlet admin = new AdminServlet(); admin.doGet(request, response); } public void endUnprivilegedUserAccessControl(WebResponse  theResponse) throws IOException { assertTrue("Normal users must not be able to access  /admin", theResponse.getStatusCode() == 401) } }
Testing Security in Integration Tests Advantages of testing at this layer Can test in the application server Many security vulnerabilities can be tested, e.g.: Injection,  Authentication flaws and Authorisation flaws. Disadvantages Not executed as often as unit tests Overhead of starting an application server Some vulnerabilities may not be easily testable, e.g.: XSS, URL  filtering performed by a web server or application firewall.
Security Testing in Acceptance Tests Tests the external API Language agnostic 2 types of tools: Include their own HTTP client and HTML parser, e.g.: HTTPUnit, jWebUnit, HtmlUnit, Canoo Webtest Drive a browser instance, e.g.: Selenium, WATIR, Watij
Security Testing in Acceptance Tests Example: Testing HTML injection with jWebUnit public class XSSinSearchFieldTest extends WebTestCase {  public void setUp() throws Exception { getTestContext().setBaseUrl(&quot;http://example.corsaire.com/ispatula/&quot;); } public void testHtmlInjection() throws Exception { beginAt(&quot;/index.html&quot;); assertLinkPresentWithText(&quot;Enter the Store&quot;); clickLinkWithText(&quot;Enter the Store&quot;); assertFormPresent(&quot;searchForm&quot;); setFormElement(&quot;query&quot;,  &quot;<a id=amp;quot;injectionamp;quot; href=amp;quot;http://www.google.com>Injection</a>&quot;); submit(); assertLinkNotPresent(&quot;injection&quot;); }  public XSSinSearchFieldTest(String name) { super(name); } }
Security Testing in Acceptance Tests
Security Testing in Acceptance Tests Example: Testing SQL injection with WATIR class SQL_Injection_Test < Test::Unit::TestCase include Watir def test_SQL_Blind_Injection_in_Login() $ie.goto('http://localhost:8080/ispatula') $ie.link(:url, /signonForm.do/).click $ie.text_field(:name, 'username').set('corsaire1apos; OR 1=1--') $ie.form(:action, &quot;/ispatula/shop/signon.do&quot;).submit assert($ie.contains_text('Signon failed')); end   # Snip setup code end
Security Testing in Acceptance Tests Example: Testing XSS with WATIR def test_XSS_In_Search $ie.goto('http://example.corsaire.com/ispatula/shop/index.do') $ie.text_field(:name, 'query').set('<script> window.open(&quot;http://example.corsaire.com/ispatula/help.html&quot;)</script>') $ie.form(:action, /Search.do/).submit assert_raises(Watir::Exception::NoMatchingWindowFoundException,  &quot;Search field is susceptible to XSS&quot;) {    ie2 = Watir::IE.attach(:url,  &quot;http://example.corsaire.com/ispatula/help.html&quot;) }  end
Security Testing in Acceptance Tests Advantages of testing at this layer Full testing of external API Security consultants can use tools to script vulnerabilities Documents vulnerabilities Easy retesting Disadvantages Low test coverage Developers aren’t involved in testing
Conclusions Existing testing tools and techniques can be used for security testing in the development lifecycle Developer training in security is a good investment! Security issues are identified early Code is subject to deep testing Compliance with a Web App Security Standard can be demonstrated

More Related Content

Security Testing

  • 1. Security Testing through Automated Software Tests Stephen de Vries, Principal Consultant, Corsaire [email_address]
  • 2. Sub bullet Typical Iterative development life cycle Correcting issues is costly The people who understand the code best, don’t perform the security tests No buy-in from developers into the security process
  • 4. Typical Iterative development life cycle Integrating Security Tests in the process: A shorter security testing phase More robust applications because testing is deep Developer involvement in security
  • 5. Outline A taxonomy and description of testing types An introduction to JUnit and examples of its use Testing compliance to a security standard Testing security in Unit Tests Testing security in Integration Tests Testing security in Acceptance Tests Conclusion Q & A
  • 6. Use cases and Abuse cases Use cases Expected behaviour Normal input Functional requirements Abuse cases Unexpected behaviour By Malicious agents Derived from risk assessment Developers should think evil which leads to… Defensive programming
  • 7. Taxonomy of Automated Software Tests Unit Tests Integration Tests Acceptance Tests
  • 8. Taxonomy of Automated Software Tests Unit Tests Operate at the method and class level High test coverage Test in isolation - stubs and mocks Executed the most frequently Written by developers
  • 9. Taxonomy of Automated Software Tests Integration Tests Integration between classes and modules Integration between tiers In-container tests or Mock objects Executed often, but not as often as unit tests Written by developers
  • 10. Taxonomy of Automated Software Tests Acceptance Tests Performed on the external API Low test coverage Executed the least frequently Performed by QA testers
  • 11. Introducing JUnit “ Never in the field of software development was so much owed by so many to so few lines of code.” - Martin Fowler
  • 12. Introducing JUnit Example: A single method from a shopping cart class public void addItem(Item item, boolean inStock) { CartItem cartItem = (CartItem) itemMap.get(item.getItemId()); if (cartItem == null) { cartItem = new CartItem(); cartItem.setItem(item); cartItem.setQuantity(0); cartItem.setInStock(inStock); itemMap.put(item.getItemId(), cartItem); itemList.getSource().add(cartItem); } cartItem.incrementQuantity(); }
  • 13. Introducing JUnit Test that: a new cart has 0 items in it adding a single item results in that item being present in the cart adding a single item results in the cart having a total of 1 items in it adding two items results in both items being present in the cart adding two items results in the cart having a total of 2 items in it Test whether adding a null item results in an exception and nothing being set in the cart
  • 14. Introducing JUnit public class CartTest extends TestCase { public CartTest(String testName) { super(testName); } protected void setUp() throws Exception { //Code here will be executed before every testXXX method } protected void tearDown() throws Exception { //Code here will be executed after every testXXX method } public void testNewCartHasZeroItems() { // Test code goes here } public void testAddSingleItem() { // Test code goes here } public void testAddTwoItems() { // Test code goes here } public void testAddNullItem() { // Test code goes here } }
  • 15. Introducing JUnit public void testAddTwoItems() { Cart instance = new Cart(); boolean isInStock = true; //First add an item Item item = new Item(); item.setItemId(&quot;item01&quot;); instance.addItem(item, isInStock); //Test adding a second item Item item2 = new Item(); item2.setItemId(&quot;item02&quot;); instance.addItem(item2, isInStock); //Check whether item01 is in the cart boolean result = instance.containsItemId(&quot;item01&quot;); assertTrue(&quot;First item is in cart&quot;, result); //Check whether item02 is in the cart result = instance.containsItemId(&quot;item02&quot;); assertTrue(&quot;Second item is in cart&quot;, result); //Check that there are 2 items in the cart assertEquals(&quot;2 items in cart&quot;, instance.getNumberOfItems(), 2); } USE CASE TEst
  • 16. Introducing JUnit public void testAddNullItem() { Cart instance = new Cart(); boolean isInStock = true; try { instance.addItem(null, isInStock); fail(&quot;Adding a null item did not throw an exception&quot;); } catch (RuntimeException expected) { assertTrue(&quot;null Item caught&quot;,true); assertEquals(&quot;Null not in cart&quot;, instance.getNumberOfItems(), 0); } } ABUSE CASE TEST
  • 17. Introducing JUnit Using JUnit Supported in all Java IDE’s Ant and Maven support Part of the code-debug cycle
  • 18. Introducing JUnit Other Unit testing frameworks Java – JUnit, ( www.junit.org ), TestNG ( http:// beust.com/testng / ), JTiger (www.jtiger.org) Microsoft .NET – NUnit ( www.nunit.org ), .NETUnit ( http:// sourceforge.net/projects/dotnetunit / ), ASPUnit ( http:// aspunit.sourceforge.net / ), CSUnit ( www.csunit.org ) and MS Visual Studio Team Edition and many more. PHP – PHPUnit ( http:// pear.php.net/package/PHPUnit ), SimpleTest ( www.simpletest.org ) Coldfusion – CFUnit ( http:// cfunit.sf.net ), cfcUnit ( www.cfcunit.org ) Perl – PerlUnit ( http:// perlunit.sf.net ), Test::More (included with Perl) Python – PyUnit ( http:// pyunit.sf.net ), doctest (included in standard library) Ruby – Test::Unit (included in the standard library) C – CUnit ( http:// cunit.sf.net ), check ( http:// check.sf.net ) C++ – CPPUnit ( http:// cppunit.sf.net ), cxxtest ( http:// cxxtest.sf.net )
  • 19. Web Application Security Standards What is a Web Application Security Standard? Derived from an organisation’s Security Policy Similar to an Operating System Build Standard Defines how the application should behave from a security point of view Should include functional and non-functional security aspects
  • 20. Web Application Security Standards Example:
  • 22. Testing Security in Unit Tests Test Valid Input public void testValidPhoneNumbers() { //Test valid input String number = &quot;232321&quot;; acc.setPhone(number); validator.validate(acc, errors); assertFalse(number+&quot; caused a validation error.&quot;, errors.hasFieldErrors(&quot;phone&quot;)); number = &quot;+23 232321&quot;; acc.setPhone(number); validator.validate(acc, errors); assertFalse(number+&quot; caused a validation error.&quot;, errors.hasFieldErrors(&quot;phone&quot;)); number = &quot;(44) 32321&quot;; acc.setPhone(number); validator.validate(acc, errors); assertFalse(number+&quot; caused a validation error.&quot;, errors.hasFieldErrors(&quot;phone&quot;)); //etc… }
  • 23. Testing Security in Unit Tests Test Invalid Input: public void testIllegalCharactersInPhoneNumber() { String number = &quot;+(23)';[]232 - 321&quot;; acc.setPhone(number); validator.validate(acc, errors); assertTrue(number+&quot; did not cause a validation error.&quot;, errors.hasFieldErrors(&quot;phone&quot;)); } public void testAlphabeticInPhoneNumber() { String number = &quot;12a12121&quot;; acc.setPhone(number); validator.validate(acc, errors); assertTrue(number+&quot; did not cause a validation error.&quot;, errors.hasFieldErrors(&quot;phone&quot;)); }
  • 24. Testing Security in Unit Tests Advantages of testing at this layer Tests are run very frequently - issues are identified quickly Most granular form of test - high test coverage Disadvantages Not many security vulnerabilities can be tested at this layer
  • 25. Testing Security in Integration Tests In-container testing Realistic and complete Requires specific tools Overhead in starting container Mock Objects Server API is faked Generic solution No container overhead
  • 26. Testing Security in Integration Tests In-container testing with Apache Cactus Popular tool for testing J2EE applications Can test EJB and Web tiers Plugin’s for Jetty, Eclipse, Ant and Maven
  • 27. Testing Security in Integration Tests Lifecycle of a single cactus test beginXXX() - setup the client side setUp() - common server side code testXXX() - server side test tearDown() - common server side code endXXX() - client side tests
  • 28. Testing Security in Integration Tests public class TestAccessControl extends ServletTestCase { public void beginUnprivilegedUserAccessControl(WebRequest theRequest) { theRequest.setAuthentication(new BasicAuthentication(&quot;user&quot;, &quot;password&quot;)); } public void testUnprivilegedUserAccessControl() throws IOException, javax.servlet.ServletException { AdminServlet admin = new AdminServlet(); admin.doGet(request, response); } public void endUnprivilegedUserAccessControl(WebResponse theResponse) throws IOException { assertTrue(&quot;Normal users must not be able to access /admin&quot;, theResponse.getStatusCode() == 401) } }
  • 29. Testing Security in Integration Tests Advantages of testing at this layer Can test in the application server Many security vulnerabilities can be tested, e.g.: Injection, Authentication flaws and Authorisation flaws. Disadvantages Not executed as often as unit tests Overhead of starting an application server Some vulnerabilities may not be easily testable, e.g.: XSS, URL filtering performed by a web server or application firewall.
  • 30. Security Testing in Acceptance Tests Tests the external API Language agnostic 2 types of tools: Include their own HTTP client and HTML parser, e.g.: HTTPUnit, jWebUnit, HtmlUnit, Canoo Webtest Drive a browser instance, e.g.: Selenium, WATIR, Watij
  • 31. Security Testing in Acceptance Tests Example: Testing HTML injection with jWebUnit public class XSSinSearchFieldTest extends WebTestCase { public void setUp() throws Exception { getTestContext().setBaseUrl(&quot;http://example.corsaire.com/ispatula/&quot;); } public void testHtmlInjection() throws Exception { beginAt(&quot;/index.html&quot;); assertLinkPresentWithText(&quot;Enter the Store&quot;); clickLinkWithText(&quot;Enter the Store&quot;); assertFormPresent(&quot;searchForm&quot;); setFormElement(&quot;query&quot;, &quot;<a id=amp;quot;injectionamp;quot; href=amp;quot;http://www.google.com>Injection</a>&quot;); submit(); assertLinkNotPresent(&quot;injection&quot;); } public XSSinSearchFieldTest(String name) { super(name); } }
  • 32. Security Testing in Acceptance Tests
  • 33. Security Testing in Acceptance Tests Example: Testing SQL injection with WATIR class SQL_Injection_Test < Test::Unit::TestCase include Watir def test_SQL_Blind_Injection_in_Login() $ie.goto('http://localhost:8080/ispatula') $ie.link(:url, /signonForm.do/).click $ie.text_field(:name, 'username').set('corsaire1apos; OR 1=1--') $ie.form(:action, &quot;/ispatula/shop/signon.do&quot;).submit assert($ie.contains_text('Signon failed')); end # Snip setup code end
  • 34. Security Testing in Acceptance Tests Example: Testing XSS with WATIR def test_XSS_In_Search $ie.goto('http://example.corsaire.com/ispatula/shop/index.do') $ie.text_field(:name, 'query').set('<script> window.open(&quot;http://example.corsaire.com/ispatula/help.html&quot;)</script>') $ie.form(:action, /Search.do/).submit assert_raises(Watir::Exception::NoMatchingWindowFoundException, &quot;Search field is susceptible to XSS&quot;) { ie2 = Watir::IE.attach(:url, &quot;http://example.corsaire.com/ispatula/help.html&quot;) } end
  • 35. Security Testing in Acceptance Tests Advantages of testing at this layer Full testing of external API Security consultants can use tools to script vulnerabilities Documents vulnerabilities Easy retesting Disadvantages Low test coverage Developers aren’t involved in testing
  • 36. Conclusions Existing testing tools and techniques can be used for security testing in the development lifecycle Developer training in security is a good investment! Security issues are identified early Code is subject to deep testing Compliance with a Web App Security Standard can be demonstrated