Secure Coding Patterns @andhallberg TrueSec Trust Domain-Driven - - PowerPoint PPT Presentation

secure coding patterns
SMART_READER_LITE
LIVE PREVIEW

Secure Coding Patterns @andhallberg TrueSec Trust Domain-Driven - - PowerPoint PPT Presentation

Secure Coding Patterns @andhallberg TrueSec Trust Domain-Driven Security The Untrusted Pa7ern Immutability The Inverse Life Coach Pa7ern Trust The founda>on of so?ware security 1. Hello! Im Businessman Bob! 2. Hello! Im the bank!


slide-1
SLIDE 1

Secure Coding Patterns

@andhallberg TrueSec

slide-2
SLIDE 2

Trust Domain-Driven Security The Untrusted Pa7ern The Inverse Life Coach Pa7ern Immutability

slide-3
SLIDE 3

Trust

The founda>on of so?ware security

slide-4
SLIDE 4
slide-5
SLIDE 5
  • 1. Hello! I’m Businessman Bob!
  • 2. Hello! I’m the bank!
  • 3. Transfer X euro from account Y to

account Z, please!

  • 4. Ok!
slide-6
SLIDE 6
  • 1. Hello! I’m Businessman Bob!
  • 2. Hello! I’m the bank!

What might go wrong?

slide-7
SLIDE 7
  • 1. Hello! I’m Businessman Bob!
  • 2. Hello! I’m the bank!

How can the bank be sure that Bob is Bob? How can Bob be sure that the bank is the bank?

  • 3. Transfer X euro from account Y to

account Z, please!

  • 4. Ok!
slide-8
SLIDE 8
  • 1. Hello! I’m Businessman Bob!
  • 2. Hello! I’m the bank!

Do we know that Bob owns account Y?

  • 3. Transfer X euro from account Y to

account Z, please!

  • 4. Ok!
slide-9
SLIDE 9
  • 1. Hello! I’m Businessman Bob!
  • 2. Hello! I’m the bank!

Do we know that account Y holds X euro?

  • 3. Transfer X euro from account Y to

account Z, please!

  • 4. Ok!
slide-10
SLIDE 10
  • 1. Hello! I’m Businessman Bob!
  • 2. Hello! I’m the bank!

Do we even know that X is a number?

  • 3. Transfer X euro from account Y to

account Z, please!

  • 4. Ok!
slide-11
SLIDE 11

Your applica>on

The user 3rd party services Database HTTP/S request data etc...

Trust boundary

slide-12
SLIDE 12

TRUSTED UNTRUSTED

slide-13
SLIDE 13

Valida,on Untrusted Rejected Trusted

slide-14
SLIDE 14

Valida,on and friends

  • Valida>on
  • Making sure data is valid in the domain

I can’t transfer amount “a” or -1

  • Canonicaliza>on and/or normaliza>on
  • Must happen *before* valida>on!

c:\public\fileupload\..\..\secrets\keys => c:\secrets\key

  • Sani>za>on
  • Clean up dangerous/unknown data

log injecBon

slide-15
SLIDE 15

Valida,on, cont.

  • Always prefer whitelis>ng over blacklis>ng
  • It’s easier to figure out what’s valid over what’s not valid
  • Strict valida>on finds bugs early!
slide-16
SLIDE 16

Ask yourself...

What is the minimal acceptable range for this parameter? Don’t accept any more than that!

slide-17
SLIDE 17

Trust

slide-18
SLIDE 18

Domain-Driven Security

Domain Driven Design + conven>ons for valida>on

slide-19
SLIDE 19
  • 1. Hello! This is Bob again!
  • 2. Hello Bob! I’m s>ll the bank!
  • 3. Transfer -1000 euro from account Y

to account Z, please!

  • 4. Ok!
slide-20
SLIDE 20

The same valida,on has to be performed

  • ver and over
  • Easy to forget to validate somewhere
  • Valida>on ends up everywhere in the code, but

(because of this?) is easily forgo7en

  • Should validate even from “internal” sources such

as databases Example: stored XSS

slide-21
SLIDE 21

Your applica>on

