Writing secure code : practical strategies and proven techniques for building secure applications in a networked world

Bibliographic Information

Writing secure code : practical strategies and proven techniques for building secure applications in a networked world

Michael Howard and David LeBlanc

Microsoft Press, c2003

2nd ed

Available at  / 4 libraries

Search this Book/Journal

Note

Includes bibliographical references (p. 741-745) and index

Description and Table of Contents

Description

Keep black-hat hackers at bay with the tips and techniques in this entertaining, eye-opening book! Developers will learn how to padlock their applications throughout the entire development process-from designing secure applications to writing robust code that can withstand repeated attacks to testing applications for security flaws. Easily digested chapters reveal proven principles, strategies, and coding techniques. The authors-two battle-scarred veterans who have solved some of the industry's toughest security problems-provide sample code in several languages. This edition includes updated information about threat modeling, designing a security process, international issues, file-system issues, adding privacy to applications, and performing security code reviews. It also includes enhanced coverage of buffer overruns, Microsoft .NET security, and Microsoft ActiveX development, plus practical checklists for developers, testers, and program managers.

Table of Contents

  • Introduction xxiii PART I CONTEMPORARY SECURITY 1 The Need for Secure Systems 3 Applications on the Wild Wild Web 5 The Need for Trustworthy Computing 7 Getting Everyone s Head in the Game 7 Using Tact to Sell Security to the Organization 8 Using Subversion 11 Some Ideas for Instilling a Security Culture 13 Get the Boss to Send an E-Mail 14 Nominate a Security Evangelist 15 The Attacker s Advantage and the Defender s Dilemma 19 Principle #1: The defender must defend all points
  • the attacker can choose the weakest point. 19 Principle #2: The defender can defend only against known attacks
  • the attacker can probe for unknown vulnerabilities. 20 Principle #3: The defender must be constantly vigilant
  • the attacker can strike at will. 20 Principle #4: The defender must play by the rules
  • the attacker can play dirty. 21 Summary 21 2 The Proactive Security Development Process 23 Process Improvements 25 The Role of Education 26 Resistance to Mandatory Training 29 Ongoing Training 29 Advancing the Science of Security 29 Education Proves the More Eyes Fallacy 31 Now the Evidence! 31 Design Phase 32 Security Questions During Interviews 33 Define the Product Security Goals 34 Security Is a Product Feature 37 Making Time for Security 40 Threat Modeling Leads to Secure Design 41 Build End-of-Life Plans for Insecure Features 41 Setting the Bug Bar 41 Security Team Review 43 Development Phase 43 Be Hardcore About Who Can Check In New Code (Check-Ins Checked) 43 Security Peer Review of New Code (Check-Ins Checked) 44 Define Secure Coding Guidelines 44 Review Old Defects 44 External Security Review 45 Security Push 45 Be Mindful of Your Bug Counts 46 Keep Track of Bug Metrics 46 No Surprises and No Easter Eggs! 47 Test Phase 47 Shipping and Maintenance Phases 47 How Do You Know When You re Done? 47 Response Process 48 Accountability 49 Summary 49 3 Security Principles to Live By 51 SD3: Secure by Design, by Default, and in Deployment 51 Secure by Design 51 Secure by Default 53 Secure in Deployment 53 Security Principles 54 Learn from Mistakes 54 Minimize Your Attack Surface 57 Employ Secure Defaults 57 Use Defense in Depth 59 Use Least Privilege 60 Backward Compatibility Will Always Give You Grief 62 Assume External Systems Are Insecure 63 Plan on Failure 64 Fail to a Secure Mode 64 Remember That Security Features != Secure Features 66 Never Depend on Security Through Obscurity Alone 66 Don t Mix Code and Data 67 Fix Security Issues Correctly 67 Summary 68 4 Threat Modeling 69 Secure Design Through Threat Modeling 70 Assemble the Threat-Modeling Team 72 Decompose the Application 73 Determine the Threats to the System 83 Rank the Threats by Decreasing Risk 93 Choose How to Respond to the Threats 106 Choose Techniques to Mitigate the Threats 107 Security Techniques 108 Authentication 109 Authorization 114 Tamper-Resistant and Privacy-Enhanced Technologies 115 Protect Secrets, or Better Yet, Don t Store Secrets 116 Encryption, Hashes, MACs, and Digital Signatures 116 Auditing 117 Filtering, Throttling, and Quality of Service 118 Least Privilege 118 Mitigating the Sample Payroll Application Threats 118 A Cornucopia of Threats and Solutions 120 Summary 124 PART II SECURE CODING TECHNIQUES 5 Public Enemy #1: The Buffer Overrun 127 Stack Overruns 129 Heap Overruns 138 Array Indexing Errors 144 Format String Bugs 147 Unicode and ANSI Buffer Size Mismatches 153 A Real Unicode Bug Example 154 Preventing Buffer Overruns 155 Safe String Handling 156 A Word of Caution About String-Handling Functions 166 The Visual C++ .NET /GS Option 167 Summary 170 6 Determining Appropriate Access Control 171 Why ACLs Are Important 171 A Diversion: Fixing the Registry Code 173 What Makes Up an ACL? 175 A Method of Choosing Good ACLs 178 Effective Deny ACEs 180 Creating ACLs 181 Creating ACLs in Windows NT 4 181 Creating ACLs in Windows 2000 185 Creating ACLs with Active Template Library 189 Getting the ACE Order Right 191 Be Wary of the Terminal Server and Remote Desktop SIDs 193 NULL DACLs and Other Dangerous ACE Types 195 NULL DACLs and Auditing 197 Dangerous ACE Types 197 What If I Can t Change the NULL DACL? 198 Other Access Control Mechanisms 199 .NET Framework Roles 199 COM+ Roles 201 IP Restrictions 202 SQL Server Triggers and Permissions 203 A Medical Example 203 An Important Note About Access Control Mechanisms 205 Summary 206 7 Running with Least Privilege 207 Least Privilege in the Real World 208 Viruses and Trojans 209 Web Server Defacements 210 Brief Overview of Access Control 211 Brief Overview of Privileges 211 SeBackupPrivilege Issues 212 SeRestorePrivilege Issues 215 SeDebugPrivilege Issues 215 SeTcbPrivilege Issues 216 SeAssignPrimaryTokenPrivilege and SeIncreaseQuotaPrivilege Issues 217 SeLoadDriverPrivilege Issues 217 SeRemoteShutdownPrivilege Issues 217 SeTakeOwnershipPrivilege Issues 217 Brief Overview of Tokens 218 How Tokens, Privileges, SIDs, ACLs, and Processes Relate 218 SIDs and Access Checks, Privileges and Privilege Checks 219 Three Reasons Applications Require Elevated Privileges 220 ACL Issues 220 Privilege Issue 221 Using LSA Secrets 221 Solving the Elevated Privileges Issue 222 Solving ACL Issues 222 Solving Privilege Issues 223 Solving LSA Issues 223 A Process for Determining Appropriate Privilege 223 Step 1: Find Resources Used by the Application 224 Step 2: Find Privileged APIs Used by the Application 224 Step 3: Which Account Is Required? 226 Step 4: Get the Token Contents 226 Step 5: Are All the SIDs and Privileges Required? 232 Step 6: Adjust the Token 233 Low-Privilege Service Accounts in Windows XP and Windows .NET Server 2003 248 The Impersonate Privilege and Windows .NET Server 2003 250 Debugging Least-Privilege Issues 251 Why Applications Fail as a Normal User 251 How to Determine Why Applications Fail 252 Summary 258 8 Cryptographic Foibles 259 Using Poor Random Numbers 259 The Problem: rand 260 Cryptographically Random Numbers in Win32 262 Cryptographically Random Numbers in Managed Code 268 Cryptographically Random Numbers in Web Pages 269 Using Passwords to Derive Cryptographic Keys 269 Measuring the Effective Bit Size of a Password 270 Key Management Issues 272 Long-Term and Short-Term Keys 274 Use Appropriate Key Lengths to Protect Data 274 Keep Keys Close to the Source 276 Key Exchange Issues 279 Creating Your Own Cryptographic Functions 281 Using the Same Stream-Cipher Encryption Key 283 Why People Use Stream Ciphers 284 The Pitfalls of Stream Ciphers 284 What If You Must Use the Same Key? 287 Bit-Flipping Attacks Against Stream Ciphers 289 Solving Bit-Flipping Attacks 290 When to Use a Hash, Keyed Hash, or Digital Signature 290 Reusing a Buffer for Plaintext and Ciphertext 296 Using Crypto to Mitigate Threats 297 Document Your Use of Cryptography 298 9 Protecting Secret Data 299 Attacking Secret Data 300 Sometimes You Don t Need to Store a Secret 301 Creating a Salted Hash 302 Using PKCS #5 to Make the Attacker s Job Harder 303 Getting the Secret from the User 305 Protecting Secrets in Windows 2000 and Later 305 A Special Case: Client Credentials in Windows XP 309 Protecting Secrets in Windows NT 4 311 Protecting Secrets in Windows 95, Windows 98, Windows Me, and Windows CE 315 Getting Device Details Using PnP 316 Not Opting for a Least Common Denominator Solution 320 Managing Secrets in Memory 321 A Compiler Optimization Caveat 322 Encrypting Secret Data in Memory 326 Locking Memory to Prevent Paging Sensitive Data 327 Protecting Secret Data in Managed Code 329 Managing Secrets in Memory in Managed Code 335 Raising the Security Bar 336 Storing the Data in a File on a FAT File System 337 Using an Embedded Key and XOR to Encode the Data 337 Using an Embedded Key and 3DES to Encrypt the Data 337 Using 3DES to Encrypt the Data and Storing a Password in the Registry 337 Using 3DES to Encrypt the Data and Storing a Strong Key in the Registry 337 Using 3DES to Encrypt the Data, Storing a Strong Key in the Registry, and ACLing the File and the Registry Key 338 Using 3DES to Encrypt the Data, Storing a Strong Key in the Registry, Requiring the User to Enter a Password, and ACLing the File and the Registry Key 338 Trade-Offs When Protecting Secret Data 338 Summary 339 10 All Input Is Evil! 341 The Issue 342 Misplaced Trust 343 A Strategy for Defending Against Input Attacks 345 How to Check Validity 347 Tainted Variables in Perl 349 Using Regular Expressions for Checking Input 350 Be Careful of What You Find Did You Mean to Validate? 352 Regular Expressions and Unicode 353 A Regular Expression Rosetta Stone 358 Regular Expressions in Perl 358 Regular Expressions in Managed Code 359 Regular Expressions in Script 360 Regular Expressions in C++ 360 A Best Practice That Does Not Use Regular Expressions 361 Summary 362 11 Canonical Representation Issues 363 What Does Canonical Mean, and Why Is It a Problem? 364 Canonical Filename Issues 364 Bypassing Napster Name Filtering 364 Vulnerability in Apple Mac OS X and Apache 365 DOS Device Names Vulnerability 365 Sun Microsystems StarOffice /tmp Directory Symbolic-Link Vulnerability 366 Common Windows Canonical Filename Mistakes 367 Canonical Web-Based Issues 373 Bypassing AOL Parental Controls 373 Bypassing eEye s Security Checks 374 Zones and the Internet Explorer 4 "Dotless-IP Address" Bug 374 Internet Information Server 4.0 ::$DATA Vulnerability 375 When is a Line Really Two Lines? 377 Yet Another Web Issue Escaping 378 Visual Equivalence Attacks and the Homograph Attack 382 Preventing Canonicalization Mistakes 383 Don t Make Decisions Based on Names 383 Use a Regular Expression to Restrict What s Allowed in a Name 383 Stopping 8.3 Filename Generation 385 Don t Trust the PATH Use Full Path Names 385 Attempt to Canonicalize the Name 386 Calling CreateFile Safely 390 Web-Based Canonicalization Remedies 391 Restrict What Is Valid Input 391 Be Careful When Dealing with UTF-8 391 ISAPIs Between a Rock and a Hard Place 392 A Final Thought: Non-File-Based Canonicalization Issues 393 Server Names 393 Usernames 394 Summary 396 12 Database Input Issues 397 The Issue 398 Pseudoremedy #1: Quoting the Input 401 Pseudoremedy #2: Use Stored Procedures 402 Remedy #1: Never Ever Connect as sysadmin 403 Remedy #2: Building SQL Statements Securely 404 Building SQL Stored Procedures Securely 406 An In-Depth Defense in Depth Example 407 Summary 411 13 Web-Specific Input Issues 413 Cross-Site Scripting: When Output Turns Bad 413 Sometimes the Attacker Doesn t Need a <SCRIPT> Block 417 The Attacker Doesn t Need the User to Click a Link! 418 Other XSS-Related Attacks 418 XSS Attacks Against Local Files 418 XSS Attacks Against HTML Resources 420 XSS Remedies 421 Encoding Output 422 Adding Double Quotes Around All Tag Properties 422 Inserting Data in the innerText Property 423 Forcing the Codepage 423 The Internet Explorer 6.0 SP1 HttpOnly Cookie Option 424 Internet Explorer "Mark of the Web" 425 Internet Explorer <FRAME SECURITY> Attribute 426 ASP.NET 1.1 ValidateRequest configuration option 427 Don t Look for Insecure Constructs 428 But I Want Users to Post HTML to My Web Site! 430 How to Review Code for XSS Bugs 431 Other Web-Based Security Topics 431 eval() Can Be Bad 431 HTTP Trust Issues 432 ISAPI Applications and Filters 433 Be Wary of "Predictable Cookies" 436 SSL/TLS Client Issues 437 Summary 438 14 Internationalization Issues 439 The Golden I18N Security Rules 440 Use Unicode in Your Application 440 Prevent I18N Buffer Overruns 441 Words and Bytes 442 Validate I18N 443 Visual Validation 443 Do Not Validate Strings with LCMapString 443 Use CreateFile to Validate Filenames 443 Character Set Conversion Issues 444 Use MultiByteToWideChar with MB_PRECOMPOSED and MB_ERR_INVALID_CHARS 444 Use WideCharToMultiByte with WC_NO_BEST_FIT_CHARS 445 Comparison and Sorting 448 Unicode Character Properties 448 Normalization 450 Summary 451 PART III EVEN MORE SECURE CODING TECHNIQUES 15 Socket Security 455 Avoiding Server Hijacking 456 TCP Window Attacks 463 Choosing Server Interfaces 464 Accepting Connections 464 Writing Firewall-Friendly Applications 470 Use One Connection to Do the Job 471 Don t Require the Server to Connect Back to the Client 471 Use Connection-Based Protocols 472 Don t Multiplex Your Application over Another Protocol 472 Don t Embed Host IP Addresses in Application-Layer Data 473 Make Your Application Configurable 473 Spoofing and Host-Based and Port-Based Trust 473 IPv6 Is Coming! 474 Summary 476 16 Securing RPC, ActiveX Controls, and DCOM 477 An RPC Primer 478 What Is RPC? 478 Creating RPC Applications 479 How RPC Applications Communicate 481 Secure RPC Best Practices 482 Use the /robust MIDL Switch 483 Use the [range] Attribute 483 Require Authenticated Connections 484 Use Packet Privacy and Integrity 489 Use Strict Context Handles 491 Don t Rely on Context Handles for Access Checks 492 Be Wary of NULL Context Handles 493 Don t Trust Your Peer 494 Use Security Callbacks 495 Implications of Multiple RPC Servers in a Single Process 497 Use Mainstream Protocols 499 Secure DCOM Best Practices 499 DCOM Basics 500 Application-Level Security 502 DCOM User Contexts 502 Programmatic Security 505 Sources and Sinks 508 An ActiveX Primer 509 Secure ActiveX Best Practices 509 What ActiveX Components Are Safe for Initialization and Safe for Scripting? 510 Best Practices for Safe for Initialization and Scripting 511 Summary 515 17 Protecting Against Denial of Service Attacks 517 Application Failure Attacks 517 CPU Starvation Attacks 521 Memory Starvation Attacks 529 Resource Starvation Attacks 530 Network Bandwidth Attacks 532 Summary 533 18 Writing Secure .NET Code 535 Code Access Security: In Pictures 537 FxCop: A "Must-Have" Tool 539 Assemblies Should Be Strong-Named 540 Strong-Named Assemblies and ASP.NET 542 Specify Assembly Permission Requirements 542 Request Minimal Permission Set 543 Refuse Unneeded Permissions 544 Request Optional Permissions 544 Overzealous Use of Assert 545 Further Information Regarding Demand and Assert 547 Keep the Assertion Window Small 549 Demands and Link Demands 550 An Example LinkDemand Security Bug 551 Use SuppressUnmanagedCodeSecurityAttribute with Caution 552 Remoting Demands 553 Limit Who Uses Your Code 554 No Sensitive Data in XML or Configuration Files 555 Review Assemblies That Allow Partial Trust 556 Check Managed Wrappers to Unmanaged Code for Correctness 557 Issues with Delegates 558 Issues with Serialization 558 The Role of Isolated Storage 559 Disable Tracing and Debugging Before Deploying ASP.NET Applications 561 Do Not Issue Verbose Error Information Remotely 561 Deserializing Data from Untrusted Sources 562 Don t Tell the Attacker Too Much When You Fail 562 Summary 564 PART IV SPECIAL TOPICS 19 Security Testing 567 The Role of the Security Tester 567 Security Testing Is Different 568 Building Security Test Plans from a Threat Model 569 Decompose the Application 570 Identify the Component Interfaces 570 Rank the Interfaces by Potential Vulnerability 572 Ascertain the Data Structures Used by Each Interface 573 Attacking Applications with STRIDE 573 Attacking with Data Mutation 575 Before Testing 587 Building Tools to Find Flaws 588 Testing Clients with Rogue Servers 606 Should a User See or Modify That Data? 607 Testing with Security Templates 607 When You Find a Bug, You re Not Done! 609 Test Code Should Be of Great Quality 610 Test the End-to-End Solution 611 Determining Attack Surface 611 Determine Root Attack Vectors 611 Determine Bias For Attack Vectors 612 Count the Biased Vectors in the Product 612 Summary 613 20 Performing a Security Code Review 615 Dealing with Large Applications 617 A Multiple-Pass Approach 618 Low-Hanging Fruit 619 Integer Overflows 620 A Related Issue: Integer Underflows 624 Checking Returns 624 Perform an Extra Review of Pointer Code 625 Never Trust the Data 625 Sumary 626 21 Secure Software Installation 627 Principle of Least Privilege 628 Clean Up After Yourself! 630 Using the Security Configuration Editor 630 Low-Level Security APIs 638 Using the Windows Installer 638 Summary 640 22 Building Privacy into Your Application 641 Malicious vs. Annoying Invasions of Privacy 642 Major Privacy Legislation 643 Personally Identifiable Information 643 The EU Directives on Data Protection 643 Safe Harbor Principles 644 Other Privacy Legislation 646 Privacy vs. Security 646 Building a Privacy Infrastructure 647 The Role of the Chief Privacy Officer 648 The Role of the Privacy Advocate 648 Designing Privacy-Aware Applications 649 Including Privacy in the Development Process 649 Exploring Privacy Features 652 Summary 662 23 General Good Practices 663 Don t Tell the Attacker Anything 663 Service Best Practices 663 Security, Services, and the Interactive Desktop 664 Service Account Guidelines 665 Don t Leak Information in Banner Strings 667 Be Careful Changing Error Messages in Fixes 668 Double-Check Your Error Paths 668 Keep It Turned Off! 668 Kernel-Mode Mistakes 668 High-Level Security Issues 669 Handles 670 Symbolic Links 670 Quota 670 Serialization Primitives 670 Buffer-Handling Issues 671 IRP Cancellation 673 Add Security Comments to Code 674 Leverage the Operating System 674 Don t Rely on Users Making Good Decisions 675 Calling CreateProcess Securely 675 Do Not Pass NULL for lpApplicationName 677 Use Quotes Around the Path to Executable in lpCommandLine 677 Don t Create Shared/Writable Segments 677 Using Impersonation Functions Correctly 678 Don t Write User Files to \Program Files 678 Don t Write User Data to HKLM 679 Don t Open Objects for FULL_CONTROL or ALL_ACCESS 679 Object Creation Mistakes 679 Care and Feeding of CreateFile 681 Creating Temporary Files Securely 682 Implications of Setup Programs and EFS 686 File System Reparse Point Issues 686 Client-Side Security Is an Oxymoron 687 Samples Are Templates 688 Dogfood Your Stuff! 688 You Owe It to Your Users If 689 Determining Access Based on an Administrator SID 689 Allow Long Passwords 690 Be Careful with _alloca 691 ATL Conversion Macros 691 Don t Embed Corporate Names 692 Move Strings to a Resource DLL 693 Application Logging 693 Migrate Dangerous C/C++ to Managed Code 694 24 Writing Security Documentation and Error Messages 695 Security Issues in Documentation 695 The Basics 696 Threat Mitigation Through Documentation 697 Documenting Security Best Practices 698 Security Issues in Error Messages 700 A Typical Security Message 700 Information Disclosure Issues 701 Informed Consent 702 Progressive Disclosure 704 Be Specific 705 Consider Not Asking the Question 706 Usability Test Your Security Messages 707 A Note When Reviewing Product Specifications 708 Security Usability 708 Summary 709 PART V APPENDIXES A Dangerous APIs 713 B Ridiculous Excuses We ve Heard 723 C A Designer s Security Checklist 729 D A Developer s Security Checklist 731 E A Tester s Security Checklist 737 A Final Thought 739 ANNOTATED BIBLIOGRAPHY 741 INDEX

by "Nielsen BookData"

Details

Page Top