Microsoft SDL and the CWE/SANS Top 25

advertisement
The Microsoft SDL and the CWE/SANS Top 25
Bryan Sullivan, Security Program Manager, Microsoft Corp.
Michael Howard, Principal Security Program Manager, Microsoft Corp.
Introduction
The purpose of this document is to present an overview of how the Microsoft SDL maps to the
CWE/SANS list of the Top 25 Most Dangerous Programming Errors. This document will assume that
you’re familiar with the vulnerabilities described in the SANS/CWE list. If not, please follow the
hyperlinks on the CWE items that will take you to the appropriate page on the MITRE web site.
The list is organized into three categories:



Insecure Interaction Between Components
Risky Resource Management
Porous Defenses.
Insecure Interaction Between Components
CWE-20: Improper Input Validation
As Adam Shostack has blogged so often, threat modeling is critical to the SDL. The SDL requires
development teams to threat model their applications, and the SDL Threat Modeling Tool is one of the
most widely used tools for this activity. The tool automatically adds potential input tampering threats to
any Data Flow Diagram (DFD) process elements added to the model. Modelers are prompted to ensure
that all inputs to the process across all execution paths are verified for correctness. Allow-list validation
techniques are suggested as appropriate mitigations.
The SDL also includes specific guidance around using input validation to prevent cross-site scripting (XSS),
the most prevalent web application vulnerability. Developers are required to validate or sanitize all
incoming data against XSS attacks by blocking or removing potentially malicious script input. Details on
how to accomplish this can be found in the September 2008 MSDN magazine article “SDL Embraces the
Web”. As a defense in depth measure, the SDL also requires use of the ValidateRequest feature of
ASP.NET, which automatically blocks some forms of script input.
Finally, we have a security training class dedicated to Web-based vulnerabilities.
CWE-116: Improper Encoding or Escaping of Output
The SDL requires output encoding of data written to web pages (to prevent XSS vulnerabilities) and
escaping of input passed to SQL commands (to prevent SQL injection).
HTML output encoding is actually much trickier to perform correctly than many developers believe. To
make this process easier, the SDL requires developers to use the CISG AntiXSS library.
1
SQL command input escaping is required implicitly by the SDL requirement to always use stored
procedures for all database access. The database stored procedure logic will automatically escape input
to a safe format and prevent SQL injection vulnerabilities.
This subject is covered in our Security Basics class, as well as many other secure coding classes.
CWE-89: Failure to Preserve SQL Query Structure (aka SQL Injection)
SQL injection vulnerabilities are thoroughly covered by the SDL. Besides the requirement to always use
stored procedures for all database access mentioned earlier, there are two additional requirements.
The first is to avoid the use of the SQL EXECUTE/EXEC command in your stored procedures (or more
precisely, to only use EXECUTE to call other stored procedures, never to execute arbitrary SQL
commands). Without this requirement, you could accidentally undo the security benefits of using stored
procedures by coding vulnerable T-SQL code directly into the stored procedure.
The second requirement is a defense-in-depth feature. All direct table and view privileges for the
interactive user for the database must be revoked, and only execute permissions for the necessary
stored procedures granted. This requirement dramatically lowers the damage that any potential attack
could cause: attackers will be limited to only calling those functions that the application is already
designed to access, and they will not be able to (for example) iterate through the sys.objects table or call
the xp_cmdshell procedure.
The subject of SQL injection is covered in our Security Basics class, as well as in the Web-based
vulnerabilities class.
CWE-79: Failure to Preserve Web Page Structure (aka Cross-Site Scripting)
XSS vulnerabilities are also thoroughly covered by the SDL. As mentioned earlier, the SDL has
implementation requirements around validating and sanitizing input (removal of malicious script input,
also ValidateRequest) and output encoding (AntiXSS library).
As an additional verification step, the SDL also requires the use of static analysis to detect possible XSS
vulnerabilities. Specifically, it requires the use of the CISG Code Analysis Tool for .NET (aka CAT.NET) for
managed code projects. Internal Microsoft teams have been using this tool with great success for a
while now, and we’re very happy that CISG has recently made a free Community Technology Preview of
it available to the public.
This subject is covered in our Security Basics class, as well as in the Web-based vulnerabilities class.
CWE-78: Failure to Preserve OS Command Structure (aka OS Command Injection)
The SDL-mandated CAT.NET tool is also required to detect potential SQL injection problems, openredirect phishing, XPath and LDAP injection, and some types of command injection vulnerabilities. Any
dataflow source that ends at a System.Diagnostics.Process or ProcessStartInfo sink without passing
through an appropriate validation function will flag as a potential command injection vulnerability. The
SDL also recommends that applications be granted minimal privileges and apply appropriate ACLs – for
2
instance, denying access to the file system, or allowing only read-only access to the registry – so that
developers can reduce the damage that any successful command injection attack would cause.
This subject is covered briefly in our Security Basics class and at length in our Secure Code Review and
Secure Design classes.
CWE-319: Cleartext Transmission of Sensitive Information
Our threat modeling process would uncover these design vulnerabilities: they are considered
Information Disclosure vulnerabilities in the STRIDE taxonomy.
The recently released SDL Threat Modeling Tool will prompt the modeler to answer the following
questions for all data flow elements added to the diagram:
1. If there is a channel and/or message encryption system for the data flow as a whole, is it strong,
and in accordance with the Crypto Board and SDL requirements?
2. If not, or if there is not a confidentiality system, what prevents information disclosure?
The tool also offers the suggestion to encrypt the data flow if it crosses a network, or to use appropriate
ACLs if it’s on a single system. (The definition of “strong” channel encryption per the SDL standards will
be discussed later in this post under the topic CWE-327, Use of a Broken or Risky Cryptographic
Algorithm.)
Finally, this topic is covered at length the Security Basics class, Secure Design Class and Threat Modeling
class.
CWE-352: Cross-Site Request Forgery (aka CSRF)
Cross-site request forgery vulnerabilities are covered by the SDL requirement to use the
ViewStateUserKey feature of ASP.NET. Setting the ViewStateUserKey property creates a secret “canary”
value shared between the client (stored in the page view state) and the server (calculated or stored as
the developer desires). Any request missing a valid ViewStateUserKey value is assumed to be a
malicious forgery and the request is denied.
Note that this only mitigates some forms of POST-based CSRF attacks. HTTP GET requests have no
request body, and therefore no view state, and therefore cannot use view state-based defense
mechanisms.
CSRF (and related) vulnerabilities are discussed in depth in the Web Security class.
CWE-362: Race Condition
In reviewing the CWE/SANS list thus far, we have had requirements in place to mitigate all the
vulnerabilities discussed. In some cases we’ve had many overlapping requirements to provide defensein-depth. But we do not have any specific SDL requirements to detect possible race conditions. The main
reason for this is that race conditions are notoriously difficult to detect and reproduce. Until someone
develops an automatic analysis tool to accurately detect potential race conditions, our only way to find
these issues is through manual code review. While we don’t consider code review a complete solution,
3
we note that we’ve only issued three bulletins concerning race condition vulnerabilities in the last ten
years.
Race conditions and Time of Check/Time of Use (TOCTOU) vulnerabilities are discussed in the Secure
Design class.
CWE-209: Error Message Information Leak
The SDL recommends that error messages should present just enough information to provide the user a
clear understanding of what an appropriate action to take would be, but not any information that would
help an attacker to compromise the system. Further guidance to help a developer determine how much
information is “just enough” can be found at http://msdn.microsoft.com/en-us/library/ms995351.aspx.
In addition, CAT.NET (available in Visual Studio, and as a standalone tool) will detect when inappropriate
exception information is presented to the user. Any internal stack traces or exception messages
(determined by either the Exception.Message property or the Exception.ToString method) displayed to
the user will be flagged as information disclosure vulnerabilities.
This topic is explained in detail in the Security Basics class, primarily in the context of SQL injection
vulnerabilities.
Risky Resource Management
CWE-119: Failure to Constrain Memory Operations within the Bounds of a Memory Buffer
Beyond a doubt, buffer overflows are the most thoroughly covered vulnerabilities in the SDL. The most
recent version of the SDL has at least nine requirements concerning overflows, and more if you consider
the primary purpose of fuzz testing to be finding overflow vulnerabilities. Let’s take a quick look at each
requirement:




Use static analysis tools to find code with potential vulnerabilities. The main tool we use is
PREfast – available externally as the /analyze option in Visual C++.
Avoid banned APIs. Avoiding the API calls that can lead to overflows is the primary defense
against overflow attacks. An easy way to find these APIs is to include Michael’s banned.h header
file which will deprecate all unsafe functions. You can find banned.h here:
http://download.microsoft.com/download/2/e/b/2ebac853-63b7-49b4-b66f9fd85f37c0f5/banned.h
Use the /GS compiler option. /GS causes the compiler to insert stack cookie-checking code
around function calls. If an attacker tries to smash the stack (either for fun or profit), the cookie
value will be changed and the application will stop executing. A detailed analysis of this
mitigation can be found at
http://blogs.msdn.com/michael_howard/archive/2007/04/03/hardening-stack-based-bufferoverrun-detection-in-vc-2005-sp1.aspx.
Link with the /NXCompat flag to enable Data Execution Prevention (DEP). DEP helps to prevent
exploitation of overflow vulnerabilities by preventing data from being executed as code. See
http://msdn.microsoft.com/en-us/library/ms235442(VS.80).aspx
4







Link with the /DynamicBase flag to enable Address Space Layout Randomization (ASLR). Another
defense-in-depth mechanism that complements /GS and /NXCompat, ASLR randomizes the
locations of function calls to make exploiting any existing overflow vulnerabilities more difficult.
See http://blogs.msdn.com/michael_howard/archive/2006/05/26/address-space-layoutrandomization-in-windows-vista.aspx for more information.
Link with the /SafeSEH flag to enable safe structured exception handling. SafeSEH compiles a
table of valid exception handler addresses at link time and adds this table to the image. If an
attacker tries to define his own exception handler in order to execute arbitrary code of his
choosing, the application will fail the handler address table verification check and stop executing.
Use the HeapSetInformation function with the HeapEnableTerminationOnCorruption flag. In the
event of heap corruption (that might occur from a buffer overflow attack, for example), the
application will shut down. You can find more information at
http://blogs.msdn.com/michael_howard/archive/2008/02/18/faq-about-heapsetinformationin-windows-vista-and-heap-based-buffer-overruns.aspx.
Run Application Verifier to detect heap-related buffer overruns and double-free errors through
dynamic testing.
Use –fstack-protector-all for Apple OS X applications (such as Mac Office). This is a stack cookie
protection similar to /GS. (Don’t be so surprised! Microsoft makes OS X applications too and we
want them to be just as secure as our Windows applications, and online services, and Xbox
games, and hardware devices, etc…)
Use library randomization for Apple OS X applications. The –WI, -pie compiler options provide a
similar feature to ASLR for OS X.
Use the GCC fortify source compiler option for Apple OS X. The GCC compiler option –
D_FORTIFY_SOURCE=2 will automatically migrate some overflow-vulnerable API calls to their
safe equivalents.
In addition, the SDL also makes several recommendations around overflow defense:



Automate banned API replacement. Visual C++ 2005 and later versions support the ability to
automatically replace some overflow-vulnerable API calls with their safe equivalents. For
example, calls to strcpy will be replaced with calls to strcpy_s. To use this feature, include this
line in one of your header files:
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES (1)
Encode long-lived pointers such as global function pointers or pointers to shared memory
regions with the EncodePointer or EncodeSystemPointer function. This is a defense-in-depth
measure designed to make exploitation of overflow vulnerabilities more difficult for the attacker.
You can read more at
http://blogs.msdn.com/michael_howard/archive/2006/01/30/520200.aspx.
Avoid global exception handlers. Using catch-all global exception handlers may prevent the
application from crashing, but it also gives attackers more opportunity to exploit vulnerabilities.
The ASLR defense for example will be negated if you use exception handlers like these. The
5
PREfast Analysis Tool (included in Visual Studio with the /analyze compiler option) and the
Application Verifier tool (also included in Visual Studio) will both flag this vulnerability.
Finally, there are numerous training classes that cover buffer overrun vulnerabilities; it’s in the Security
Basics, Code Review and Fuzzing classes.
CWE-642: External Control of Critical State Data
A good threat model should identify the potential for an attacker to tamper with client-side state data (T
in STRIDE). Additionally, we cover in our Web security class the specific vulnerability of using hidden
form fields to hold critical data.
CWE-73: External Control of File Name or Path
The SDL includes the following recommendations around defending against canonicalization attacks:







Limit URL length to no more than 16,384 characters
For managed code, use the standard System.IO classes to take advantage of built-in
canonicalization defenses in the .NET framework. Avoid P/Invoking out to the Win32 file I/O
APIs.
Build an allow-list of valid file names or types
Explicitly reject file types such as exe, bat, cmd, com, htw, ida, idq, htr, idc, shtm, shtml, stm,
printer, ini, pol, dat
For managed code, catch the exceptions System.ArgumentException,
System.NotSupportedException, System.IO.FileNotFoundException, and
System.IO.DirectoryNotFoundException
For native code, prepend \\?\ to the filename (this bypasses filename equivalency checks)
For URLs, check that a single pass of URL-decoding the filename matches a second pass of URLdecoding the filename. If the two decodes do not match, reject the filename.
CAT.NET can flag the use of unvalidated user input as a parameter to System.IO.File and FileInfo method
calls that can lead to canonicalization vulnerabilities.
In addition, the SDL also recommends that web developers avoid open redirect vulnerabilities by
validating all redirect targets against a predefined allow-list of known good sites or domains.
Canonicalization issues are discussed in great detail in the Security Basics class.
CWE-426: Untrusted Search Path
CAT.NET can detect the use of untrusted user input as a parameter to
System.Reflection.Assembly.LoadFile and LoadFrom methods. Additionally, our C/C++ static analysis
tools such as PREfast (/analyze in Visual C++) will flag some function calls that can exacerbate the
problem. Also in Windows versions beginning with Windows Server 2003 we changed the default search
path ordering to not include the current directory by default.
Finally, untrusted search path vulnerabilities are explained in the Security Basics class.
6
CWE-94: Failure to Control Generation of Code (aka 'Code Injection')
The SDL covers one form of this attack by recommending that web developers never use the JavaScript
function eval() or its functional equivalents setTimeout() and setInterval(). Using these functions could
potentially allow an attacker to specify his own malicious script that would execute on the victim’s
machine. Instead, the SDL asks web developers to design their applications whenever possible in such a
way that dynamic code execution is not required.
The evils of eval() are explained in the Web security class.
CWE-494: Download of Code Without Integrity Check
The SDL Threat Modeling process and tool can find these vulnerabilities: for each data flow element in
the system, the modeler is prompted to brainstorm who could tweak the bits on the wire and thus
perform a potential Man in the Middle (MitM) attack. To mitigate threats, the tool suggests the use of
cryptographic integrity controls or any MitM defenses inherent in the OS. The threat modeling process
also looks at spoofing attacks, and so potential downloads from an imposter site should also be covered.
CWE-404: Improper Resource Shutdown or Release
Many types of this vulnerability, including memory leaks (CWE-401), double-frees (CWE-415), use after
free (CWE-416) and freeing invalid pointers (CWE-590) are found by either the Microsoft Application
Verifier (appverif.exe) or the PREfast Analysis Tool, both of which are required by the SDL. Both of these
tools are included with Visual Studio, and you can also download AppVerif as a free standalone tool at
http://www.microsoft.com/downloads/details.aspx?FamilyID=C4A25AB9-649D-4A1B-B4A7C9D8B095DF18&displaylang=en.
All the topics listed above are covered in the secure code review class.
CWE-665: Improper Initialization
The SDL-required PREfast static analysis tool includes checks for use of improperly initialized memory.
The SDL also recommends that C++ development teams set the compiler warning level to level 4
(compiler switch /W4) and fix all resulting flagged warnings. These warnings include checks for
uninitialized variables and for other issues such as signed/unsigned variable mismatches and potential
data loss from type conversions.
Initialization issues are discussed in the secure code review class.
Additionally, the CWE/SANS guidance recommends fuzzing to test for uninitialized memory problems.
The SDL requires each product to complete a large number of clean fuzzing iterations for each of the
following:




