SlideShare a Scribd company logo
@DanielDeogun @DanielSawano#DevoxxPL
Platinum Sponsor:
Cracking the Code
to Secure Software
Daniel Deogun & Daniel Sawano
@DanielDeogun @DanielSawano #DevoxxPL
Daniel Deogun Daniel Sawano
@DanielDeogun @DanielSawano #DevoxxPL
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.
@DanielDeogun @DanielSawano #DevoxxPL
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
@DanielDeogun @DanielSawano #DevoxxPL
Key Takeaway
By focusing on good design principles you
can create secure software without constantly
thinking about security.
@DanielDeogun @DanielSawano #DevoxxPL
• 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
@DanielDeogun @DanielSawano #DevoxxPL
Domain Primitives
A value object so precise in its definition that
it, by its mere existence, manifests its validity
is called a domain primitive.
@DanielDeogun @DanielSawano #DevoxxPL
• 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
@DanielDeogun @DanielSawano #DevoxxPL
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
@DanielDeogun @DanielSawano #DevoxxPL
• 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
@DanielDeogun @DanielSawano #DevoxxPL
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
@DanielDeogun @DanielSawano #DevoxxPL
Domain Primitives
External context
Your context
Email
Email
Defined by RFC
Defined by you
@DanielDeogun @DanielSawano #DevoxxPL
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
@DanielDeogun @DanielSawano #DevoxxPL
✓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
@DanielDeogun @DanielSawano #DevoxxPL
• 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
@DanielDeogun @DanielSawano #DevoxxPL
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);
}
// ...
}
@DanielDeogun @DanielSawano #DevoxxPL
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
@DanielDeogun @DanielSawano #DevoxxPL
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;
}
// ...
}
@DanielDeogun @DanielSawano #DevoxxPL
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
}
}
@DanielDeogun @DanielSawano #DevoxxPL
✓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
@DanielDeogun @DanielSawano #DevoxxPL
Dealing with Legacy Code
[6]
Declutter EntitiesHarden your APIsDraw the Line
[7] [8]
3 good design patterns
@DanielDeogun @DanielSawano #DevoxxPL
• 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]
@DanielDeogun @DanielSawano #DevoxxPL
• 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)
@DanielDeogun @DanielSawano #DevoxxPL
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));

}

}

}
@DanielDeogun @DanielSawano #DevoxxPL
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));

}

}
@DanielDeogun @DanielSawano #DevoxxPL
✓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
@DanielDeogun @DanielSawano #DevoxxPL
Security in your Delivery Pipeline
[10][12]
- Unit Testing
@DanielDeogun @DanielSawano #DevoxxPL
The Hospital Case
[9]
@DanielDeogun @DanielSawano #DevoxxPL
Email Domain Primitive
External context
Your context
Email
Email
Defined by RFC
Defined by you
@DanielDeogun @DanielSawano #DevoxxPL
Normal & Boundary Testing
Normal
Boundary
Tests with input that clearly
meets the domain rules
Tests that verify behavior
around the boundary
@DanielDeogun @DanielSawano #DevoxxPL
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();
}
...
}
@DanielDeogun @DanielSawano #DevoxxPL
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
@DanielDeogun @DanielSawano #DevoxxPL
Testing with invalid input
@TestFactory
Stream<DynamicTest> should_reject_invalid_input() {
return Stream.of(
null,
"null",
"nil",
"0",
"",
" ",
"t",
"n",
"john.doen@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)));
}
@DanielDeogun @DanielSawano #DevoxxPL
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();
}
...
}
@DanielDeogun @DanielSawano #DevoxxPL
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())));
}
@DanielDeogun @DanielSawano #DevoxxPL
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$"
@DanielDeogun @DanielSawano #DevoxxPL
✓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
@DanielDeogun @DanielSawano #DevoxxPL
• 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
@DanielDeogun @DanielSawano #DevoxxPL
Domain DoS Attacks
A DoS attack caused by utilizing
domain rules in a malicious way is
called a Domain DoS
@DanielDeogun @DanielSawano #DevoxxPL
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]
@DanielDeogun @DanielSawano #DevoxxPL
Uber vs Ola
[4]
@DanielDeogun @DanielSawano #DevoxxPL
Lyft vs Uber
[5]
@DanielDeogun @DanielSawano #DevoxxPL
Key Takeaway
By focusing on good design principles you
can create secure software without constantly
thinking about security.
@DanielDeogun @DanielSawano #DevoxxPL
Questions & More
[2]
URL: http://bit.ly/secure-by-design
Discount code: ctwdevoxxpl17 (40% off)
Want a free ebook?
Catch us in the
break!
@DanielDeogun @DanielSawano #DevoxxPL
[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 byYoel 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

More Related Content

Similar to Devoxx PL 2017 - Cracking the Code to Secure Software

DevDays LT 2017 - Secure by Design
DevDays LT 2017 - Secure by DesignDevDays LT 2017 - Secure by Design
DevDays LT 2017 - Secure by DesignDaniel Sawano
 
Domain Primitives In Action - Explore DDD 2017
Domain Primitives In Action - Explore DDD 2017Domain Primitives In Action - Explore DDD 2017
Domain Primitives In Action - Explore DDD 2017Omegapoint Academy
 
GeeCon Prague 2017 - Cracking the Code to Secure Software
GeeCon Prague 2017 - Cracking the Code to Secure SoftwareGeeCon Prague 2017 - Cracking the Code to Secure Software
GeeCon Prague 2017 - Cracking the Code to Secure SoftwareDaniel Sawano
 
NoSQL Endgame JCON Conference 2020
NoSQL Endgame JCON Conference 2020NoSQL Endgame JCON Conference 2020
NoSQL Endgame JCON Conference 2020Thodoris Bais
 
Fighting security trolls_with_high-quality_mindsets
Fighting security trolls_with_high-quality_mindsetsFighting security trolls_with_high-quality_mindsets
Fighting security trolls_with_high-quality_mindsetsddeogun
 
Domain Primitives in Action - DataTjej 2018
Domain Primitives in Action - DataTjej 2018Domain Primitives in Action - DataTjej 2018
Domain Primitives in Action - DataTjej 2018Omegapoint Academy
 
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?Trisha Gee
 
10.Local Database & LINQ
10.Local Database & LINQ10.Local Database & LINQ
10.Local Database & LINQNguyen Tuan
 
EclipseCon 2021 NoSQL Endgame
EclipseCon 2021 NoSQL EndgameEclipseCon 2021 NoSQL Endgame
EclipseCon 2021 NoSQL EndgameThodoris Bais
 
Eclipse JNoSQL: One API to Many NoSQL Databases - BYOL [HOL5998]
Eclipse JNoSQL: One API to Many NoSQL Databases - BYOL [HOL5998]Eclipse JNoSQL: One API to Many NoSQL Databases - BYOL [HOL5998]
Eclipse JNoSQL: One API to Many NoSQL Databases - BYOL [HOL5998]Otávio Santana
 
Unit Testing for Great Justice
Unit Testing for Great JusticeUnit Testing for Great Justice
Unit Testing for Great JusticeDomenic Denicola
 
NoSQL Endgame Percona Live Online 2020
NoSQL Endgame Percona Live Online 2020NoSQL Endgame Percona Live Online 2020
NoSQL Endgame Percona Live Online 2020Thodoris Bais
 
MongoDB .local London 2019: Realm: The Secret Sauce for Better Mobile Apps
MongoDB .local London 2019: Realm: The Secret Sauce for Better Mobile AppsMongoDB .local London 2019: Realm: The Secret Sauce for Better Mobile Apps
MongoDB .local London 2019: Realm: The Secret Sauce for Better Mobile AppsMongoDB
 
Lessons from the Trenches - Building Enterprise Applications with RavenDB
Lessons from the Trenches - Building Enterprise Applications with RavenDBLessons from the Trenches - Building Enterprise Applications with RavenDB
Lessons from the Trenches - Building Enterprise Applications with RavenDBOren Eini
 
How to use the new Domino Query Language
How to use the new Domino Query LanguageHow to use the new Domino Query Language
How to use the new Domino Query LanguageTim Davis
 
NoSQL Endgame DevoxxUA Conference 2020
NoSQL Endgame DevoxxUA Conference 2020NoSQL Endgame DevoxxUA Conference 2020
NoSQL Endgame DevoxxUA Conference 2020Thodoris Bais
 
Decomposing the Monolith using modern-day .NET and a touch of microservices
Decomposing the Monolith using modern-day .NET and a touch of microservicesDecomposing the Monolith using modern-day .NET and a touch of microservices
Decomposing the Monolith using modern-day .NET and a touch of microservicesDennis Doomen
 
JakartaData-JCon.pptx
JakartaData-JCon.pptxJakartaData-JCon.pptx
JakartaData-JCon.pptxEmilyJiang23
 

Similar to Devoxx PL 2017 - Cracking the Code to Secure Software (20)

DevDays LT 2017 - Secure by Design
DevDays LT 2017 - Secure by DesignDevDays LT 2017 - Secure by Design
DevDays LT 2017 - Secure by Design
 
Domain Primitives In Action - Explore DDD 2017
Domain Primitives In Action - Explore DDD 2017Domain Primitives In Action - Explore DDD 2017
Domain Primitives In Action - Explore DDD 2017
 
GeeCon Prague 2017 - Cracking the Code to Secure Software
GeeCon Prague 2017 - Cracking the Code to Secure SoftwareGeeCon Prague 2017 - Cracking the Code to Secure Software
GeeCon Prague 2017 - Cracking the Code to Secure Software
 
NoSQL Endgame JCON Conference 2020
NoSQL Endgame JCON Conference 2020NoSQL Endgame JCON Conference 2020
NoSQL Endgame JCON Conference 2020
 
Fighting security trolls_with_high-quality_mindsets
Fighting security trolls_with_high-quality_mindsetsFighting security trolls_with_high-quality_mindsets
Fighting security trolls_with_high-quality_mindsets
 
Domain Primitives in Action - DataTjej 2018
Domain Primitives in Action - DataTjej 2018Domain Primitives in Action - DataTjej 2018
Domain Primitives in Action - DataTjej 2018
 
Designing Testable Software
Designing Testable SoftwareDesigning Testable Software
Designing Testable Software
 
What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?What do you mean, Backwards Compatibility?
What do you mean, Backwards Compatibility?
 
10.Local Database & LINQ
10.Local Database & LINQ10.Local Database & LINQ
10.Local Database & LINQ
 
EclipseCon 2021 NoSQL Endgame
EclipseCon 2021 NoSQL EndgameEclipseCon 2021 NoSQL Endgame
EclipseCon 2021 NoSQL Endgame
 
Eclipse JNoSQL: One API to Many NoSQL Databases - BYOL [HOL5998]
Eclipse JNoSQL: One API to Many NoSQL Databases - BYOL [HOL5998]Eclipse JNoSQL: One API to Many NoSQL Databases - BYOL [HOL5998]
Eclipse JNoSQL: One API to Many NoSQL Databases - BYOL [HOL5998]
 
Unit Testing for Great Justice
Unit Testing for Great JusticeUnit Testing for Great Justice
Unit Testing for Great Justice
 
NoSQL Endgame Percona Live Online 2020
NoSQL Endgame Percona Live Online 2020NoSQL Endgame Percona Live Online 2020
NoSQL Endgame Percona Live Online 2020
 
MongoDB .local London 2019: Realm: The Secret Sauce for Better Mobile Apps
MongoDB .local London 2019: Realm: The Secret Sauce for Better Mobile AppsMongoDB .local London 2019: Realm: The Secret Sauce for Better Mobile Apps
MongoDB .local London 2019: Realm: The Secret Sauce for Better Mobile Apps
 
Real World MVC
Real World MVCReal World MVC
Real World MVC
 
Lessons from the Trenches - Building Enterprise Applications with RavenDB
Lessons from the Trenches - Building Enterprise Applications with RavenDBLessons from the Trenches - Building Enterprise Applications with RavenDB
Lessons from the Trenches - Building Enterprise Applications with RavenDB
 
How to use the new Domino Query Language
How to use the new Domino Query LanguageHow to use the new Domino Query Language
How to use the new Domino Query Language
 
NoSQL Endgame DevoxxUA Conference 2020
NoSQL Endgame DevoxxUA Conference 2020NoSQL Endgame DevoxxUA Conference 2020
NoSQL Endgame DevoxxUA Conference 2020
 
Decomposing the Monolith using modern-day .NET and a touch of microservices
Decomposing the Monolith using modern-day .NET and a touch of microservicesDecomposing the Monolith using modern-day .NET and a touch of microservices
Decomposing the Monolith using modern-day .NET and a touch of microservices
 
JakartaData-JCon.pptx
JakartaData-JCon.pptxJakartaData-JCon.pptx
JakartaData-JCon.pptx
 

More from Daniel Sawano

Devoxx PL 2016 - Beyond Lambdas, the Aftermath
Devoxx PL 2016 - Beyond Lambdas, the AftermathDevoxx PL 2016 - Beyond Lambdas, the Aftermath
Devoxx PL 2016 - Beyond Lambdas, the AftermathDaniel Sawano
 
GeeCon 2016 - Beyond Lambdas, the Aftermath
GeeCon 2016 - Beyond Lambdas, the AftermathGeeCon 2016 - Beyond Lambdas, the Aftermath
GeeCon 2016 - Beyond Lambdas, the AftermathDaniel Sawano
 
Spotify 2016 - Beyond Lambdas - the Aftermath
Spotify 2016 - Beyond Lambdas - the AftermathSpotify 2016 - Beyond Lambdas - the Aftermath
Spotify 2016 - Beyond Lambdas - the AftermathDaniel Sawano
 
JDays 2016 - Beyond Lambdas - the Aftermath
JDays 2016 - Beyond Lambdas - the AftermathJDays 2016 - Beyond Lambdas - the Aftermath
JDays 2016 - Beyond Lambdas - the AftermathDaniel Sawano
 
JFokus 2016 - Beyond Lambdas - the Aftermath
JFokus 2016 - Beyond Lambdas - the AftermathJFokus 2016 - Beyond Lambdas - the Aftermath
JFokus 2016 - Beyond Lambdas - the AftermathDaniel Sawano
 
Devoxx, MA, 2015, Failing Continuous Delivery
Devoxx, MA, 2015, Failing Continuous DeliveryDevoxx, MA, 2015, Failing Continuous Delivery
Devoxx, MA, 2015, Failing Continuous DeliveryDaniel Sawano
 
Failing Continuous Delivery, Agile Prague 2015
Failing Continuous Delivery, Agile Prague 2015Failing Continuous Delivery, Agile Prague 2015
Failing Continuous Delivery, Agile Prague 2015Daniel Sawano
 
Failing Continuous Delivery, Devoxx Poland, 2015
Failing Continuous Delivery, Devoxx Poland, 2015Failing Continuous Delivery, Devoxx Poland, 2015
Failing Continuous Delivery, Devoxx Poland, 2015Daniel Sawano
 
Things Every Professional Programmer Should Know
Things Every Professional Programmer Should KnowThings Every Professional Programmer Should Know
Things Every Professional Programmer Should KnowDaniel Sawano
 
Failing Continuous Delivery, JDays, 2015
Failing Continuous Delivery, JDays, 2015Failing Continuous Delivery, JDays, 2015
Failing Continuous Delivery, JDays, 2015Daniel Sawano
 
Reactive Programming With Akka - Lessons Learned
Reactive Programming With Akka - Lessons LearnedReactive Programming With Akka - Lessons Learned
Reactive Programming With Akka - Lessons LearnedDaniel Sawano
 

More from Daniel Sawano (12)

Devoxx PL 2016 - Beyond Lambdas, the Aftermath
Devoxx PL 2016 - Beyond Lambdas, the AftermathDevoxx PL 2016 - Beyond Lambdas, the Aftermath
Devoxx PL 2016 - Beyond Lambdas, the Aftermath
 
GeeCon 2016 - Beyond Lambdas, the Aftermath
GeeCon 2016 - Beyond Lambdas, the AftermathGeeCon 2016 - Beyond Lambdas, the Aftermath
GeeCon 2016 - Beyond Lambdas, the Aftermath
 
Spotify 2016 - Beyond Lambdas - the Aftermath
Spotify 2016 - Beyond Lambdas - the AftermathSpotify 2016 - Beyond Lambdas - the Aftermath
Spotify 2016 - Beyond Lambdas - the Aftermath
 
JDays 2016 - Beyond Lambdas - the Aftermath
JDays 2016 - Beyond Lambdas - the AftermathJDays 2016 - Beyond Lambdas - the Aftermath
JDays 2016 - Beyond Lambdas - the Aftermath
 
JFokus 2016 - Beyond Lambdas - the Aftermath
JFokus 2016 - Beyond Lambdas - the AftermathJFokus 2016 - Beyond Lambdas - the Aftermath
JFokus 2016 - Beyond Lambdas - the Aftermath
 
Devoxx, MA, 2015, Failing Continuous Delivery
Devoxx, MA, 2015, Failing Continuous DeliveryDevoxx, MA, 2015, Failing Continuous Delivery
Devoxx, MA, 2015, Failing Continuous Delivery
 
Failing Continuous Delivery, Agile Prague 2015
Failing Continuous Delivery, Agile Prague 2015Failing Continuous Delivery, Agile Prague 2015
Failing Continuous Delivery, Agile Prague 2015
 
Failing Continuous Delivery, Devoxx Poland, 2015
Failing Continuous Delivery, Devoxx Poland, 2015Failing Continuous Delivery, Devoxx Poland, 2015
Failing Continuous Delivery, Devoxx Poland, 2015
 
Things Every Professional Programmer Should Know
Things Every Professional Programmer Should KnowThings Every Professional Programmer Should Know
Things Every Professional Programmer Should Know
 
Failing Continuous Delivery, JDays, 2015
Failing Continuous Delivery, JDays, 2015Failing Continuous Delivery, JDays, 2015
Failing Continuous Delivery, JDays, 2015
 
Akka Made Our Day
Akka Made Our DayAkka Made Our Day
Akka Made Our Day
 
Reactive Programming With Akka - Lessons Learned
Reactive Programming With Akka - Lessons LearnedReactive Programming With Akka - Lessons Learned
Reactive Programming With Akka - Lessons Learned
 

Recently uploaded

iGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by SkilrockiGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by SkilrockSkilrock Technologies
 
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownloadvrstrong314
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEJelle | Nordend
 
Advanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowAdvanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowPeter Caitens
 
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1KnowledgeSeed
 
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...Alluxio, Inc.
 
Crafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM IntegrationCrafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM IntegrationWave PLM
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Anthony Dahanne
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyanic lab
 
GraphAware - Transforming policing with graph-based intelligence analysis
GraphAware - Transforming policing with graph-based intelligence analysisGraphAware - Transforming policing with graph-based intelligence analysis
GraphAware - Transforming policing with graph-based intelligence analysisNeo4j
 
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAGAI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAGAlluxio, Inc.
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamtakuyayamamoto1800
 
Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesKrzysztofKkol1
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfOrtus Solutions, Corp
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessWSO2
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke
 
AI/ML Infra Meetup | ML explainability in Michelangelo
AI/ML Infra Meetup | ML explainability in MichelangeloAI/ML Infra Meetup | ML explainability in Michelangelo
AI/ML Infra Meetup | ML explainability in MichelangeloAlluxio, Inc.
 

Recently uploaded (20)

iGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by SkilrockiGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by Skilrock
 
Top Mobile App Development Companies 2024
Top Mobile App Development Companies 2024Top Mobile App Development Companies 2024
Top Mobile App Development Companies 2024
 
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBroker
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
 
Advanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowAdvanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should Know
 
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
 
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
 
Crafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM IntegrationCrafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM Integration
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
 
GraphAware - Transforming policing with graph-based intelligence analysis
GraphAware - Transforming policing with graph-based intelligence analysisGraphAware - Transforming policing with graph-based intelligence analysis
GraphAware - Transforming policing with graph-based intelligence analysis
 
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAGAI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
 
Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web Services
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
AI/ML Infra Meetup | ML explainability in Michelangelo
AI/ML Infra Meetup | ML explainability in MichelangeloAI/ML Infra Meetup | ML explainability in Michelangelo
AI/ML Infra Meetup | ML explainability in Michelangelo
 

Devoxx PL 2017 - Cracking the Code to Secure Software

  • 1. @DanielDeogun @DanielSawano#DevoxxPL Platinum Sponsor: Cracking the Code to Secure Software Daniel Deogun & Daniel Sawano
  • 3. @DanielDeogun @DanielSawano #DevoxxPL 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.
  • 4. @DanielDeogun @DanielSawano #DevoxxPL 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
  • 5. @DanielDeogun @DanielSawano #DevoxxPL Key Takeaway By focusing on good design principles you can create secure software without constantly thinking about security.
  • 6. @DanielDeogun @DanielSawano #DevoxxPL • 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
  • 7. @DanielDeogun @DanielSawano #DevoxxPL Domain Primitives A value object so precise in its definition that it, by its mere existence, manifests its validity is called a domain primitive.
  • 8. @DanielDeogun @DanielSawano #DevoxxPL • 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
  • 9. @DanielDeogun @DanielSawano #DevoxxPL 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
  • 10. @DanielDeogun @DanielSawano #DevoxxPL • 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
  • 11. @DanielDeogun @DanielSawano #DevoxxPL 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
  • 12. @DanielDeogun @DanielSawano #DevoxxPL Domain Primitives External context Your context Email Email Defined by RFC Defined by you
  • 13. @DanielDeogun @DanielSawano #DevoxxPL 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
  • 14. @DanielDeogun @DanielSawano #DevoxxPL ✓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
  • 15. @DanielDeogun @DanielSawano #DevoxxPL • 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
  • 16. @DanielDeogun @DanielSawano #DevoxxPL 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); } // ... }
  • 17. @DanielDeogun @DanielSawano #DevoxxPL 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
  • 18. @DanielDeogun @DanielSawano #DevoxxPL 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; } // ... }
  • 19. @DanielDeogun @DanielSawano #DevoxxPL 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 } }
  • 20. @DanielDeogun @DanielSawano #DevoxxPL ✓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
  • 21. @DanielDeogun @DanielSawano #DevoxxPL Dealing with Legacy Code [6] Declutter EntitiesHarden your APIsDraw the Line [7] [8] 3 good design patterns
  • 22. @DanielDeogun @DanielSawano #DevoxxPL • 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]
  • 23. @DanielDeogun @DanielSawano #DevoxxPL • 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)
  • 24. @DanielDeogun @DanielSawano #DevoxxPL 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));
 }
 }
 }
  • 25. @DanielDeogun @DanielSawano #DevoxxPL 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));
 }
 }
  • 26. @DanielDeogun @DanielSawano #DevoxxPL ✓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
  • 27. @DanielDeogun @DanielSawano #DevoxxPL Security in your Delivery Pipeline [10][12] - Unit Testing
  • 29. @DanielDeogun @DanielSawano #DevoxxPL Email Domain Primitive External context Your context Email Email Defined by RFC Defined by you
  • 30. @DanielDeogun @DanielSawano #DevoxxPL Normal & Boundary Testing Normal Boundary Tests with input that clearly meets the domain rules Tests that verify behavior around the boundary
  • 31. @DanielDeogun @DanielSawano #DevoxxPL 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(); } ... }
  • 32. @DanielDeogun @DanielSawano #DevoxxPL 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
  • 33. @DanielDeogun @DanielSawano #DevoxxPL Testing with invalid input @TestFactory Stream<DynamicTest> should_reject_invalid_input() { return Stream.of( null, "null", "nil", "0", "", " ", "t", "n", "john.doen@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))); }
  • 34. @DanielDeogun @DanielSawano #DevoxxPL 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(); } ... }
  • 35. @DanielDeogun @DanielSawano #DevoxxPL 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()))); }
  • 36. @DanielDeogun @DanielSawano #DevoxxPL 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$"
  • 37. @DanielDeogun @DanielSawano #DevoxxPL ✓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
  • 38. @DanielDeogun @DanielSawano #DevoxxPL • 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
  • 39. @DanielDeogun @DanielSawano #DevoxxPL Domain DoS Attacks A DoS attack caused by utilizing domain rules in a malicious way is called a Domain DoS
  • 40. @DanielDeogun @DanielSawano #DevoxxPL 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]
  • 43. @DanielDeogun @DanielSawano #DevoxxPL Key Takeaway By focusing on good design principles you can create secure software without constantly thinking about security.
  • 44. @DanielDeogun @DanielSawano #DevoxxPL Questions & More [2] URL: http://bit.ly/secure-by-design Discount code: ctwdevoxxpl17 (40% off) Want a free ebook? Catch us in the break!
  • 45. @DanielDeogun @DanielSawano #DevoxxPL [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 byYoel 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