Secure Development

Defensive Programming

Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser 20.11.2020

Winter 2020/21, www.iaik.tugraz.at Table of contents www.tugraz.at

1. Defense-in-Depth

2. Defensive Programming Overview Safety Concepts Secure Data Flow Secure Control Flow General Principles Improve Code Quality

3. Summary & Outlook

1 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Defense-in-Depth Defense-in-Depth www.tugraz.at

y Understand the attacker’s perspective • ”Know your enemy” – Sun Tzu, The Art of War y Defend on all layers • The weakest link will break first

2 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Defense In Depth www.tugraz.at

Attacker’s perspective Defender’s perspective ó Vulnerability discovery ó Vulnerability prevention (today) Ǻ Exploitation Ǻ Exploit prevention (next time) Š Privilege elevation Š Privilege minimization (next time)

3 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Defense In Depth www.tugraz.at

Attacker’s perspective Defender’s perspective ó Vulnerability discovery ó Vulnerability prevention • buffer/integer overflow, use-after-free, • Code quality, memory safety, type format strings, type confusion safety, error handling ... Ǻ Exploitation Ǻ Exploit prevention • Data corruption, shellcode, code reuse, • Compiler/runtime defenses, hardware ROP, return-to-libc defenses Š Privilege elevation Š Privilege minimization • admin flag, spawn a shell, cat flag.txt, • System call filtering, sandboxing, gain persistence virtualization

4 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Vulnerability Prevention: Goals I www.tugraz.at

\ Overall goal: eliminate all vulnerabilities • Prove the program correct → Other courses, e.g., Model-based Testing, Verification and Testing • ”A program is functionally correct iff it satisfies the specification” • Specification needed • Bugs in spec? • Ambiguities? • Unspecified behavior?! • Most vulnerabilities are not specified • ”A program is safe iff it is functionally correct and does not exhibit unspecified behavior” • Invalid assumptions?! ”The attacker is not supposed to ...”

5 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Vulnerability Prevention: Goals II www.tugraz.at

• Verification is hard super hard • seL4 microkernel took 20.5 person years to verify [?] \ Overall goal: eliminate as many vulnerabilities as possible • Maybe degrade some vulnerabilities to unexploitable bugs • Best effort but no hard security guarantee → Defense-in-Depth is necessary, e.g., exploit prevention and privilege minimization \ Practical goal: Improve code quality via defensive programming

6 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Defensive Programming Overview Defensive Programming: Goals & Principles www.tugraz.at

Sub-goals General principles \ Memory safety • Choose appropriate language \ Type safety • Improve code quality \ Integer safety • Coding standard • Source code reuse \ Secure data flow • Portability / Assumptions • Input sanitization • Documentation \ Secure control flow • Testing & Assertions • Error handling • Compiler assistance

7 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Spatial memory safety www.tugraz.at

\ Goal: eliminate array out-of-bounds access y Use or develop accessor functions which check boundaries • Example: C++ std::vector int x= vector[index]; // unchecked int y= vector.at(index); // checked • Memory-safe languages: Compiler can optimize out unnecessary bounds checks

8 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Temporal memory safety www.tugraz.at

