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-2014 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. Functions that are difficult to use
2.2.2. String handling with std::string
2.2.3. Containers and operator[]
2.2.4. Iterators
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
5. Shell Programming and bash
5.1. Consider alternatives
5.2. Shell language features
5.2.1. Parameter expansion
5.2.2. Double expansion
5.2.3. Other obscurities
5.3. Invoking external commands
5.4. Temporary files
5.5. Performing input validation
5.6. Guarding shell scripts against changes
6. The Go Programming Language
6.1. Memory safety
6.2. Error handling
6.3. Garbage Collector
6.4. Marshaling and unmarshaling
7. The Vala Programming Language
II. Specific Programming Tasks
8. Library Design
8.1. State management
8.1.1. Global state
8.1.2. Handles
8.2. Object orientation
8.3. Callbacks
8.4. Process attributes
9. File Descriptor Management
9.1. Closing descriptors
9.1.1. Error handling during descriptor close
9.1.2. Closing descriptors and race conditions
9.1.3. Lingering state after close
9.2. Preventing file descriptor leaks to child processes
9.3. Dealing with the select limit
10. File system manipulation
10.1. Working with files and directories owned by other users
10.2. Accessing the file system as a different user
10.3. File system limits
10.4. File system features
10.5. Checking free space
11. Temporary files
11.1. Obtaining the location of temporary directory
11.2. Named temporary files
11.3. Temporary files without names
11.4. Temporary directories
11.5. Compensating for unsafe file creation
12. Processes
12.1. Safe process creation
12.1.1. Obtaining the program path and the command line template
12.1.2. Bypassing the shell
12.1.3. Specifying the process environment
12.1.4. Robust argument list processing
12.1.5. Passing secrets to subprocesses
12.2. Handling child process termination
12.3. SUID/SGID processes
12.3.1. Accessing environment variables
12.4. Daemons
12.5. Semantics of command line arguments
12.6. fork as a primitive for parallelism
13. Serialization and Deserialization
13.1. Recommendations for manually written decoders
13.2. Protocol design
13.3. Fragmentation
13.3.1. Fragment IDs
13.4. Library support for deserialization
13.5. XML serialization
13.5.1. External references
13.5.2. Entity expansion
13.5.3. XInclude processing
13.5.4. Algorithmic complexity of XML validation
13.5.5. Using Expat for XML parsing
13.5.6. Using Qt for XML parsing
13.5.7. Using OpenJDK for XML parsing and validation
13.6. Protocol Encoders
14. Cryptography
14.1. Primitives
14.2. Randomness
15. RPM packaging
15.1. Generating X.509 self-signed certificates during installation
15.2. Generating X.509 self-signed certificates before service start
III. Implementing Security Features
16. Authentication and Authorization
16.1. Authenticating servers
16.2. Host-based authentication
16.3. UNIX domain socket authentication
16.4. AF_NETLINK authentication of origin
17. Transport Layer Security
17.1. Common Pitfalls
17.1.1. OpenSSL Pitfalls
17.1.2. GNUTLS Pitfalls
17.1.3. OpenJDK Pitfalls
17.1.4. NSS Pitfalls
17.2. TLS Clients
17.2.1. Implementation TLS Clients With OpenSSL
17.2.2. Implementation TLS Clients With GNUTLS
17.2.3. Implementing TLS Clients With OpenJDK
17.2.4. Implementing TLS Clients With NSS
17.2.5. Implementing TLS Clients With Python
A. Revision History