The user 3rd party services Database HTTP/S request data etc...

Trust boundary

String String Integer Integer Valida>on Valida>on

slide-22
SLIDE 22

Domain-Driven Security

  • Primi>ve types and data structures are untrusted

by default

  • Strings, integers, byte arrays, collec>ons etc.
  • Domain objects
  • Built-in valida>on
  • (Immutability – more on this later!)
slide-23
SLIDE 23

Your applica>on

The user 3rd party services Database HTTP/S request data etc...

Trust boundary

String Integer

Account Amount

slide-24
SLIDE 24

public final class AccountNumber {

  • private final String value;
  • public AccountNumber(String value) {

if(!isValid(value)){ throw new IllegalArgumentException("Invalid account number"); } this.value = value; }

  • public static boolean isValid(String accountNumber){

return accountNumber != null && hasLength(accountNumber, 10, 12) && isNumeric(accountNumber); } }

slide-25
SLIDE 25

Webservice

SOAP (int, string, byte[], ...)

User Account

slide-26
SLIDE 26

SOAP (int, string, byte[], ...)

Excep>on!

User

Webservice

Account

slide-27
SLIDE 27

public void Reticulate(Spline spline, int angle);

WTF ??

public void Reticulate(Spline spline, Angle angle);

slide-28
SLIDE 28

public void Heat(int duration, int temperature); public void Heat(Duration duration, Temperature temperature); reactor.Heat(100, 5); // Boil for 5 minutes

slide-29
SLIDE 29

