| FOREWORD | i |
| CREDITS
AND ACKNOWLEDGEMENTS | v |
| TABLE
OF CONTENTS | vii |
| List
of tables | xv |
| List
of figures | xv |
| 1
INTRODUCTION | 1 |
| 1.1
Document purpose and intended audience | 1 |
| 1.2
Document structure and content | 3 |
| 2
BACKGROUND: UNDERSTANDING THE PROBLEM | 6 |
| 2.1
What is secure software? | 6 |
| 2.2
Why does software assurance matter? | 8 |
| 2.3
Which software must always be secure? | 9 |
| 2.4
What makes software secure? | 10 |
| 2.5
Threats that target software | 15 |
| 2.5.1
Attacks that exploit software vulnerabilities | 19 |
| 2.5.2
Causes of weaknesses and vulnerabilities | 27 |
| 2.5.2.1
Does vulnerability avoidance equate to security? | 30 |
|
2.6
Security training, education, and professional certification for software
practitioners | 31 |
| 3
INTEGRATING SECURITY INTO THE SDLC | 34 |
| 3.1
Influence of how software comes to be on its security | 35 |
| 3.2
General software security principles | 36 |
| 3.2.1
Software assurance, information assurance, and system security | 37 |
| 3.3
Secure development life cycle activities and practices | 45 |
| 3.4
Secure version management and change control of SDLC artifacts | 50 |
| 3.5
Security assurance cases for software | 51 |
| 3.6
SDLC methodologies that aid in secure software production | 54 |
| 3.6.1
Secure SDLC methodologies | 54 |
| 3.6.2
Can agile methods produce secure software? | 56 |
| 3.6.3
Formal methods and secure software development | 64 |
| 4
REQUIREMENTS FOR SECURE SOFTWARE | 67 |
| 4.1
The challenge of negative and non-functional requirements | 69 |
| 4.2
Origins of requirements for secure software | 72 |
| 4.3
Deriving requirements that will ensure security of software | 74 |
| 4.4
Secure software requirements verification challenges | 77 |
| 4.5
Requirements engineering and security modeling methodologies and tools | 79 |
| 4.5.1
Attack modeling | 80 |
| 4.5.1.1
Security use cases, misuse cases, and abuse cases | 81 |
| 4.5.1.2
Attack patterns | 82 |
| 4.5.1.3
Threat modeling | 85 |
| 4.5.1.4
Other modeling techniques | 87 |
| 4.5.1.4.1
Attack trees and attack graphs | 87 |
| 4.5.1.4.2
Anti-models | 89 |
| 4.5.1.4.3
State-transition diagrams | 90 |
| 5
SECURE DESIGN PRINCIPLES AND PRACTICES | 91 |
| 5.1
Secure architecture considerations | 91 |
| 5.2
Secure software design principles and practices | 92 |
| 5.2.1
General Principle 1: Minimize the number of high-consequence targets | 93 |
| 5.2.1.1
Principle of least privilege | 93 |
| 5.2.1.2
Principle of separation of privileges, duties, and roles | 95 |
| 5.2.1.3
Principle of separation of domains | 96 |
| 5.2.2
General Principle 2: Don’t expose vulnerable or high-consequence components | 97 |
| 5.2.2.1
Keep program data, executables, and program control/configuration data separate | 97 |
| 5.2.2.2
Segregate trusted entities from untrusted entities | 98 |
| 5.2.2.3
Minimize the number of entry and exit points into and out of any entity | 101 |
| 5.2.2.4
Assume environment data is not trustworthy | 101 |
| 5.2.2.5
Use only safe interfaces to environment resources | 101 |
| 5.2.3
General Principle 3: Deny attackers the means to compromise | 102 |
| 5.2.3.1
Simplify the design | 102 |
| 5.2.3.2.
Hold all actors accountable, not just human users | 104 |
| 5.2.3.3
Avoid timing, synchronization, and sequencing issues | 105 |
| 5.2.3.4
Make secure states easy to enter and vulnerable states difficult to enter | 106 |
| 5.2.3.5
Design for controllability | 106 |
| 5.2.3.6
Design for secure failure | 107 |
| 5.2.3.7
Design for survivability | 107 |
5.2.3.8
Server functions should never rely on clients to perform high-consequence
functions or
trust client-originated data | 108 |
| 5.3
Modeling and risk analysis for architecture and design | 109 |
| 5.3.1
Leveraging misuse and abuse cases in architecture | 111 |
| 5.3.2
Leveraging attack patterns in architecture and design | 112 |
| 5.4
Relationship of security patterns to secure software | 114 |
| 5.5
Execution environment security constraints, protections, and services for
software | 117 |
| 5.5.1
Environment-level compartmentalization: constraint and isolation mechanisms | 119 |
| 5.5.1.1
Standard operating system access controls | 119 |
| 5.5.1.2
Trusted operating systems | 119 |
| 5.5.1.3
Security-enhanced operating systems | 120 |
| 5.5.1.4
Hardened and security-enhanced operating systems | 120 |
| 5.5.1.5
Minimized kernels and microkernels | 121 |
| 5.5.1.6
Virtual machines | 122 |
| 5.5.1.7
Trusted processor modules | 122 |
| 5.5.1.8
Tamper-resistant processors | 123 |
| 5.5.2
Application frameworks | 123 |
| 5.5.3
Benign software on a malicious host | 125 |
| 5.6
Secure architecture and design methodologies | 126 |
| 6
SECURE COMPONENT-BASED SOFTWARE ENGINEERING | 127 |
| 6.1
Architecture and design considerations for component-based software systems | 129 |
| 6.2.
Security issues associated with COTS and OSS components | 131 |
| 6.2.1
Lack of visibility (the “black box” problem) | 131 |
| 6.2.2
Ignorance of pedigree and provenance | 132 |
| 6.2.3
Questionable validity of security assumptions | 134 |
| 6.2.4
Presence of unused and unexpected functions: dormant, dead, and malicious code | 134 |
| 6.3
Security evaluation and selection of components | 136 |
| 6.3.1
Steps in a component security evaluation | 137 |
| 6.3.2
Questions to ask about components under evaluation | 140 |
| 6.4
Implementing secure component-based software | 141 |
| 6.5
Secure sustainment of component-based software | 142 |
| 7
SECURE CODING | 144 |
| 7.1
Secure coding principles and practices | 144 |
| 7.1.1
Keep code small and simple | 144 |
| 7.1.2
Use a consistent coding style | 145 |
| 7.1.3
Follow secure coding standards and/or guidelines | 145 |
| 7.1.4
Make code forward and backward traceable | 146 |
| 7.1.5
Code for reuse and maintainability | 146 |
| 7.1.6
Allocate memory and other resources carefully | 146 |
| 7.1.7
Minimize retention of state information | 147 |
| 7.1.8
Leverage security through obscurity only as an additional deterrence measure | 147 |
| 7.1.9
Avoid unauthorized privilege escalation | 147 |
| 7.1.10
Use consistent naming | 147 |
| 7.1.11
Use encapsulation cautiously | 148 |
| 7.1.12
Leverage attack patterns | 148 |
| 7.1.13
Input encoding and validation | 149 |
| 7.1.13.1
Implementing input validation | 149 |
| 7.1.13.1.1
Preliminary client-side validation | 151 |
| 7.1.13.1.2
XML schema and input validation | 151 |
| 7.1.13.2
Testing input validation logic | 152 |
| 7.1.14
Output filtering and sanitization | 153 |
| 7.1.15
Avoid security conflicts arising between native and non-native, passive and
dynamic code | 153 |
| 7.1.16
Review code during and after coding | 153 |
| 7.2
Survivability through error, anomaly, and exception handling | 157 |
| 7.3.1
Anomaly awareness | 159 |
| 7.3.2
Event monitors | 159 |
| 7.3.3
Security error and failure handling | 159 |
| 7.3.4
Core dump prevention | 160 |
| 7.4 Secure memory/cache
management | 160 |
| 7.4.1
Safe creation and deletion of temporary files | 161 |
| 7.5
Interprocess authentication | 162 |
| 7.5.1
Secure RPC | 163 |
| 7.6
Secure software localization | 163 |
| 7.7
Language-specific security considerations | 164 |
| 7.8
Tools that assist in secure coding and compilation | 166 |
| 7.8.1
Compiler security checking and enforcement | 167 |
| 7.8.2 Safe software libraries | 169 |
| 7.8.3
Runtime error checking and safety enforcement | 169 |
| 7.8.4
Code obfuscation | 169 |
| 8
RISK-BASED SOFTWARE SECURITY TESTING | 170 |
| 8.1
Test planning | 173 |
| 8.1.1
Test timing | 174 |
| 8.1.2
System and Application Security Checklists | 176 |
| 8.2
Software security test techniques | 178 |
| 8.2.1
White and grey box testing techniques | 178 |
| 8.2.1.1
Source code fault injection | 179 |
| 8.2.1.2
Dynamic code analysis | 181 |
| 8.2.1.3
Property-based testing | 182 |
| 8.2.2
Black box testing techniques | 182 |
| 8.2.2.1
Binary fault injection | 182 |
| 8.2.2.2
Fuzz testing | 184 |
| 8.2.2.3
Binary code analysis | 184 |
| 8.2.2.4
Byte code analysis | 185 |
| 8.2.2.5
Black box debugging | 185 |
| 8.2.2.6
Vulnerability scanning | 186 |
| 8.2.2.7
Penetration testing | 188 |
| 8.3
Interpreting and using test results | 189 |
| 9
SECURE DISTRIBUTION, DEPLOYMENT, AND SUSTAINMENT | 191 |
| 9.1
Preparations for secure distribution | 191 |
| 9.1.1
Review and sanitization of user-viewable source code | 192 |
9.1.1.1
Preventing disclosure of user-viewable source code and copying of all
browser-displayed
content | 195 |
| 9.1.2
Bytecode obfuscation to deter reverse engineering | 197 |
| 9.2
Secure distribution | 197 |
| 9.2.1
Protection for online distributions | 197 |
| 9.2.2
Protection for offline distributions | 197 |
| 9.3
Secure installation and configuration | 198 |
9.3.1
Instructions for configuring restrictive file system access controls for
initialization files and
target directories | 199 |
| 9.3.2
Instructions for validating install-time security assumptions | 199 |
| 9.3.3
Instructions for removing all unused and unreferenced files | 199 |
| 9.3.4
Instructions for changing of passwords and account names on default accounts | 200 |
| 9.3.5
Instructions for deleting unused default accounts | 200 |
| 9.3.6
Other considerations for locking down the execution environment | 201 |
| 9.4
Secure sustainment considerations | 202 |
| 9.4.1
Vulnerability management | 202 |
| 9.4.2
Software aging and security | 204 |
| APPENDIX
A: ABBREVIATIONS, ACRONYMS, AND DEFINITIONS | 207 |
| A.1
Abbreviations and acronyms | 207 |
| A.2
Definitions | 211 |
| APPENDIX
B: RESOURCES AND BIBLIOGRAPHY | 223 |
| B.1
Freely-Accessible Online resources | 223 |
| B.2
Restricted-Access Online Resources | 251 |
| B.3
Bibliography | 254 |
APPENDIX
C: SECURITY CONCERNS ASSOCIATED WITH SPECIFIC SOFTWARE TECHNOLOGIES,
METHODOLOGIES, AND PROGRAMMING LANGUAGES | 258 |
| C.1
Security concerns associated with Web service software | 258 |
| C.2
Security concerns associated with embedded system software | 259 |
| C.3
Formal methods and secure software | 262 |
| C.4
Security concerns and benefits associated with specific programming languages | 267 |
| C.4.1 C and C++ | 267 |
| C.4.2
Java | 268 |
| C.4.2.1
Secure Java development | 269 |
| C.4.3
C# and VB.NET | 271 |
| C.4.4
Ada | 273 |
| C.4.5
Ruby | 275 |
| C.4.6
Server-side scripting languages | 276 |
| C.4.6.1
Perl | 278 |
| C.4.6.2
PHP | 279 |
| C.4.6.2.1
Setting register_globals to “Off” | 280 |
| C.4.6.2.2
PHP implementation of input validation | 282 |
| C.4.6.2.3
Naming conventions for variables | 283 |
| C.4.6.3
Python | 283 |
| C.4.6.4
ASP and ASP.NET | 284 |
| C.4.7
Client-side scripting languages | 285 |
| C.4.7.1
JavaScript | 286 |
| C.4.7.2.
AJAX (Asynchronous JavaScript And XML) | 287 |
| C.4.7.3
VBScript | 289 |
| C.4.7.4
TCL | 289 |
| C.4.8
Mobile code security | 290 |
| C.4.8.1
Digital signing of mobile code | 291 |
| C.4.8.2 Mobile code signature validation | 291 |
| C.4.9
Shell scripting languages | 292 |
| C.4.10 Secure language variants and derivatives | 292 |
| C.5.
Leveraging Design by Contract™ for software security | 293 |
| APPENDIX
D: SECURITY CHECKLIST EXCERPTS | 296 |
| |
| |