Presentation is loading. Please wait.

Presentation is loading. Please wait.

Secure Coding James Walden Northern Kentucky University.

Similar presentations


Presentation on theme: "Secure Coding James Walden Northern Kentucky University."— Presentation transcript:

1 Secure Coding James Walden Northern Kentucky University

2 Topics 1.Error Handling 2.Return Codes 3.Exceptions 4.Logging 5.Memory Allocation 6.Using and Storing Passwords 7.Protecting Secrets in Memory

3 CSC 666: Secure Software Engineering Security Impact of Error Handling Information leakage  Stack traces  Database errors Resource leakage  Return on error without de-allocation  Exceptions bypass de-allocation

4 CSC 666: Secure Software Engineering Error Handling Techniques Return a neutral value: return a value that’s known to be harmless, i.e. a negative number, zero, or “”. Substitute the next piece of data: continue reading from hardware or file until a valid record is found. Return same answer as last time: don’t keep reading; instead return the last valid answer. Substitute closest legal value: if velocity has a range of 0..100, show a 0 when backing up. Log a warning message: Write a warning to a log, then continue on, perhaps using one of the other techniques. Terminate program: Terminate program execution. Return an error code: Report error by  Setting the value of a status variable (errno)  Return status as the function’s return value  Throw an exception

5 CSC 666: Secure Software Engineering Return Codes Use function return code to indicate error.  Easy to ignore. Simply ignore return code.  Error handling logic is mixed with logic processing normal return codes.  No universal convention for error codes. Common return code patterns.  Negative values when nonnegative expected.  NULL values for pointer return codes.

6 Example: character get functions fgetc(), getc(), getchar() read char, return int Use int to represent EOF error code. Incorrect example: return value is declared as a char char buf[BUFSIZ]; char c; int i = 0; while ( (c = getchar()) != '\n' && c != EOF ) if (i < BUFSIZ-1) { buf[i++] = c; } buf[i] = '\0'; /* terminate NTBS */ Correct example char buf[BUFSIZ]; int c; int i = 0; while (((c = getchar()) != '\n') && !feof(stdin) && !ferror(stdin)) if (i < BUFSIZ-1) { buf[i++] = c; } buf[i] = '\0'; /* terminate NTBS */

7 CSC 666: Secure Software Engineering Resource Leaks Resources leak due to early returns  Memory  Filehandles Example char *getblock(int fd) { char *buf = (char *)malloc(1024); if (!buf) { return NULL; } if (read(fd, buf, 1024) != 1024) { return NULL; } return buf }

8 CSC 666: Secure Software Engineering Using goto for error handling Problem: need to de-allocate resources on return.  Each return is different since  Different resources allocated at each point. Solution: single de-allocation point  Check if resource is allocated, then  De-allocate if it is, and  Return with appropriate error code. Why goto ?  Avoids deep nesting.  Improves code readability.  Commonly used technique in kernel.

9 CSC 666: Secure Software Engineering Fixed version with goto char *getblock(int fd) { char *buf = (char *)malloc(1024); if (!buf) { goto ERROR; } if (read(fd, buf, 1024) != 1024) { goto ERROR; } return buf; ERROR: if (buf) { free(buf); } return NULL; }

