Cracking the Code to Secure Software

A presentation at Devoxx Poland 2017 in June 2017 in Kraków, Poland by Daniel Sawano

Slide 1

Slide 1

@ DanielDeogun @DanielSawano #D evoxxPL Platinum Sponsor: Cracking the Code to Secure Software Daniel Deogun & Daniel Sawano

Slide 2

Slide 2

@ DanielDeogun @DanielSawano #D evoxxPL Daniel Deogun Daniel Sawano

Slide 3

Slide 3

@ DanielDeogun @DanielSawano #D evoxxPL Secure by Design Secure by Design is a new approach to software security that lets you create secure software while still focusing on business features.

Slide 4

Slide 4

@ DanielDeogun @DanielSawano #D evoxxPL Secure by Design “Any activity involving active decision making should be considered part of the software design process and can thus be referred to as design .”

  • Johnsson, Deogun, and Sawano

Slide 5

Slide 5

@ DanielDeogun @DanielSawano #D evoxxPL Key Takeaway By focusing on good design principles you can create secure software without constantly thinking about security.

Slide 6

Slide 6

@ DanielDeogun @DanielSawano #D evoxxPL • Domain Primitives • Entity Snapshots • Dealing with Legacy Code • Security in your Delivery Pipeline • Domain DoS Attacks What we’ll cover today… Design patterns Security & tests Upcoming threat

Slide 7

Slide 7

@ DanielDeogun @DanielSawano #D evoxxPL Domain Primitives A value object so precise in its definition that it, by its mere existence, manifests its validity is called a domain primitive .

Slide 8

Slide 8

@ DanielDeogun @DanielSawano #D evoxxPL • A Domain Primitive is very strict in its definition • If it’s not valid then it cannot exist • Defined in the current domain • It’s preciseness brings robustness in your code • It’s immutable so it will always be valid Domain Primitives

Slide 9

Slide 9

@ DanielDeogun @DanielSawano #D evoxxPL Domain Primitives import static org.apache.commons.lang3.Validate.inclusiveBetween; import static org.apache.commons.lang3.Validate.notNull; public final class Quantity { private final int value; public Quantity(final int value) { inclusiveBetween(1, 200, value); this.value = value;

} public int value() { return value;

} public Quantity add(final Quantity addend) { notNull(addend); return new Quantity(value + addend.value); } // ... } Quantity is not just an int! • Enforces invariants at creation • Provides domain operations to • Encapsulate domain behavior

Slide 10

Slide 10

@ DanielDeogun @DanielSawano #D evoxxPL • Confidentiality

  • protecting data from being read by unauthorized users • Integrity
  • ensures data is changed in an authorized way • Availability
  • concerns having data available when authorized users need it CIA [11] Not this

Slide 11

Slide 11

@ DanielDeogun @DanielSawano #D evoxxPL Domain Primitives import static org.apache.commons.lang3.Validate.inclusiveBetween; import static org.apache.commons.lang3.Validate.notNull; public final class Quantity { private final int value; public Quantity(final int value) { inclusiveBetween(1, 200, value); this.value = value;

} public int value() { return value;

} public Quantity add(final Quantity addend) { notNull(addend); return new Quantity(value + addend.value); } // ... } Quantity is not just an int! • Enforces invariants at creation • Provides domain operations to • Encapsulate domain behavior

Slide 12

Slide 12

@ DanielDeogun @DanielSawano #D evoxxPL Domain Primitives External context Your context Email Email Defined by RFC Defined by you

Slide 13

Slide 13

@ DanielDeogun @DanielSawano #D evoxxPL Use Domain Primitives as: • the smallest building block in your domain model • to build your Domain Primitive Library • to harden your code and your APIs Domain Primitives

Slide 14

Slide 14

@ DanielDeogun @DanielSawano #D evoxxPL ✓ Domain Primitives • Entity Snapshots • Dealing with Legacy Code • Security in your Delivery Pipeline • Domain DoS Attacks What we’ll cover today… Design patterns Security & tests Upcoming threat

Slide 15

Slide 15

@ DanielDeogun @DanielSawano #D evoxxPL • An entity has an identity that doesn’t change over time • The values/data belonging to an entity can change over time • Typically modeled as mutable objects Entities

Slide 16

Slide 16

@ DanielDeogun @DanielSawano #D evoxxPL Classic Entity public final class Order { private final OrderId id; private final List<OrderItem> orderItems = new ArrayList<>(); public Order(final OrderId id) { this.id = notNull(id); } public void addItem(final OrderItem item) { notNull(item); orderItems.add(item); }

// ... }

Slide 17

Slide 17

@ DanielDeogun @DanielSawano #D evoxxPL Entity Snapshots are: • Securing mutable state by making it immutable • An immutable representation of a mutable entity • Solves many of the security problems with regular entities Entity Snapshots

Slide 18

Slide 18

@ DanielDeogun @DanielSawano #D evoxxPL Entity Snapshots public final class Order { private final OrderId id; private final List<OrderItem> orderItems; public Order(final OrderId id, final List<OrderItem> orderItems) { noNullElements(orderItems); notNull(id); this.id = id; this.orderItems = unmodifiableList(new ArrayList<>(orderItems)); } public List<OrderItem> orderItems() { return orderItems; } // ... }

