SECURE PROGRAMMING Digest of remaining topics
Handling errors and exceptionsReturn valuesexceptionsresource leakslogs Web ApplicationsI/O validationHTTP considerations: POST not GET Privacy and SecretsIdentifying informationHandling passwordsCryptography and random numbersSecrets in memory Privileged programs Overview Memory allocation vulnerabilities and mitigation strategies Integer problems, vulnerabilities and mitigation strategies Formatted output problems Concurrency problems, pitfalls, vulnerabilities, mitigation strategies. File I/O: Basics, access control, file identification, race conditions TOCTOU, other problems, mitigation strategies
Mitigation strategies: Ste freed pointers to null (not practical) Consistent memory management conventions phkmalloc (for virtual memory, but has stronger checks) Randomization of allocated memory chunks. OpenBSD use phkmalloc and randomization at the OS level. Also guard pages. Memory allocation vulnerabilities and mitigation strategies Buffer overflows Double free vulnerability Writing to free memory Look-aside table All of these allow overwriting allocation pointers to point to stack memory, etc...
Runtime tools: Purify (IBM) Valgrind Insure++ Application verifier Memory allocation mitigation strategies jemalloc, based on phkmalloc, emphasis on scalability and fragmentation behavior. Heap separated into per-thread subheaps called arenas Static analysis (special rules on page 218)
Overflows possible with +, -, *, %, ++, --, +=, <<, unary -. = can cause truncation. Security consequences: Integers are used for array index malloc argument array bound pointer arithmetic object length or size In security critical code Integer problems, vulnerabilities and mitigation strategies Signed and unsigned integers; biggest problem is overflow. Consider: in unsigned integers, (biggest number) + 1 =0 For signed integers, (biggest number) +1 = -(biggest number) – 1 Biggest integer usually called intmax or uintmax. Many types: char, short, int, long, long long, ptrdiff, size_t Conversions can be a problem: converting from signed to unsigned can happen...
Overflows are hard to check for: Use assembly language Use pre/post condition checking Vulnerabilities arise whenever wrapped or trncated integers are used for the operations above. jpg example. general example Integer problems, vulnerabilities and mitigation strategies (2) Every overflow, every instance of a “too large” integer is a potential vulnerability. Specially problematic are truncations: mitigation: avoid. Avoid situations where truncations may end up with a 1 in the sign bit for a positive number. “Undoing” the truncation will not work.
More mitigation strategies: Overflow detection: <fenv.h> <ienv.h>??? Compiler-generated runtime checks Microsoft studio gcc -trapv ?? Integer problems, mitigation strategies (1) Mitigation strategies... • Use precondition and/or postcondition for overflows. • Use temporary variables that are large enough for the result. • Use a secure integer library.
Static Analysis; Rose Splint Microsoft Visual Studio Testing??? Source code audits proper types ranges checked nonegative variables declared unsigned. Integer problems, mitigation strategies (2) verifiably in-range operations • Modwrap semantics • Restricted range usage • As-If infinitely ranged integer model
Mitigation Strategies: Disable %n?? Exclude user input from format strings Do not use dynamic form strings Restricting bytes written (%.xxn) Use snprintf and vsnprintf ?? or asprintf,vasprintf,slprintf Use _s versions iostream Formatted output problems The problem: a data generated format. Oftentimes, the data generated format will cause data overwriting (buffer overflows) sprintf is particularly dangerous, also %n Internationalization is a problem Stack randomization will not work
Static Binary Analysis: Checks for stack correction < minimum value variable vs constant format string Formatted ouput mitigation strategies Testing Compiler checks gcc -wformat... Static Taint analysis Modifying the API: Safer variadic function handling Exec shield (stack randomization) FormatGuard (checks argument counts)
Mitigation strategies: Sychronization primitives: mutex variables lock guards, …. Atomic operations Fences Semaphores pipes Critical section objects Concurrency problems, pitfalls, vulnerabilities, mitigation strategies Multithreading != concurrency != parallelism Common errors: Race conditions: non-deterministic behavior: • Concurrency, shared object, state change
Pitfalls: (pp 384, 385 Concurrency problems, pitfalls, vulnerabilities, mitigation strategies Mitigation strategies for race conditions: Reentrant code Thread safe code
Vulnerabilities in Syscall wrappers (page 400) Concurrency problems, pitfalls, vulnerabilities, mitigation strategies Deadlock Prematurely releasing a lock (reads must be protected also) Excessive contention ABA problem Spinlocks
File ID problems .. allows monkey business. (File traversal vulnerability) Equivalence errors Symbolic links Canonicalization: realpath() Hard links Device files File attributes – stat File I/O: Basics, …. File structure, directory tree Special files File I/O interfaces Data Streams File manipulation Access control Managing privileges, setiud/setgid Managing Permissions: Secure directories Permissions on newly created files
Mitigation strategies... Close the race window mutex Thread safe functions Use atomic operations Do not reopen files check for symlinks, p 464/5 check for TOCTOU Eliminate shared objects Use file descriptors, not file names File I/O TOCTOU Create without replace (specify with flags in open, page 454) Exclusive access in Unix is sometimes not possible. Shared directories Unique/unpredictable file names Create w/o replace Exclusive access appropriate privileges Removal before termination (p 461)
File I/O mitigations Control access to the race object Principle of least privilege Secure directories Chroot jails Container virtualization Limit exposure Race Detection Tools Static Analysis (NP-complete) Dynamic Analysis (overhead)
Preventing resource leaks hard to track down Watch for multiple return statements, unexpected exceptions. Classes can be used to advantage. Logging and debugging Centralize the output operation Provide time stamps Log everything! Protect the logs Handling errors and exceptions Handling errors: with return values easy to ignore errors code hard to r/w no conventions with exceptions try/catch mechanism finally clause in some languages non-caught exceptions may cause problems
Web Applications I/O validation: Expect that the browser has been subverted Assume that the browser is an open book. Don't trust anything from the browser. Use POST, not GET (less data leaked)
Web Applications I/O validation: Expect that the browser has been subverted Assume that the browser is an open book. Don't trust anything from the browser. Use POST, not GET (less data leaked) Maintain Session state Session timeouts Begin a new session upon authentication
Random Numbers: Useful for cryptography, port randomization, session identifiers, etc. Cryptography: Choose a good algorithm Keep secrets out of memory as much as possible; once out, overwrite it. (Easier said than done!) Privacy and Secrets Identifying Private Information Handling Private Information: Minimize exposure Keep out of logs Keep out of shared memory if possible. Outbound Passwords: Keep out of source code Store them in an encrypted configuration file.
Advice: Mistrust everything. Check everything! Use safe directories Check TOCTOU Disable all traps Check every condition: Murphy's law is on the rampage! Die on errors! Safely name temporary files. (mkstemp) Privileged Programs setuid/setgid Principle of least privilege syscalls for changing privileges (seteuid/ setreuid/setresuid) Attack Race conditions