Defensive Coding Techniques (Pt. 1) Engineering Secure Software - - PowerPoint PPT Presentation

defensive coding techniques pt 1
SMART_READER_LITE
LIVE PREVIEW

Defensive Coding Techniques (Pt. 1) Engineering Secure Software - - PowerPoint PPT Presentation

Defensive Coding Techniques (Pt. 1) Engineering Secure Software Last Revised: September 21, 2020 SWEN-331: Engineering Secure Software Benjamin S Meyers 1 Defensive Coding vs. Risk Analysis Risk Analysis All about domain, assets,


slide-1
SLIDE 1

SWEN-331: Engineering Secure Software Benjamin S Meyers

Defensive Coding Techniques (Pt. 1)

Engineering Secure Software

Last Revised: September 21, 2020 1

slide-2
SLIDE 2

SWEN-331: Engineering Secure Software Benjamin S Meyers

Defensive Coding vs. Risk Analysis

  • Risk Analysis

○ All about domain, assets, threats, what-ifs ○ Global-minded ○ Prioritization is critical

  • Defensive Coding

○ One small change in code → big change in risk analysis

■ e.g. storing passwords in the customer table vs. user table ■ e.g. website allowing uploading files for one feature

○ “Weakest link” mentality

■ Less about prioritization ■ Technology-specific

  • We should always code defensively.

2

slide-3
SLIDE 3

SWEN-331: Engineering Secure Software Benjamin S Meyers

Defensive Coding Principles

  • Writing insecure code is surprisingly easy

○ Arcane coding assumptions ○ Many different technologies to know

  • Maintainability still counts

○ Duplicate code is even harder to secure ○ Vulnerabilities often have regressions and incomplete fixes

  • Know thy API’s

○ Misusing an API in the wrong context can be a vulnerability

■ e.g. an XML parser that also executes includes

○ Copying from internet examples without understanding? For shame.

  • Don’t be paranoid; know what you can trust

3

slide-4
SLIDE 4

SWEN-331: Engineering Secure Software Benjamin S Meyers

Complexity

  • “Complexity is the enemy of security” — Gary McGraw
  • Structural complexity

○ Lots of interconnected subsystems → architectural complexity ○ Lots of if-statements and loops → cyclomatic complexity

  • Cognitive complexity

○ Lack of understanding → mistakes (vulnerabilities) ○ How much do I have to think about how this feature works? ○ Subjective, but important

4

slide-5
SLIDE 5

SWEN-331: Engineering Secure Software Benjamin S Meyers

Complexity

  • “Complexity is the enemy of security” — Gary McGraw
  • Complexity of inputs → big security risks

○ e.g. apps to operating systems ○ e.g. web pages to web browsers ○ e.g. video files ○ e.g. font files

  • Obviously no vulnerabilities (vs. no obvious vulnerabilities)

5

slide-6
SLIDE 6

SWEN-331: Engineering Secure Software Benjamin S Meyers

Know the Tree of Knowledge

  • A lot of defensive coding comes down to clever tricks

○ CWE ○ Why we do VOTD

  • Understanding history tells us what’s common and possible

○ CVE ○ Why we do case studies

  • Makers of any technology understand their own limitations

○ Read the guidelines provided by originators and experts ○ Many situations don’t apply to you, but some very much will

■ Java: https://www.oracle.com/java/technologies/javase/seccodeguide.html ■ C++: https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=88046682

6

slide-7
SLIDE 7

SWEN-331: Engineering Secure Software Benjamin S Meyers

Validating Input

  • Input validation is blocking bad inputs
  • Black list

○ Enumerate the bad stuff ○ Drawback: infinite, easy to get around ○ Benefit: react quickly (if no re-compilation), straightforward ○ e.g. virus definitions

  • White list

○ Only accept known good input ○ Often done with regular expressions ○ Drawbacks:

■ Sometimes not possible to block certain characters ■ Often requires re-compilation and patches

  • Recommendation: do both, but prefer a white list

7

slide-8
SLIDE 8

SWEN-331: Engineering Secure Software Benjamin S Meyers

Input in Many Forms

  • Not always strings and numbers
  • Consider: images with metadata

○ PHP had many issues with EXIF JPEG metadata ○ Adobe Acrobat and embedded fonts ○ Java with ICC and BMP ○ CVE-2007-2789