Slide 19

Slide 19

@ DanielDeogun @DanielSawano #D evoxxPL Entity Snapshots public final class WritableOrder { private final OrderId id; private final OrderRepository repository; public WritableOrder(final OrderId id, final OrderRepository repository) { this.id = notNull(id); this.repository = notNull(repository); } public void addOrderItem(final OrderItem orderItem) { notNull(orderItem); isOkToAdd(orderItem); repository.addItemToOrder(id, orderItem); } private void isOkToAdd(final OrderItem orderItem) { // domain validation logic to ensure it's ok to add order } }

Slide 20

Slide 20

@ DanielDeogun @DanielSawano #D evoxxPL ✓ Domain Primitives ✓ Entity Snapshots • Dealing with Legacy Code • Security in your Delivery Pipeline • Domain DoS Attacks What we’ll cover today… Design patterns Security & tests Upcoming threat

Slide 21

Slide 21

@ DanielDeogun @DanielSawano #D evoxxPL Dealing with Legacy Code [6] Declutter Entities Harden your APIs Draw the Line [7] [8] 3 good design patterns

Slide 22

Slide 22

@ DanielDeogun @DanielSawano #D evoxxPL • We need to identify the semantic boundary of a context • Add a layer that internally translates data to a domain primitive and then back again

data -> domain primitive -> data • This way, we have created a validation boundary that protects the inside from bad input • But, if rejecting data is to harsh, consider logging it for insight Draw the Line [6]

Slide 23

Slide 23

@ DanielDeogun @DanielSawano #D evoxxPL • Create a library of domain primitives • Express your APIs with your domain primitives • Never accept generic input if you have specific requirements Harden the API Generic Specific [7] void buyBook(ISBN, Quantity) void buyBook(String, int)

Slide 24

Slide 24

@ DanielDeogun @DanielSawano #D evoxxPL Decluttering Entities [8] import static org.apache.commons.lang3.Validate.notNull; import static org.apache.commons.lang3.Validate.isTrue; public class Order { 
 
 private final List<Object> items; 
 private boolean paid; 
 
 public void addItem(String isbn, int qty) { 
 if (this.paid == false) { 
 notNull(isbn); 
 isTrue(isbn.length() == 10); 
 isTrue(isbn.matches("[0-9X]*")); 
 isTrue(isbn.matches(“[0-9]{9}[0-9X]”)); if (inventory.avaliableBooks(isbn, qty)) {

Book book = bookcatalogue.findBy(isbn); 
 items.add(new OrderLine(book, qty)); 
 } 
 } 
 }

Slide 25

Slide 25

@ DanielDeogun @DanielSawano #D evoxxPL Decluttering Entities [8] import static org.apache.commons.lang3.Validate.notNull; import static org.apache.commons.lang3.Validate.isTrue; public class Order { 
 
 private final List<Object> items; 
 private boolean paid; 
 
 public void addItem(final ISBN isbn, final Quantity quantity) { notNull(isbn); notNull(quantity); isTrue(notPaid());

    if (inventory.avaliableBooks(isbn, quantity)) {
        Book book = bookcatalogue.findBy(isbn);


 items.add(new OrderLine(book, quantity)); 
 } 
 }

Slide 26

Slide 26

@ DanielDeogun @DanielSawano #D evoxxPL ✓ Domain Primitives ✓ Entity Snapshots ✓ Dealing with Legacy Code • Security in your Delivery Pipeline • Domain DoS Attacks What we’ll cover today… Design patterns Security & tests Upcoming threat

Slide 27

Slide 27

@ DanielDeogun @DanielSawano #D evoxxPL Security in your Delivery Pipeline [10] [12]

  • Unit Testing

Slide 28

Slide 28

@ DanielDeogun @DanielSawano #D evoxxPL The Hospital Case [9]

Slide 29

Slide 29

@ DanielDeogun @DanielSawano #D evoxxPL Email Domain Primitive External context Your context Email Email Defined by RFC Defined by you

Slide 30

Slide 30

@ DanielDeogun @DanielSawano #D evoxxPL Normal & Boundary Testing Normal Boundary Tests with i nput that clearly meets the domain rules Tests that verify behavior around the boundary

Slide 31

Slide 31

@ DanielDeogun @DanielSawano #D evoxxPL Email Address v1.0 public final class EmailAddress { public final String value; public EmailAddress(final String value) {

matchesPattern (value.toLowerCase(), "^(?=[a-z0-9.@]{15,77}$) [a-z0-9]+\.?[a-z0-9]+@\bhospital.com$"); this.value = value.toLowerCase(); } ... }

Slide 32

Slide 32

@ DanielDeogun @DanielSawano #D evoxxPL Invalid Input Testing • Any input that doesn't satisfy the domain rules is considered invalid • For some reason, null, empty strings, or "strange" characters tend to result in unexpected behavior

Slide 33

Slide 33