10 CSC 666: Secure Software Engineering Exceptions Advantages of exceptions  Cannot be ignored by not checking for errors.  Separate main code from error code. Disadvantages of exceptions  Difficult to avoid resource leaks, as exceptions create many implicit control flow paths.  Can still ignore exceptions try { // code that can throw an exception } catch (AnException e) { // empty catch block }

11 CSC 666: Secure Software Engineering Checked Exceptions Checked exceptions: Exceptions that the language requires client code to handle.  C++, C#: no checked exceptions  Java: exceptions that inherit from Exception Unchecked exceptions: Exceptions that can be ignored by client code.  C++, C#: all exceptions are unchecked  Java: exceptions that inherit from RuntimeException.

12 CSC 666: Secure Software Engineering Exception Guarantees Levels of exception safety for a class. Basic Guarantee  No resources are leaked. Strong Guarantee  Exceptions leave state exactly as it was before the operation started. No Throw Guarantee  Component will handle all exceptions itself. No Exception Safety  Component may leak resources and leave object in an inconsistent unusable state.

13 CSC 666: Secure Software Engineering Exception Safety Example void stack::push(int element) { top++; if( top == size-1 ) { int* buf = new int[size+=32]; if( buf == 0 ) throw “Out of memory”; for(int i = 0; i < top; i++) buf[i] = data[i]; delete [] data; data = buf; } data[top] = element; }

14 CSC 666: Secure Software Engineering Catch-all Exception Handlers Ensure no information leakage at top level functions. doGet(), doPost (), web service entry points protected void doPost(HttpServletRequest req, HttpServlet Response res) { try { /* function body */ } catch (Throwable t) { logger.error(“Top-level exception caught”, t); } Do not do this in low level code.  Need to deal with individual error types separately, instead of ignoring them or handling generically.

15 CSC 666: Secure Software Engineering Destructor De-Allocation Resource Acquisition Is Initialization design pattern  Resources acquired during initialization of object, before it can be used.  Resources are de-allocated by the object’s destructor, which occurs even via exceptions. Example file (const char* filename) { file_ = fopen(filename, “w+”); if (!file_) throw std::runtime_error("file open failure"); } ~file() { if (f) { fclose(file_); } }

16 CSC 666: Secure Software Engineering Finally  Finally block executed regardless of whether an exception is caught or not.  Example Statement stmt = conn.createStatement(); try { stmt.execute(sqlString); } finally { if (stmt != null ) { stmt.close(); } }

17 CSC 666: Secure Software Engineering Logging Frameworks Use a standard logging framework.  Provide single consistent view of system.  Facilitate changes, such as logging to a new system or to a database. Examples  syslog()  log4j  java.util.logging

18 Memory Allocation Strategies Static Buffer Allocation  Advantages: simple, easy to know bounds.  Disadvantages: inflexible, wastes memory. Dynamic Buffer Allocation  Advantages: flexible.  Disadvantages: must check for DoS attacks. Track Buffer Sizes typedef struct { char* ptr; size_t bufsize; } buffer; CSC 666: Secure Software Engineering

19 Common Allocation Errors  Assuming that memory is zeroed.  Allocated memory contains junk, not zeros.  Failure to check that allocation succeeded.  Most C functions return a NULL pointer on failure.  new will throw std::bad_alloc exception on failure.  Unless specify T* p = new(std::nothrow) T ;  Use of invalid pointers.  Dereference NULLs, use after free, double free.  Failure to deallocate memory.  Memory leaks.  Zero-length allocations are implementation defined in C.

20 Inbound and Outbound Passwords Inbound Passwords  Used to authenticate users to application.  In cleartext only at point of user data entry.  Risks: online and offline password guessing. Outbound Passwords  Used to authenticate application to other systems, such as databases or CC processors.  Must be in cleartext to use.  Risks: information leakage. CSC 666: Secure Software Engineering

21 Securing Inbound Passwords Slide #21

22 Offline Password Cracking Password dictionary Usernames + Hashed Passwords word = Next dictionary word word hash = Hash(word) for each (username, hash) word hash == hash False True Store(usernames, word)

23 Hashing and Salting MD4 (Windows)  Unlimited password length.  Slow MD4 hash, no salt. SHA512crypt (Linux, Mac OS X)  Unlimited password length.  5000 iterations of SHA-512 hash function.  16 character salt. PBKDF2 (Password-Based Key Derivation Function 2)  Framework with configurable hash, iterations, salt. In.NET. Scrypt  Sequential, memory-hard hashing algorithm.  Defense against specialized hardware (GPUs, ASICs, FPGAs) CSC 666: Secure Software Engineering

24 Outbound Passwords Used by app to auth to db, other systems.  Must be accessible in cleartext at some point. Solutions  Store in source code. -Easy to view in source or binary form.  Store cleartext in a configuration file.  Store encrypted in a configuration file. -Use a good, known algorithm like AES. -Limit ACLs so only app can access.  Require admin enter password on restart. -PCI 3.6.6 requires key be split among admins.

25 CSC 666: Secure Software Engineering Secrets in Memory Attackers can obtain secrets from memory  Remote exploit: buffer overflow or fmt string  Physical attack: direct media access  Accidental leakage: core dumps or page files

26 CSC 666: Secure Software Engineering Securing Secrets in Memory  Minimize time spent holding secrets.  Decrypt data just before use.  Overwrite data after use.  Share secrets sparingly.  Do not store secrets on the client.  Erase secrets securely.  Explicitly overwrite memory.  Prevent unnecessary duplication.

27 CSC 666: Secure Software Engineering Locking Pages in Memory Prevent secrets from paging to disk. Does not prevent suspend or hibernate saving pages. Linux page locking mlock(const void *addr, size_t len) munlock(const void *addr, size_t len) Windows page locking VirtualLock(LPVOID lpAddress, SIZE_T dwSize); VirtualUnlock(LPVOID lpAddress, SIZE_T dwSize);

28 CSC 666: Secure Software Engineering Erasing Secrets Securely Garbage collecting languages  Essentially impossible to ensure secrets are erased immediately. Low level languages  Compiler can optimize away code that overwrites a buffer if buffer contents are not used later.  Use memset_s() if compiler supports C11.  Use SecureZeroMemory() in Windows.  If neither function is available, use volatile pointers to prevent compiler from optimizing away memory overwrites. Some compilers may still cause problems.

29 CSC 666: Secure Software Engineering Erasing Secrets Securely in C99 void auth_function() { char pass[32]; if (getpass(pass)) { // Do something with password } memset(pass, 0, sizeof(pass)); // Prevent memset from being optimized // away by using volatile pointers. *(volatile char *)pass = *(volatile char *)pass; }

30 References 1.David Abrahams, Exception-Safety in Generic Components. Lecture Notes In Computer Science: 69-79, 2000.Exception-Safety in Generic Components 2.Tom Cargill, Exception Handling: A False Sense of Security, C++ Report, Volume 6, Number 9, November-December 1994. 3.CERT, Error Handling, https://www.securecoding.cert.org/confluence/download/attachme nts/3524/error-handling.pdf, 2006. https://www.securecoding.cert.org/confluence/download/attachme nts/3524/error-handling.pdf 4.Brian Chess and Jacob West, Secure Programming with Static Analysis, Addison-Wesley, 2007. 5.Robert J. Ellison et. al., Survivability: Protecting Your Critical Systems, IEEE Computer, 1999. 6.Fred Long, CERT Secure Coding Standards: Error Handling, https://www.securecoding.cert.org/confluence/display/cplusplus/1 2.+Error+Handling+(ERR), 2009. https://www.securecoding.cert.org/confluence/display/cplusplus/1 2.+Error+Handling+(ERR) 7.Steve McConnell, Code Complete, 2 nd edition, Microsoft Press, 2004.


Download ppt "Secure Coding James Walden Northern Kentucky University."

Similar presentations


Ads by Google