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, 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. ● SWEN-331: Engineering Secure Software Benjamin S Meyers 2
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 ● SWEN-331: Engineering Secure Software Benjamin S Meyers 3
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 ○ SWEN-331: Engineering Secure Software Benjamin S Meyers 4
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) ● SWEN-331: Engineering Secure Software Benjamin S Meyers 5
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 ■ SWEN-331: Engineering Secure Software Benjamin S Meyers 6
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 ● SWEN-331: Engineering Secure Software Benjamin S Meyers 7
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 ○ SWEN-331: Engineering Secure Software Benjamin S Meyers 8
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 < ■ 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 ○ SWEN-331: Engineering Secure Software Benjamin S Meyers 9
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) str = “123 <script>” i = “123 <script>” return “$#{str.to_i}” # returns “$123” return “$” + str(int(re.sub(r“[^0-9]”, “”, i)) Ruby Python Canonicalization for filepaths ○ Convert date strings to Epoch dates (i.e. integer MS since Jan 1, ○ 1970) SWEN-331: Engineering Secure Software Benjamin S Meyers 10 10
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 SWEN-331: Engineering Secure Software Benjamin S Meyers 11 11
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{} ● SWEN-331: Engineering Secure Software Benjamin S Meyers 12 12
finally Don’t forget about the finally clause! ● Anything in the finally clause gets executed no matter what ○ Good for cleanup of resources ○ public void something() { Connection conn = null; try { conn = getConnection(); // do db stuff } catch (SQLException e) { // handle the exception } finally { DBUtil.closeConnection(conn); } } SWEN-331: Engineering Secure Software Benjamin S Meyers 13 13
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 ○ SWEN-331: Engineering Secure Software Benjamin S Meyers 14 14
Think of the Children Malicious subclasses can override the finalize() method to ● resurrect objects public class ClassLoader { public ClassLoader() { securityCheck(); init(); } private securityCheck() { … }; private init() { … }; } SWEN-331: Engineering Secure Software Benjamin S Meyers 15 15
Think of the Children Malicious subclasses can override the finalize() method to ● resurrect objects 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); } } SWEN-331: Engineering Secure Software Benjamin S Meyers 16 16
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) ● SWEN-331: Engineering Secure Software Benjamin S Meyers 17 17
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: ● public static final List<String> list = new ArrayList<String>(); SWEN-331: Engineering Secure Software Benjamin S Meyers 18 18
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: ● public static final List<String> list = new ArrayList<String>(); Instead: java.util.Collections.unmodifiableList() ● public static final List<String> list = new unmodifiableList(asList(“Alice”, “Bob”, “Charlie”)); SWEN-331: Engineering Secure Software Benjamin S Meyers 19 19
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” ○ SWEN-331: Engineering Secure Software Benjamin S Meyers 20 20
Recommend
More recommend