@ DanielDeogun @DanielSawano #D evoxxPL Testing with invalid input @TestFactory Stream<DynamicTest> should_reject_invalid_input() { return Stream.of( null,
"null",
"nil",
"0",
"",
" ",
" ",
" ",
"john.doe @hospital.com",
" @hospital.com",
"%20@hospital.com",
"john.d%20e@hospital.com",
"john.doe.jane@hospital.com",
"--",
"e x a m p l e @ hospital . c o m",
"=0@$*^%;<!->.:\()&#"") .map(input -> dynamicTest("Rejected: " + input, assertInvalidEmail(input))); }

Slide 34

Slide 34

@ DanielDeogun @DanielSawano #D evoxxPL Email Address v2.0 public final class EmailAddress { public final String value; public EmailAddress(final String value) {

notNull(value, "Input cannot be null");

matchesPattern (value.toLowerCase(), "^(?=[a-z0-9.@]{15,77}$) [a-z0-9]+\.?[a-z0-9]+@\bhospital.com$"); this.value = value.toLowerCase(); } ... }

Slide 35

Slide 35

@ DanielDeogun @DanielSawano #D evoxxPL Testing with Extreme Input • Testing the extreme is all about identifying weaknesses in the design that makes the application break or behave strangely when handling extreme values. @TestFactory Stream<DynamicTest> should_reject_extreme_input() { return Stream.<Supplier<String>>of( () -> repeat("x ", 10000),
() -> repeat("x ", 100000),
() -> repeat("x ", 1000000),
() -> repeat("x ", 10000000), () -> repeat("x ", 20000000),
() -> repeat("x ", 40000000)) .map(input -> dynamicTest("Rejecting extreme input", assertInvalidEmail(input.get()))); }

Slide 36

Slide 36

@ DanielDeogun @DanielSawano #D evoxxPL Inefficient Backtracking v.s "^ (?=[a-z0-9.@]{15,77}$) [a-z0-9]+\.?[a-z0-9]+@\bhospital.com$" “^ [a-z0-9]+\.?[a-z0-9]+@\bhospital.com$"

Slide 37

Slide 37

@ DanielDeogun @DanielSawano #D evoxxPL ✓ Domain Primitives ✓ Entity Snapshots ✓ Dealing with Legacy Code ✓ Security in your Delivery Pipeline • Domain DoS Attacks What we’ll cover today… Design patterns Security & tests Upcoming threat

Slide 38

Slide 38

@ DanielDeogun @DanielSawano #D evoxxPL • The main objective of a DoS attack is to prevent availability of a system’s services • A DoS attack doesn’t require heavy load to be successful (asymmetric) DoS Attacks

Slide 39

Slide 39

@ DanielDeogun @DanielSawano #D evoxxPL Domain DoS Attacks A DoS attack caused by utilizing domain rules in a malicious way is called a Domain DoS

Slide 40

Slide 40

@ DanielDeogun @DanielSawano #D evoxxPL We need great customer service! Domain DoS Example - The Hotel Full refund if cancelled before 4 p.m. Book all empty rooms No rooms available for ordinary customers [9]

Slide 41

Slide 41

@ DanielDeogun @DanielSawano #D evoxxPL Uber vs Ola [4]

Slide 42

Slide 42

@ DanielDeogun @DanielSawano #D evoxxPL Lyft vs Uber [5]

Slide 43

Slide 43

@ DanielDeogun @DanielSawano #D evoxxPL Key Takeaway By focusing on good design principles you can create secure software without constantly thinking about security.

Slide 44

Slide 44

@ DanielDeogun @DanielSawano #D evoxxPL Questions & More [2] URL: http://bit.ly/secure-by-design Discount code: ctwdevoxxpl17 (40% off) Want a free ebook? Catch us in the break!

Slide 45

Slide 45

@ DanielDeogun @DanielSawano #D evoxxPL [1] https://www.flickr.com/photos/stewart/461099066 by Stewart Butterfield under license https://creativecommons.org/licenses/by/2.0/ [2] https://flic.kr/p/9ksxQa by Damián Navas under license https://creativecommons.org/licenses/by-nc-nd/2.0/ [3] https://flic.kr/p/nEZKMd by Graeme Fowler under license https://creativecommons.org/licenses/by/2.0/ [4] Uber vs Ola, https://www.bloomberg.com/news/articles/2016-03-23/uber-sues-ola-claiming-fake-bookings-as-india-fight-escalates [5] Lyft vs Uber, http://time.com/3102548/lyft-uber-cancelling-rides/ [6] 3d key, https://flic.kr/p/e9qfrf by Yoel Ben-Avraham under license https://creativecommons.org/licenses/by-nd/2.0/ [7] Building blocks, https://flic.kr/p/agPw7C by Tiffany Terry under license https://creativecommons.org/licenses/by/2.0/ [8] Doctors Stock Photo, https://flic.kr/p/HNJUzV, by Sergio Santos under license https://creativecommons.org/licenses/by/2.0/ [9] “Anonymous” - Icon made by Egor Rumyantsev from   www.flaticon.com - CC 3.0 References