Special Offers

Writing Secure Code, Second Edition
Author Michael Howard and David LeBlanc
Pages 800
Disk N/A
Level Intermediate
Published 12/04/2002
ISBN 9780735617223
Price $49.99
To see this book's discounted price, select a reseller below.

More Information

About the Book
Table of Contents
Sample Chapter
Companion Content
Related Series
Related Books
About the Author

Support: Book & CD

Rate this book
Barnes Noble Amazon Quantum Books


Table of Contents

1 The Need for Secure Systems3
    Applications on the Wild Wild Web5
    The Need for Trustworthy Computing7
    Getting Everyone's Head in the Game7
        Using Tact to Sell Security to the Organization8
        Using Subversion11
    Some Ideas for Instilling a Security Culture13
        Get the Boss to Send an E-Mail14
        Nominate a Security Evangelist15
    The Attacker's Advantage and the Defender's Dilemma19
        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
2 The Proactive Security Development Process23
    Process Improvements25
    The Role of Education26
        Resistance to Mandatory Training29
        Ongoing Training29
        Advancing the Science of Security29
        Education Proves the More Eyes Fallacy31
        Now the Evidence!31
    Design Phase32
        Security Questions During Interviews33
        Define the Product Security Goals34
        Security Is a Product Feature37
        Making Time for Security40
        Threat Modeling Leads to Secure Design41
        Build End-of-Life Plans for Insecure Features41
        Setting the Bug Bar41
        Security Team Review43
    Development Phase43
        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 Guidelines44
        Review Old Defects44
        External Security Review45
        Security Push45
        Be Mindful of Your Bug Counts46
        Keep Track of Bug Metrics46
        No Surprises and No Easter Eggs!47
    Test Phase47
    Shipping and Maintenance Phases47
        How Do You Know When You're Done?47
        Response Process48
3  Security Principles to Live By51
    SD3: Secure by Design, by Default, and in Deployment51
        Secure by Design51
        Secure by Default53
        Secure in Deployment53
    Security Principles54
        Learn from Mistakes54
        Minimize Your Attack Surface57
        Employ Secure Defaults57
        Use Defense in Depth59
        Use Least Privilege60
        Backward Compatibility Will Always Give You Grief62
        Assume External Systems Are Insecure63
        Plan on Failure64
        Fail to a Secure Mode64
        Remember That Security Features != Secure Features66
        Never Depend on Security Through Obscurity Alone66
        Don't Mix Code and Data67
        Fix Security Issues Correctly67
4  Threat Modeling69
    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
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
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 Key338
        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 Key338
    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 Perl349
    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 Vulnerability375
        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 Remedies421
        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 Bugs431
    Other Web-Based Security Topics431
        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
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 Trust473
    IPv6 Is Coming! 474
    Summary 476
16  Securing RPC, ActiveX Controls, and DCOM 477
    An RPC Primer 478
        What Is RPC?478
        Creating RPC Applications479
        How RPC Applications Communicate481
    Secure RPC Best Practices482
        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 Checks492
        Be Wary of NULL Context Handles 493
        Don't Trust Your Peer494
        Use Security Callbacks 495
        Implications of Multiple RPC Servers in a Single Process497
        Use Mainstream Protocols 499
    Secure DCOM Best Practices 499
        DCOM Basics500
        Application-Level Security 502
        DCOM User Contexts502
        Programmatic Security 505
        Sources and Sinks508
    An ActiveX Primer509
    Secure ActiveX Best Practices509
        What ActiveX Components Are Safe for Initialization and Safe for Scripting? 510
        Best Practices for Safe for Initialization and Scripting511
17  Protecting Against Denial of Service Attacks 517
    Application Failure Attacks 517
    CPU Starvation Attacks521
    Memory Starvation Attacks529
    Resource Starvation Attacks530
    Network Bandwidth Attacks 532
18  Writing Secure .NET Code535
    Code Access Security: In Pictures 537
    FxCop: A "Must-Have" Tool 539
    Assemblies Should Be Strong-Named540
        Strong-Named Assemblies and ASP.NET 542
    Specify Assembly Permission Requirements 542
        Request Minimal Permission Set543
        Refuse Unneeded Permissions544
        Request Optional Permissions544
    Overzealous Use of Assert 545
    Further Information Regarding Demand and Assert547
    Keep the Assertion Window Small 549
    Demands and Link Demands550
        An Example LinkDemand Security Bug 551
    Use SuppressUnmanagedCodeSecurityAttribute with Caution 552
    Remoting Demands 553
    Limit Who Uses Your Code554
    No Sensitive Data in XML or Configuration Files555
    Review Assemblies That Allow Partial Trust 556
    Check Managed Wrappers to Unmanaged Code for Correctness557
    Issues with Delegates558
    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 Sources562
    Don't Tell the Attacker Too Much When You Fail562
    Summary 564
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
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
21  Secure Software Installation627
    Principle of Least Privilege628
    Clean Up After Yourself!630
    Using the Security Configuration Editor630
    Low-Level Security APIs638
    Using the Windows Installer638
22  Building Privacy into Your Application641
    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 Legislation646
    Privacy vs. Security 646
    Building a Privacy Infrastructure 647
        The Role of the Chief Privacy Officer 648
        The Role of the Privacy Advocate648
    Designing Privacy-Aware Applications649
        Including Privacy in the Development Process 649
        Exploring Privacy Features652
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 Issues701
        Informed Consent702
        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
A  Dangerous APIs 713
B  Ridiculous Excuses We've Heard723
C  A Designer's Security Checklist729
D  A Developer's Security Checklist731
E  A Tester's Security Checklist737
A Final Thought739

Last Updated: November 14, 2002
Top of Page