\ Goal: eliminate temporal issues y Use reference counting • Avoids memory leaks and double free • E.g., C++ smart pointers std::shared_ptr y Exclusive ownership: only one owner with write access • Avoids race conditions and time-of-check vs time-of-use (TOCTOU) • E.g., Rust ownership y Deinitialize free’d resources • Avoids use-after-free (UAF) memset(ptr, 0, sizeof(*ptr); free(ptr); ptr= NULL;

9 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Type safety www.tugraz.at

\ Goal: eliminate type confusion issues y Avoid use of C unions y Avoid unsafe casts • Avoid cast to (void*) This should mainly be used for memory allocators • Avoid C++ reinterpret_cast

10 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Fat Pointers www.tugraz.at

• General concept • Store additional runtime metadata alongside pointer, e.g.: • pointer type • length • validity • access permissions • Examples: C++ smart pointer, dynamic cast<> h Typically consume 2–5 times more memory per pointer

11 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Integer Safety I www.tugraz.at

\ Goal 1: prevent integer overflows/underflows y Use correct integer types • Use size t for indices and length • Use uint64 t, etc. for fixed-size integers • Use uintptr t for pointer-to-integer conversion y For every arithmetic operation check if overflow is possible y Detect and prevent integer overflows via • Compiler builtins, e.g. builtin saddl overflow • Larger types for intermediate results • Explicit checks (see next tutorial)

12 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Integer Safety II www.tugraz.at

\ Goal 2: prevent integer conversion issues y Avoid mixing signed and unsigned • Attention: char can be signed or unsigned y Make large types explicit int y = ...; long long x=y + 2; // int-addition might overflow long long x=( long long)y+2LL; y Perform range checks on each downcast int x = ...; if (x> SHORT_MAX) error(); short y=( short)x;

13 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Integer Safety III www.tugraz.at

\ Goal 3: prevent undefined behavior y Know undefined behavior! E.g., ȱ Left-shift a signed type • number could become negative if MSB is reached ȱ Left-shift by a negative number ȱ sizeof(void*) • GNU C specifies it to be 1 size_t strlen(void* string){ while(*(char*)string !=’\0’) string++; // undefined increment }

14 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Secure Data Flow www.tugraz.at

? Observation: Attacker injects payload as data, which might get misinterpreted as code “ Idea: Focus on data flow rather than memory objects, types, etc. \ Goal: Secure data flow → attacker cannot inject payload • Check every input an attacker can control directly or indirectly • Better: Check every input. y Input sanitization

15 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Secure Data Flow: Deserialization Issues I www.tugraz.at

16 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Secure Data Flow: Deserialization Issues II www.tugraz.at

17 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Secure Data Flow: Unicode Issues www.tugraz.at

18 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Secure Data Flow: Input Sanitization www.tugraz.at

\ Goal: sanitize dangerous input • Detect and reject • Pattern matching • Canonicalization • Neutralize • Filtering • Character escaping

19 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Secure Data Flow: Pattern Matching www.tugraz.at

y Use existing sanitizers wherever possible! • HTML, SQL, CSS, XML, E-mail ... • Blacklist (deny list) h It is easy to overlook stuff • Whitelist (allow list) î Very restrictive, thus secure h Very restrictive, thus often unusable • Regex î Very powerful h Horrible syntax • Rust pattern matcher

20 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Secure Data Flow: Canonicalization I www.tugraz.at

ȱ Issue: equivalent representations make sanitization a pain

Example: equivalent Unix paths Example: equivalent numbers

/proc/self/maps 21 ˜/../../proc/self/maps 21.0 /proc/1/maps +21 /proc/1/./maps 025 /proc/1/././////maps 0x15 /proc/../proc/1/maps 21e0 ......

21 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Secure Data Flow: Canonicalization II www.tugraz.at

“ Idea: make parsing more uniform y Canonicalization before Sanitization! • Example: canonicalizing paths using realpath • Resolve relative paths ../../etc/passwd --> /etc/passwd --> DENY ./etc/passwd --> /home/ssd/etc/passwd --> ALLOW • Resolve symlinks: mylink-to-passwd --> /etc/passwd --> DENY

22 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Secure Data Flow: Canonicalization III www.tugraz.at

More issues to consider ȱ Newlines: \r\n vs. \n ȱ Path separators: Windows \ vs. Unix / ȱ Case (in)sensitivity: (Git CVE-2014-9390) ȱ File system permissions: FAT vs NTFS vs EXT ȱ Time stamps (UTC vs GMT)

23 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Secure Data Flow: Character Escaping I www.tugraz.at

ȱ Issue: user input gets interpreted as code, e.g.: • SQL injection • Cross-site scripting (HTML injection) • Shell command injection Please enter your username: Dr.‘whoami‘ User Dr.Weiser created. “ Best idea: never interpret user input as code! “ If not possible: neutralize dangerous characters y Escaping before Interpretation!

24 Daniel Gruss, Vedad Hadzic, Martin Schwarzl, Samuel Weiser — Winter 2020/21, www.iaik.tugraz.at Secure Data Flow: Character Escaping II www.tugraz.at

• Examples: • Shell: replace ‘ with \‘ • HTML: replace