Product SiteDocumentation Site

Fedora Security Team

Defensive Coding

A Guide to Improving Software Security

Edition 1

Florian Weimer

Red Hat Product Security Team

Legal Notice

Copyright © 2012 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. The original authors of this document, and Red Hat, designate the Fedora Project as the "Attribution Party" for purposes of CC-BY-SA. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, JBoss, MetaMatrix, Fedora, the Infinity Logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
For guidelines on the permitted uses of the Fedora trademarks, refer to https://fedoraproject.org/wiki/Legal:Trademark_guidelines.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
All other trademarks are the property of their respective owners.
Abstract
This document provides guidelines for improving software security through secure coding. It covers common programming languages and libraries, and focuses on concrete recommendations.

I. Programming Languages
1. The C Programming Language
1.1. The core language
1.1.1. Undefined behavior
1.1.2. Recommendations for pointers and array handling
1.1.3. Recommendations for integer arithmetic
1.1.4. Global variables
1.2. The C standard library
1.2.1. Absolutely banned interfaces
1.2.2. Functions to avoid
1.2.3. String Functions With Explicit Length Arguments
1.3. Memory allocators
1.3.1. malloc and related functions
1.3.2. alloca and other forms of stack-based allocation
1.3.3. Array allocation
1.3.4. Custom memory allocators
1.3.5. Conservative garbage collection
1.4. Other C-related topics
1.4.1. Wrapper functions
2. The C++ Programming Language
2.1. The core language
2.1.1. Array allocation with operator new[]
2.1.2. Overloading
2.1.3. ABI compatibility and preparing for security updates
2.1.4. C++0X and C++11 support
2.2. The C++ standard library
2.2.1. Containers and operator[]
3. The Java Programming Language
3.1. The core language
3.1.1. Inceasing robustness when reading arrays
3.1.2. Resource management
3.1.3. Finalizers
3.1.4. Recovering from exceptions and errors
3.2. Low-level features of the virtual machine
3.2.1. Reflection and private parts
3.2.2. Java Native Interface (JNI)
3.2.3. sun.misc.Unsafe
3.3. Interacting with the security manager
3.3.1. Security manager compatibility
3.3.2. Activating the security manager
3.3.3. Reducing trust in code
3.3.4. Re-gaining privileges
4. The Python Programming Language
4.1. Dangerous standard library features
4.2. Run-time compilation and code generation
4.3. Sandboxing
II. Specific Programming Tasks
5. Library Design
5.1. State management
5.1.1. Global state
5.1.2. Handles
5.2. Object orientation
5.3. Callbacks
5.4. Process attributes
6. File Descriptor Management
6.1. Closing descriptors
6.1.1. Error handling during descriptor close
6.1.2. Closing descriptors and race conditions
6.1.3. Lingering state after close
6.2. Preventing file descriptor leaks to child processes
6.3. Dealing with the select limit
7. File system manipulation
7.1. Working with files and directories owned by other users
7.2. Accessing the file system as a different user
7.3. File system limits
7.4. File system features
7.5. Checking free space
8. Temporary files
8.1. Obtaining the location of temporary directory
8.2. Named temporary files
8.3. Temporary files without names
8.4. Temporary directories
8.5. Compensating for unsafe file creation
9. Processes
9.1. Safe process creation
9.1.1. Obtaining the program path and the command line template
9.1.2. Bypassing the shell
9.1.3. Specifying the process environment
9.1.4. Robust argument list processing
9.1.5. Passing secrets to subprocesses
9.2. Handling child process termination
9.3. SUID/SGID processes
9.3.1. Accessing environment variables
9.4. Daemons
9.5. Semantics of command line arguments
9.6. fork as a primitive for parallelism
10. Serialization and Deserialization
10.1. Recommendations for manually written decoders
10.2. Protocol design
10.3. Library support for deserialization
10.4. XML serialization
10.4.1. External references
10.4.2. Entity expansion
10.4.3. XInclude processing
10.4.4. Algorithmic complexity of XML validation
10.4.5. Using Expat for XML parsing
10.4.6. Using Qt for XML parsing
10.4.7. Using OpenJDK for XML parsing and validation
10.5. Protocol Encoders
11. Cryptography
11.1. Primitives
11.2. Randomness
III. Implementing Security Features
12. Authentication and Authorization
12.1. Authenticating servers
12.2. Host-based authentication
12.3. UNIX domain socket authentication
12.4. AF_NETLINK authentication of origin
13. Transport Layer Security
13.1. Common Pitfalls
13.1.1. OpenSSL Pitfalls
13.1.2. GNUTLS Pitfalls
13.1.3. OpenJDK Pitfalls
13.1.4. NSS Pitfalls
13.2. TLS Clients
13.2.1. Implementation TLS Clients With OpenSSL
13.2.2. Implementation TLS Clients With GNUTLS
13.2.3. Implementing TLS Clients With OpenJDK
13.2.4. Implementing TLS Clients With NSS
13.2.5. Implementing TLS Clients With Python
A. Revision History