JFALL 2016 In depth: secure coding patterns

After we find a bug in our code, we as developers reason about our code and question ourselves: did we have Unit Tests and Integration Tests, Design Patterns, Clean Code and Logging. What are their equivalents for security bugs and vulnerabilities, and how can we reason about them?

Slides are available at: How We Hacked LinkedIn and What Happened Next | JFall 2016 from Ruben van Vreeland

So, lets start with one the most commonly found class of vulnerabilities in code: missing validation. Just like with regular bugs, you, your co-worker or penetration tester might find this bug.

    @Controller
    public class TestController {
        @RequestMapping(value = "/validBody")

Missing the @Valid annotation

        public String addFromBody(@RequestBody Tweet tweet) {

            logger.debug("Received dto from body");
            return "index";
        }
    }

This method is clearly missing the @Valid annotation. We have to add it to patch this method.

    @Controller
    public class TestController {
        @RequestMapping(value = "/validBody")

Added the @Valid annotation that let Spring do the validation.

        public String addFromBody(@RequestBody Tweet tweet) {

            logger.debug("Received dto from body");
            return "index";
        }
    }

Added validation to the class using @Annotations

    class Tweet {
        @NotEmpty

        @Length(max = 140)
        private String text;

        public Tweet() {
        }

        public String getText() {
            return text;

        }
        public void setText(String text) {

        this.text = text;
        }
    }

Usually we just patch this up an move along… until we just find another validation bug again. And again.

When we find a bug in an application’s source code, after fixing it we’re checking the tests. Let’s do the same with this security bug and add tests around it’s methods to make sure it never happens again.

    public class BeanValidationTest extends TestSupport.IntegrationTestSupport {

This should validate.

        @Test
        public void validationExceptionTest() {
            new RestTemplate().getForObject(uri + "/valid" + "?text=bar", String.class);
        }

This should throw a 4xx response code.

        @Test(expected = HttpClientErrorException.class)
        public void validationExceptionTestShouldThrow() {

            new RestTemplate().getForObject(uri + "/valid" + "?text=", String.class);
        }
    }

With these tests added, we’re safe in every future release of our code.