8

slide-9
SLIDE 9

SWEN-331: Engineering Secure Software Benjamin S Meyers

Sanitizing Input

  • Instead of blocking input, sanitize it

○ All input comes in, but it’s manipulated ○ Convert it to something that won’t be interpreted as code ○ Usually utilizes escape characters

■ e.g. HTML: < is &lt; ■ e.g. Java: “ is \“

  • Drawback:

○ Need to know everything to escape ○ Very blacklist-like ○ False positives are also annoying ○ Need to remember to do it… everywhere

9

slide-10
SLIDE 10

SWEN-331: Engineering Secure Software Benjamin S Meyers

Simplify Input

  • Instead of blocking or sanitizing input, convert it to a simpler

form

  • Examples:

○ Convert a number in a string to an integer (even if you then put it back into a string) ○ Canonicalization for filepaths ○ Convert date strings to Epoch dates (i.e. integer MS since Jan 1, 1970)

10 10

str = “123 <script>” return “$#{str.to_i}” # returns “$123” i = “123 <script>” return “$” + str(int(re.sub(r“[^0-9]”, “”, i))

Ruby Python

slide-11
SLIDE 11

SWEN-331: Engineering Secure Software Benjamin S Meyers

Simplify Input

  • Pros

○ Reduces if-complexity (“what if” scenarios) ○ Simplifies future operations ○ You KNOW what is there

  • Cons

○ Simplifying takes work ○ Can your input truly be simplified?

  • Note: “normalize input” has a different meaning in a Machine

Learning context

11 11

slide-12
SLIDE 12

SWEN-331: Engineering Secure Software Benjamin S Meyers

Exception Handling

  • Most weird (or unexpected) behavior results in an exception

○ Handle the exceptions you know about ○ Know that sometimes, some get away

  • Design your system to handle exceptions at the top-level

○ e.g. Java: catch Throwable not Exception ○ e.g. JSP: <%@ page errorPage=“exceptionHandler.jsp” %>

  • For maintainability and complexity:

○ Avoid promoting unnecessarily (e.g. throws Exception) ○ Deal with related exception in one place, near the problem

■ e.g. wrapper around private methods in a class

  • Sheer laziness: try{something();} catch{}

12 12

slide-13
SLIDE 13

SWEN-331: Engineering Secure Software Benjamin S Meyers

finally

  • Don’t forget about the finally clause!

○ Anything in the finally clause gets executed no matter what ○ Good for cleanup of resources

13 13