int accountNumber = database.getAccountNumberForUser(user); if (accountNumber <= 0 || accountNumber > 100000) { throw new IllegalStateException(”Invalid accountNumber!"); } pension.transferTo(accountNumber); AccountNumber accountNumber = new AccountNumber(database.getAccountNumberForUser(user)); pension.transferTo(accountNumber); VS

slide-30
SLIDE 30

Domain Driven Security essen,als

  • You know that all domain objects are valid
  • You know you forgot to validate something when you see

primi>ve types being passed around

  • The type system ensures that the correct domain object must

be used

  • Remember: you s>ll need to validate your business rules! But

at least you don’t have to worry about the building blocks being invalid.

slide-31
SLIDE 31

One more thing...

slide-32
SLIDE 32

Never use null!

slide-33
SLIDE 33

public class Optional<T> { public bool IsPresent; public T Get; } int? foo = null;

  • 1. “Value might not exist” – make it explicit!
slide-34
SLIDE 34
  • 2. “This shouldn’t happen!” - throw!

public Account GetDefaultAccountForUser(User user) { Optional<Account> account = _defaultAccountRepository.GetForUser(user); if (!account.IsPresent) { throw new InvalidOperationException("No default account for user “ + user.Id + ", should not happen!"); } return account.Get; }

slide-35
SLIDE 35

Trust Domain-Driven Security Trust

slide-36
SLIDE 36

The Untrusted PaBern

Make trust a first-class concept at trust boundaries

slide-37
SLIDE 37

public void Foo(string bar) { if (!IsValid(bar)) { throw new ValidationException(); } DoSomethingWith(bar); }

slide-38
SLIDE 38

public void Foo(string untrusted_bar) { if (!IsValid(untrusted_bar)) { throw new ValidationException(); } var bar = untrusted_bar; DoSomethingWith(bar); }

slide-39
SLIDE 39

public void Foo2(string untrusted_bar, string untrusted_frob, byte[] data);

WTF ??

slide-40
SLIDE 40

public void Foo(string untrusted_bar) { var bar = Validate(untrusted_bar); DoSomethingWith(bar); }

slide-41
SLIDE 41

public void Foo(Untrusted<string> bar);

slide-42
SLIDE 42

public class Untrusted<T> { readonly T _value; public Untrusted(T value) { _value = value; } private T Value { get { return _value }; } } [assembly: InternalsVisibleTo("Validation")]

slide-43
SLIDE 43

// In the "Validation" assembly public abstract class Validator<T> { public T Validate(Untrusted<T> untrusted) { if (!InnerValidate(untrusted.Value)) { throw new ValidationException(); } return untrusted.Value; } protected abstract bool InnerValidate(T value); }

slide-44
SLIDE 44

public void HandleAcctNbr(Untrusted<string> accountNbr) { var trusted = new AccountNumberValidator().Validate(accountNbr); DoSomethingWith(trusted); }

slide-45
SLIDE 45

public void CreateAccount(string nbr) { var untrustedNbr = new Untrusted<string>(nbr); HandleAccountNbr(untrustedNbr); ... }

slide-46
SLIDE 46

Trust Domain-Driven Security The Untrusted Pa7ern

slide-47
SLIDE 47

Immutability

Stuff passed over a trust boundary, regardless of direc>on, should not be able to change later.

slide-48
SLIDE 48

Does your applica,on handle concurrency?

  • Hundreds of threads?
  • How does that affect valida>on?
  • The thing you just validated, is it s>ll valid?
slide-49
SLIDE 49

TOCTTOU

Time Of Check To Time Of Use

slide-50
SLIDE 50

public public void tryTransfer(Amount amount) { if if (!this.account.contains(amount)) { thro row new new ValidationException(); } transfer(amount); } TOC TOU

Thread 2: amount.setValue(1000000);

slide-51
SLIDE 51

public public cl class ss Amount { pri riva vate final final Integer Integer value; public public Amount(Integer r value) { if (!isValid(value) { throw new IllegalArgumentException(); } this this.value = value; } public public Integer Integer getValue() { re return rn this this.value; } }

slide-52
SLIDE 52

Immutability

  • Immutability significantly reduces TOCTTOU-problems
  • Plays very well with Domain Driven Security
  • … and readability
  • … and paralleliza>on
  • … and event sourcing
  • ... etc
slide-53
SLIDE 53

Race condi,on, web example

slide-54
SLIDE 54

public void Wizard_Step3(Guid key) { var data = wizardData[key]; if (UserHasAccess(HttpContext.Current.User, data.ProductId)) // TOC { DoSomethingWith(data); // TOU } } { Wizard_Step2(key, secret_productId) } public Guid Wizard_Step1() { var key = Guid.NewGuid(); wizardData.Add(key, new Data()); return key; } public void Wizard_Step2(Guid key, string productId) { wizardData[key].ProductId = productId; } static Dictionary<Guid, Data> wizardData = new Dictionary<Guid, Data>();

slide-55
SLIDE 55

public Guid Wizard_Step1() { var key = Guid.NewGuid(); wizardData.Add(key, new ImmutableData()); return key; } public void Wizard_Step2(Guid key, string productId) { var data = wizardData[key]; var newData = data.CloneWithProductId(productId); // Copies data, new productId wizardData[key] = newData; } public void Wizard_Step3(Guid key) { var data = wizardData[key]; if (UserHasAccess(HttpContext.Current.User, data.ProductId)) // TOC { DoSomethingWith(data); // TOU } } static Dictionary<Guid, ImmutableData> wizardData = new Dictionary<Guid, ImmutableData>();

slide-56
SLIDE 56

Immutability

  • Security spray
  • Should be the norm!
slide-57
SLIDE 57

Trust Domain-Driven Security The Untrusted Pa7ern Immutability

slide-58
SLIDE 58

The Inverse Life Coach PaBern

Be a pessimist!

slide-59
SLIDE 59

boolean success = true;

  • return success;
slide-60
SLIDE 60

boolean success = false;

  • return success;

Assume failure!

slide-61
SLIDE 61

public ResultData doStuff(Account account) { if (!hasAccess(account)) { throw new Exception(); }

  • return new ResultData(stuffFromCode);

}

Fail fast and force a narrow path of success

Fail fast by throwing No way of exi>ng without a valid object

slide-62
SLIDE 62
slide-63
SLIDE 63
slide-64
SLIDE 64
slide-65
SLIDE 65

Consider your Trust Boundaries

slide-66
SLIDE 66

Enjoy Domain-Driven Security

slide-67
SLIDE 67

Immutability should be the norm

slide-68
SLIDE 68

Null is a burning bag of dog poop

slide-69
SLIDE 69

Fire your Life Coach