File format parsers (100,000 clean iterations required)
RPC interfaces (24 hours of “smart” and “dumb” fuzzing without failure or memory leakage)
ActiveX control methods (100 values for each parameter of each method)
Network interfaces including SOAP (100,000 packets recommended)
7
CWE-682: Incorrect Calculation
Our static analysis tools, most notably PREfast, will detect some forms of incorrect calculation errors.
While it is not officially required or recommended by the SDL, many Microsoft teams use David
LeBlanc’s SafeInt library, which provides defenses against calculation errors such as integer overflows
and underflows. SafeInt is available for download on Codeplex: http://www.codeplex.com/SafeInt.
The subject of arithmetic issues is taught in great detail in the Security Basics and Secure Code Review
classes.
Porous Defenses
CWE-285: Improper Access Control (Authorization)
Access control issues like elevation of privilege (EoP) and information disclosure are thoroughly
addressed by the SDL threat modeling requirement. If you’re using a Data Flow Diagram (DFD) based
threat modeling approach (like the SDL Threat Modeling Tool), you can use the trust boundary DFD
element to divide your application into areas of appropriate privilege level. For example, resources that
can be accessed by anonymous users can be separated by a trust boundary from resources that must be
accessed by authenticated users, and those resources can be separated from resources that require
administrative access.
Access Control list (ACL) issues are covered in the Security Basics class.
Ongoing education and automated analysis help us find weak object permissions as part of the SDL
attack surface analysis requirements.
The SDL recommendation to grant only minimal privileges by applying appropriate ACLs also helps to
mitigate this vulnerability.
CWE-327: Use of a Broken or Risky Cryptographic Algorithm
All Microsoft products must meet the SDL cryptographic standards, which list the currently acceptable
and unacceptable cryptographic algorithms.
Algorithm Type
Symmetric block
Symmetric stream
Asymmetric
Hash/HMAC
Unacceptable
Acceptable
Preferred
DES, DESX, RC2,
SKIPJACK
SEAL, CYLINK_MEK,
RC4 (<128bit or
unreviewed)
RSA (<2048 bit),
Diffie-Hellman
(<2048 bit)
3DES (2 or 3 key)
AES (>=128 bit)
RC4 (reviewed & >=
128bit)
None – Block cipher
is preferred
RSA
((>=2048bit),
Diffie-Hellman
((>=2048bit)
SHA-2
RSA (>=2048bit)
Diffie-Hellman
(>=2048bit)
ECC (>=256bit)
SHA-2
(includes:
SHA-256,
SHA-384,
SHA-512)
SHA-0 (SHA), SHA-1,
MD2, MD4, MD5
8
HMAC key lengths
<112bit
>= 112bit
>= 128bit
The Application Verifier tool will also detect the use of weak cryptographic algorithms.
Cryptography training covers this topic in great detail, and the Security Basics class touches on the
subject.
Finally, the SDL requires products to be cryptographically “agile”; that is, they should be able to easily
switch algorithms should a weakness be found in a currently acceptable algorithm.
CWE-259: Hard-Coded Password
The SDL cryptographic standards require developers to use the Data Protection API (DPAPI) functions
CryptProtectData and CryptUnprotectData included with Windows to store all secret data, including
keys and passwords. For managed code developers, DPAPI is wrapped by the .NET framework class
System.Security.Cryptography.ProtectedData; the corresponding appropriate functions are Protect and
Unprotect.
The dangers of hard-coded passwords and related vulnerabilities such as storing passwords in a
reversible format (or even storing passwords at all, in most cases) are covered in the Security Basics
training class. The SDL Threat Modeling Tool similarly prompts designers to consider authentication
methods that do not store secrets either on the server or the client.
CWE-732: Insecure Permission Assignment for Critical Resource
The SDL recommendation to grant only minimal privileges helps to mitigate this vulnerability. We’ve also
built (and require the use of) internal verification tools to help find and report on system configuration
errors such as weak ACLs.
Access Control list (ACL) issues are covered in the Security Basics class. Training on the subject of weak
permissions is in the Security Basics and Secure Design classes.
CWE-330: Use of Insufficiently Random Values
Insufficient randomness is yet another vulnerability covered by the SDL cryptographic standards.
Pseudorandom functions like the CRT rand function or GetTickCount are banned. The only currently
approved cryptographically strong random number generation functions are CryptGenRandom and
rand_s for native code and the System.Security.Cryptography.RNGCryptoServiceProvider class for
managed code.
Use of correct random number generators is covered the Security Basics and Cryptography classes.
CWE-250: Execution with Unnecessary Privileges
The SDL requires teams to design their products to be used by a standard non-administrative user
whenever possible. Applications must be developed with User Account Control (UAC) best practices in
mind to ensure they run with least privilege. Also, applications should access resources using the
9
smallest-possible permission set; for example open an object for Read rather than Full Control when
only read access is required.
Least Privilege issues are covered in the Security Basics and Secure Design classes.
CWE-602: Client-Side Enforcement of Server-Side Security
This vulnerability has ties to both CWE-642 (External Control of Critical State Data) and CWE-20
(Insufficient Input Validation). Just as you shouldn’t trust the client to hold sensitive state data, you
shouldn’t trust the client to tell you whether or not it is authorized to perform an action.
The primary defense specified by the SDL against this vulnerability is threat modeling. Authentication
issues in general are well covered by the SDL Threat Modeling tool, although there are no specific
leading questions posed around client-side authentication/authorization vulnerabilities.
Summary
The following table summarizes the mapping between the SANS/CWE Top 25 and the Microsoft SDL;
note that each CWE vulnerability is addressed by one or more SDL requirements:
CWE Title
20
116
89
79
78
319
352
362
209
119
642
73
426
94
494
404
665
682
285
327
Education?
Improper Input Validation
Improper Encoding or Escaping of Output
Failure to Preserve SQL Query Structure (aka
SQL Injection)
Failure to Preserve Web Page Structure (aka
Cross-Site Scripting)
Failure to Preserve OS Command Structure
(aka OS Command Injection)
Cleartext Transmission of Sensitive
Information
Cross-site Request Forgery (aka CSRF)
Race Condition
Error Message Information Leak
Failure to Constrain Memory Operations
within the Bounds of a Memory Buffer
External Control of Critical State Data
External Control of File Name or Path
Untrusted Search Path
Failure to Control Generation of Code (aka
'Code Injection')
Download of Code Without Integrity Check
Improper Resource Shutdown or Release
Improper Initialization
Incorrect Calculation
Improper Access Control (Authorization)
Use of a Broken or Risky Cryptographic
Algorithm
10
Tools?
Y
Y
Y
Manual
Process?
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Threat
Model?
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
259
732
330
250
602
Hard-Coded Password
Insecure Permission Assignment for Critical
Resource
Use of Insufficiently Random Values
Execution with Unnecessary Privileges
Client-Side Enforcement of Server-Side
Security
11
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Y
Download