public void something() { Connection conn = null; try { conn = getConnection(); // do db stuff } catch (SQLException e) { // handle the exception } finally { DBUtil.closeConnection(conn); } }

slide-14
SLIDE 14

SWEN-331: Engineering Secure Software Benjamin S Meyers

Think of the Children

  • Subclassing overrides methods

○ In untrusted API situations, make sure you can’t be extended and have a sensitive method overridden ○ Use the final keyword: public final class Countdown{}

  • Malicious subclasses can override the finalize() method to

resurrect objects

○ Gets executed right before the object goes to garbage collector

14 14

slide-15
SLIDE 15

SWEN-331: Engineering Secure Software Benjamin S Meyers

Think of the Children

  • Malicious subclasses can override the finalize() method to

resurrect objects

15 15

public class ClassLoader { public ClassLoader() { securityCheck(); init(); } private securityCheck() { … }; private init() { … }; }

slide-16
SLIDE 16

SWEN-331: Engineering Secure Software Benjamin S Meyers

Think of the Children

  • Malicious subclasses can override the finalize() method to

resurrect objects

16 16

public class MaliciousCL extends ClassLoader { static ClassLoader cl; @Override protected void finalize() { cl = this; } public static void main(String[] args) { try { new MaliciousCL(); } catch (SecurityException e) { … } System.gc(); System.runFinalization(); System.out.println(cl); } }

slide-17
SLIDE 17

SWEN-331: Engineering Secure Software Benjamin S Meyers

Immutability in Object-Oriented Programming

  • Setters are evil (except the Irish kind)

○ What if we construct, run, set, then run again? ○ Unnecessarily increases complexity ○ Violates encapsulation ○ Don’t just throw setters in if you don’t have a reason

  • Beans are one exception to this rule

○ Functionality is only get and set ○ Little other functionality

■ Mapping to validation ■ Mapping to relations

  • Prefer immutable types (final keyword)

17 17

slide-18
SLIDE 18

SWEN-331: Engineering Secure Software Benjamin S Meyers

Global Variables

  • Global variables are dangerous
  • Mutable global variables are very dangerous

○ Unnecessarily increased complexity ○ Tampering concern in an untrusted API

  • Nice try, but still doesn’t count:

18 18

public static final List<String> list = new ArrayList<String>();

slide-19
SLIDE 19

SWEN-331: Engineering Secure Software Benjamin S Meyers

Global Variables

  • Global variables are dangerous
  • Mutable global variables are very dangerous

○ Unnecessarily increased complexity ○ Tampering concern in an untrusted API

  • Nice try, but still doesn’t count:
  • Instead: java.util.Collections.unmodifiableList()

19 19

public static final List<String> list = new ArrayList<String>(); public static final List<String> list = new unmodifiableList(asList(“Alice”, “Bob”, “Charlie”));

slide-20
SLIDE 20

SWEN-331: Engineering Secure Software Benjamin S Meyers

Concurrency is Always a Risk

  • Treat anything concurrent with initial distrust

○ Race conditions → denial of service ○ Shared memory → potential leakage ○ Weird circumstances → potential tampering

  • Concurrency is ubiquitous

○ Webapps, databases, GUI’s, games, etc.

  • Common poor assumptions

○ “There will be only one copy of this thread” ○ “There will only be X threads” ○ “Nobody knows about my mutability”

20 20

slide-21
SLIDE 21

SWEN-331: Engineering Secure Software Benjamin S Meyers

free is Not Idempotent

  • Yes, you need to free() every malloc()
  • But! Don’t call free() twice

○ Something else might already be using that memory ○ Now it can get overwritten by someone else

■ Definitely an availability problem, potentially integrity

21 21

int *a, *b, *c; a = (int *) malloc(sizeof(int)); // a is now 0x12345678 free(a); // byte 0x12345678 is now available to malloc b = (int *) malloc(sizeof(int)); // b is now 0x12345678! *b = 5; free(a); // free 0x12345678 again?!?! b is now freed too! c = (int *) malloc(sizeof(int)); // c is now 0x12345678 *c = 6; printf (“%d”, *b); // prints 6 not 5! Corrupted!

slide-22
SLIDE 22

SWEN-331: Engineering Secure Software Benjamin S Meyers

free is Not Idempotent

  • Yes, you need to free() every malloc()
  • But! Don’t call free() twice

○ Something else might already be using that memory ○ Now it can get overwritten by someone else

■ Definitely an availability problem, potentially integrity

22 22

int *a, *b, *c; a = (int *) malloc(sizeof(int)); // a is now 0x12345678 free(a); // byte 0x12345678 is now available to malloc a = 0; // zero-out pointer after free, just in case b = (int *) malloc(sizeof(int)); // b is now 0x12345678! *b = 5; free(a); // free 0x12345678 again?!?! b is now freed too! c = (int *) malloc(sizeof(int)); // c is now 0x12345678 *c = 6; printf (“%d”, *b); // prints 6 not 5! Corrupted!

slide-23
SLIDE 23

SWEN-331: Engineering Secure Software Benjamin S Meyers

free is Not Idempotent

  • Yes, you need to free() every malloc()
  • But! Don’t call free() twice

○ Something else might already be using that memory ○ Now it can get overwritten by someone else

■ Definitely an availability problem, potentially integrity

23 23

int *a, *b, *c; a = (int *) malloc(sizeof(int)); // a is now 0x12345678 free(a); // byte 0x12345678 is now available to malloc a = 0; // zero-out pointer after free, just in case b = (int *) malloc(sizeof(int)); // b is now 0x12345678! *b = 5; free(a); // free 0x12345678 again?!?! b is now freed too! c = (int *) malloc(sizeof(int)); // c is now 0x12345678 *c = 6; printf (“%d”, *b); // prints 6 not 5! Corrupted!

Don’t double-free!

slide-24
SLIDE 24

SWEN-331: Engineering Secure Software Benjamin S Meyers 24 24

Source: https://xkcd.com/2054/

to be continued...