July, 2009

  • The Security Development Lifecycle

    ATL, MS09-035 and the SDL

    • 17 Comments

    Hello, Michael here.

    <updated: 7/31 - changed the compiler 'warning' to 'error'>

    Today, the Microsoft Security Response Center (MSRC) released two out-of-band security bulletins, MS09-034 and MS09-035, and a Security Advisory, to address security bugs in the Active Template Library (ATL) and I think it’s appropriate that I explain why the SDL did not find these bugs and what we learned.

    I’ve said this many times, but I’ll say it again, because I think it bears repeating. A bug of any kind is an opportunity to learn and then adjust your development practices if appropriate. In this post I will only outline the bugs fixed in ATL, not any of the defense-in-depth mechanisms added to Internet Explorer as part of MS09-034. You can find more information about the IE update in Dave Ross’s blog post at Security Research & Defense.

    But before I explain the bugs, I want to spend a couple of minutes to explain ATL. The Active Template Library (ATL) is a set of lightweight C++ classes originally designed to make creating COM objects easier. ATL handles all the object reference counting and handles common COM tasks with ease. But ATL is not restricted to COM; there are classes to handle smart pointers, images, the registry and ACLs and more.

    When a developer creates a C++ project in Visual Studio, they are given the option to create an ATL project and if the developer opts to do so, the most important headers are automatically added to the project.

    One final point before I discuss the bugs, the ATL source code is available for you to review; in the case of Visual Studio 2008, in the %ProgramFiles%\Microsoft Visual Studio 9.0\vc\atlmfc folder.

    Now let’s dig into the bugs.

    Bug #1: A Typo!

    This is the core issue in the MSVidCtl ActiveX control. The bug is in a modified version of an older version of ATL, and is not in the public ATL code, but in a privately updated version of the ATL code.

    Sidebar: How do ActiveX and COM differ?

    Skip this section if you want to focus on the core security issues; I added this to answer to a question I get a lot. The Component Object Model (COM) is a binary specification that defines how objects can interact. An ActiveX object is a COM object. The major feature that characterizes ActiveX objects is their ability to be used from scripting languages. Doing so is often called ‘automation’. ActiveX objects use a COM interface named IDispatch which allows the script engine to resolve and call methods in the object at runtime. This is often called ‘late binding.’

    The bug is simply a typo, can you spot it? I have removed extraneous code and error checking to make it easier to spot, and removed references to the psa variable (it’s a SAFEARRAYBOUND if you need to know)

    __int64 cbSize;
    hr = pStream->Read((void*) &cbSize, sizeof(cbSize), NULL);
    BYTE *pbArray;
    HRESULT hr = SafeArrayAccessData(psa, reinterpret_cast<LPVOID *>(&pbArray));
    hr = pStream->Read((void*)&pbArray, (ULONG)cbSize, NULL);

    I’ll give you one more clue – it’s a one character typo.

    Give up? Look at the last line. The first argument is incorrect. It should be:

    hr = pStream->Read((void*)pbArray, (ULONG)cbSize, NULL);

    The extra ‘&’ character in the vulnerable code causes the code to write potentially untrusted data, of size cbSize, to the address of the pointer to the array, pbArray, rather than write the data into the array, and the pointer is on the stack. This is a stack-based buffer overrun vulnerability.

    I contend that this would be very difficult to spot in a code review, and is not picked up by the C/C++ compiler owing to the (void*) cast. If the cast is removed, the compiler issues an error like this:

    C2664: '<function>' : cannot convert parameter 1 from 'BYTE **' to 'BYTE *'

    I despise C-style casting because it’s utterly unsafe; C++ casting is safer, although the reinterpret_cast operator is almost as bad as C-style casting.

    So why did we miss this?

    Our static analysis tools don’t flag this one because the cast tells the compiler and tools, “I know what I’m doing!” I looked over a few dozen instances of casting code like this in various code bases and they were all correct, so adding a rule to flag this kind of code would be prone to false positives and I would not want to subject anyone to a potentially massive amount of noise.

    In the SDL we require that teams fuzz their controls, but our fuzzing tools didn’t find this because the method in question requires a specially formed input stream that includes many sentinel bytes. I explain the weaknesses of fuzzing here. We are in the process of adding more heuristics to our fuzzing engine so it can include these COM-specific bytes if needed.

    Our banned API removal doesn’t find this because there is no banned API in play.

    Some of the defenses such as ASLR and DEP in Windows might come into play, depending on the component in question. That seems like a vague answer, but I say “depending” because ATL is a source code template library that is used to build software, and it is up to the developers to use these defenses. Customers using Internet Explorer 8 on Windows Vista SP1 and later are better protected because ASLR and DEP are enabled by default.

    The code is compiled with /GS, but there is no stack cookie for the vulnerable function because there are no local variables to protect, so /GS protection is ineffective in this instance.

    Bug #2: Using ATL Property Maps to Instantiate a COM object

    ATL allows COM objects to easily persist their properties to a stream of bytes and that byte-stream can then be re-constituted by the object at a later time. ATL does this using a ‘property map.’ The stream can be comprised of a series of tuples. When using tuples, the first portion of the tuple is the data type and, depending on the data type, a size (for example, an n-byte string [VT_BSTR]) and the second portion is the data itself.

    If the data type in the stream is VT_DISPATCH or VT_UNKNOWN, then the control might be vulnerable.

    The vulnerable code is in the shipping ATL source code, it’s in the CComVariant::ReadFromStream() method.

    So how did we miss this? The SDL offers no requirements or recommendations about using ATL property maps; in fact, the SDL offers few practices about hosting COM containers, mainly because there are so few of them, the most well-known COM container is Internet Explorer. We do require that teams use tools to identify their Safe-for-Scripting and Safe-for-Instantiation controls, however.

    In theory fuzzing should have found this, but our fuzzing engine does not build the correct stream and the stream is rejected. See the previous bug.

    What We’re Doing

    I want to point out that this is all very fluid right now owing to our rapid turn-around getting the bulletin out and I want to make sure we do the right thing in the SDL rather than rushing things and getting it wrong.

    First and foremost, we are updating our fuzzing tools to help find COM stream-related issues quickly, and we will update the SDL to tell teams to fuzz any COM object they have using any of the risky interfaces (like IPersistStream*, IPersistStorage, etc.)

    Second, we’re going to tell teams they must use the new ATL libraries. Today we have a “minimum compiler and linker toolset” requirement, but we don’t explicitly tell people which ATL to use. We’re going to change that!

    Finally, I want to drill a little deeper into casting issues. This will be a side project for me over the next few months, as I wade through bug databases and code to see if there are other related issues. I’ll also speak to various static analysis and C/C++ language experts here at Microsoft and across the industry to get their views and insight. If you have a professional opinion on casting issues, please feel free to let me know through this blog.

  • The Security Development Lifecycle

    URL Rewriting Session at Black Hat

    • 1 Comments

    Hi everyone, Bryan here. I wanted to make a quick (and shameless) plug for my session at Black Hat this week. I’ll be talking about the use of URL rewriting as a defense against XSS, XSRF, open-redirect phishing and browser history theft that I’ve discussed in the past both on this blog and in MSDN magazine.

    In conjunction with my talk, I’d also like to announce availability of a proof-of-concept URL rewriting tool that implements the concepts illustrated in the talk. The rewriter is implemented as an HttpModule for ASP.NET applications – activating this module for use in your own code will typically require one new line of code and one change to your web.config file.

    You can download the tool here, but again I’d like to stress that this is a proof-of-concept and should not be used for any production code. Please do feel free to test it out and even decompile it if you like – just let us know where it works, where it doesn’t, and how it can be improved.

  • The Security Development Lifecycle

    Working with SAFECode to Help Secure the Software Supply Chain

    • 0 Comments

    We have a guest blogger this week: Paul Nicholas, Principal Security Strategist Manager for the Critical Infrastructure Protection group at Microsoft and Chair of SAFECode is here to talk about supply chain security.

     

    Today’s blog post provides an introduction to another aspect of software assurance.  Software assurance is most frequently discussed in the context of processes such as the SDL that make code more secure through the application of secure development practices.  However, while there has been growing focus on eliminating software vulnerabilities through secure development practices, these practices assume that all parties involved in development of the product are honest and want to make their product secure. Unfortunately, this is not always the case. Developers, testers and other people in the software supply chain occasionally have the capability and motive to intentionally introduce vulnerabilities, and this type of insider attack can be devastating.

     

    To begin the process of tackling this problem in an effective and commercially reasonable way, the Software Assurance Forum for Excellence in Code (SAFECode) has released The Software Supply Chain Integrity Framework: Defining Risks and Responsibilities for Securing Software in the Global Supply Chain. The framework introduces integrity practices and controls organizations can use to help ensure that supply chain security issues are appropriately mitigated. These practices include:

     

    ·         Chain of Custody: The confidence that each change and handoff made during the source code’s lifetime is authorized, transparent and verifiable.

    ·         Least Privilege Access: Personnel can access critical data with only the privileges needed to do their jobs.

    ·         Separation of Duties: Personnel cannot unilaterally change data, nor unilaterally control the development process.

    ·         Tamper Resistance and Evidence: Attempts to tamper are obstructed, and when they occur they are evident and reversible.

    ·         Persistent Protection: Critical data is protected in ways that remain effective even if removed from the development location.

    ·         Compliance Management: The success of the protections can be continually and independently confirmed.

    ·         Code Testing and Verification: Methods for code inspection are applied and suspicious code is detected.

     

    I’m looking forward to working with the other members of SAFECode, its international advisory board, and customers from government and the private sector as we identify and refine industry best practices for making the software supply chain more secure.  I encourage you to read Software Supply Chain Integrity Framework and join the dialogue.

     

  • The Security Development Lifecycle

    Banned Crypto and the SDL

    • 0 Comments

    Hi, Michael here.

    The SDL does not focus solely on issues such as buffer overruns, SQL injection and cross-site scripting issues; an important component is making sure developers use the correct cryptographic functionality. The reason for using the correct crypto and using crypto correctly is three-fold; first, cryptography offers many low-level building blocks, such as hash functions, symmetric encryption algorithms and message authentication codes, and it’s important to understand the strengths and weaknesses of each building block. Second, it’s easy to make subtle mistakes that render an application or the data it is protecting vulnerable. Finally, it’s important that the cryptographic building block provides adequate protection.

    There are three broad buckets for SDL crypto compliance. The first is “don’t use banned crypto.” This is a little like “don’t use banned APIs” but for crypto rather than C or C++.The second is “use appropriate key lengths” and finally, generating random numbers.

    Also note that Federal Information Standard 140 – Security Requirements for Cryptographic Modules (FIPS-140) compliance is not an SDL requirement, but for some teams within Microsoft it is a requirement.

    Don’t use banned crypto

    This is probably the most important requirement, and also the hardest to achieve in legacy code because many Internet protocols use older cryptographic primitives, and simply replacing an old and insecure algorithm with a newer one will lead to compatibility issues.

    Examples here include MD4, MD5 and SHA-1. MD4 and MD5 are no-brainers because it’s easy to get hash collisions. One property of a good hash function is that it should be very difficult to find two or more documents that share the same hash. Real hash collisions were found in by Wang et al in 2004 in MD5, and in 2005 real PostScript documents were created that had the same hash. This led Ron Rivest, the cryptographer behind MD4 and MD5 to state that MD5 (and SHA-1) are ‘clearly broken.’ Because we’re starting to see real cracks in SHA-1, we believe that SHA-1 will be broken with the next ten-or-so years, so we decided to ban the use of SHA-1 in new code also.

    Removing broken algorithms from existing code is often hard to do, so teams must remove banned crypto over time.

    Theoretical weaknesses are one thing, but when theory becomes practical, well that’s a whole ‘nother ball game!

    It’s all very well claiming that something is broken, but in the SDL we also tell engineers what they must do. So, instead of using MD4, MD5 and SHA-1, engineers should use SHA-256, SHA-384 or SHA-512. We’re keeping our eye on developments, as there’s a great deal of research going into hash functions now.

    Next are symmetric ciphers. This boils down to “Use AES” and that’s pretty much all there is to say! DES and 3DES have small keys, 56-bit and 112-bit respectively, although 3DES does have a 168-bit keying option; however it too is too weak because of an attack called a “meet in the middle” attack, which renders the effective keysize to only 112-bits.

    You must also use an approved cipher mode. We require Cipher Block Chaining (CBC) for most cases.

    For asymmetric cryptography, RSA with 2048 modulus is required. There is a great deal of ongoing research attacking RSA so we will keep a close eye on events as they unfold. Elliptic Curve is also allowed; and there has been some interesting EC research lately.

    The Mysterious Case of RC4

    I’ve been asked many times why we have banned the use of RC4, even if a developer decides to use a zillion-bit key. The reason is because it’s regularly used incorrectly. So I’ll give a short version of the story.

    · RC4 is a stream cipher; it encrypts and decrypts one byte at a time.

    · RC4 is basically a pseudo-random number generator, and the key is the seed.

    · RC4 encrypts by XORing the plaintext with the keystream (the random numbers)

    · RC4 decrypts by XORing the ciphertext with the keystream.

    · If two sets of plaintext (p1 and p2) of length len1 and len2 are encrypted with the same key, an attacker can XOR the two ciphertexts (c1 and c2) to yield the XOR of the two plaintexts up to length min(len1, len2). Analysis of (p1 XOR p2) is much easier than analyzing c1 or c2. Mason et al wrote an interesting paper on the subject.

    · Because RC4 is a stream cipher, it’s possible for an attacker to ‘flip a bit’ in a controlled manner without the recipient knowing that the bit had been manipulated. Hence you should always have some form of message integrity check. Of course, even a block cipher should have some form of integrity check too, but the issue is exacerbated when using RC4.

    Have you ever noticed that there is no RC4 implementation in the .NET Framework!? David LeBlanc has a great write-up on various crypto issues in Microsoft Office, specifically pointing out RC4 issues.

    Two years ago I wrote a very simple tool that runs as a Visual Studio macro to help find banned crypto in your code. You can find the code here.

    Use appropriate key lengths

    I already touched on this, but for symmetric ciphers you must use 128-bit or longer keys and for RSA you must use 2048-bit modulus. For Elliptic Curve Suite B crypto, we require a minimum of 256-bit keys, and ECC-based key exchange and digital signatures must use one of the three NIST approved curves (P-256, P-384, or P521).

    The reason for these sizes is because as computers gain power, the cost for attacking a given key-space become less prohibitive. We’re now seeing software that harnesses the enormous computing power of graphic cards from companies like NVIDIA and ATI used to attack keys and guess passwords.

    Generating Random Numbers

    Good crypto requires high-entropy random number generation; we’re very specific in the SDL about what’s required. Call either:

    · CryptGenRandom

    · BCryptGenRandom

    · System.Security.Cryptography.RNGCryptoServiceProvider

    That’s all there is to it!

    I have left one thing out, which we will discuss another day, and that’s the topic of crypto-agility. crypto-agility is the ability to swap out crypto-algorithm support quickly from within an application without having to update and recompile the application. But in short, please do not hard code crypto algorithms into your code, read the algorithms from an adequately protected configuration file or from the protected document as metadata.

    Cryptographic Exceptions (no, not the try/catch variety!)

    Invariably there are exceptions that must be dealt with; for example you might need to use SHA-1 as part of a key derivation function owing to backward compatibility, or an IETF document might require you to use 3DES for symmetric encryption or DSA rather than RSA for signatures. At Microsoft, all crypto-related exceptions must go through the “Crypto Board” for sign off (or push back.) The board is staffed by about a dozen cryptographers and about a dozen interested parties, me included.

    A good example of the exception process in action is to allow or deny the use of a hash function beyond its ‘classic’ hashing capability. Hash functions can be used for:

    · Non-cryptographic checksums (a more collision resistant CRC)

    · Hash table lookup

    · Key derivation from low-entropy passwords

    · Digital Signatures

    · Message authentication codes

    Clearly the bar for a digital signature is far higher than for using a hash as a CRC-replacement.

    Having the crypto board in the system helps us reduce the chance that engineering groups will use cryptography inappropriately, and is another great example of how the primary SDL focus is preventing design and code bugs from entering the code in the first place.

  • The Security Development Lifecycle

    Static Analysis Tools and the SDL (Part Two)

    • 2 Comments

    Hi, Bryan here. Michael wrote last week on static analysis for native C/C++ code, and this week I’ll be following up by covering the tools we use for managed static analysis. The SDL requires teams writing managed code to use two static analysis tools: FxCop and CAT.NET. Both of these tools are freely available to the public, and both tools also integrate very nicely into Visual Studio. If you’re not already using these tools in your development process, I highly recommend downloading and evaluating them, but first let’s take a quick look at each of them.

    FxCop

    You may be more familiar with FxCop as the “Code Analysis” feature found in Visual Studio Team Developer (and Team Suite) 2005 and later. If you’re already using Visual Studio, it’s a no-brainer to enable FxCop code analysis: open your solution’s Properties window (or your web site’s Website menu item), navigate to the Code Analysis tab, and check the “Enable Code Analysis on Build” option. If you’re not using VS, you can download the latest version of the standalone FxCop tool (1.36) here.

    FxCop comes preinstalled with many useful rules, including rules to help ensure performance (for example, “Do not cast unnecessarily”), globalization (“Do not hardcode locale specific strings”), and maintainability (“Variable names should not match field names”), but the SDL is mainly concerned with the security rules. The SDL requires teams to enable all of the FxCop security rules and fix any violations.

    Many of the security rules are focused on detecting misuses of .NET Code Access Security policy. Some examples:

    · Do not indirectly expose methods with link demands. LinkDemand checks only the immediate caller’s permissions, it does not perform a complete stack walk like Demand does. Calling a LinkDemand-protected method from an unprotected method essentially allows the caller to bypass the security check completely. In general, Demand is much safer than LinkDemand; any misuse of LinkDemand can create a potential vulnerability to luring attacks.

    · Secure serialization constructors. If you place security demands on a type’s regular constructors, you must also place them on its serialization constructors, or else the demands could be bypassed.

    · APTCA methods should only call APTCA methods. Assemblies marked with the AllowPartiallyTrustedCallersAttribute (APTCA) that call into other assemblies not marked with APTCA can be used by attackers to perform luring attacks. The attacker (calling from partially-trusted code) could simply call the APTCA method that would then call the protected method on his behalf. (Note that the use of APTCA in itself is banned by the SDL; if it’s absolutely necessary then a manual review of all APTCA methods must be made to ensure no luring attacks are possible.)

    CAT.NET

    While the built-in FxCop security rules are generally focused more on testing whether you’ve used security features in the right way (although it’s easy to write your own FxCop rules to check for almost anything you want, which we’ll talk about later in this post), CAT.NET is focused more on testing whether you’ve written your other features securely. This is a subtle but important distinction and both types of tests are necessary to help ensure secure code. By default, CAT.NET tests for the following vulnerabilities:

    · Cross-Site Scripting

    · SQL Injection

    · File Canonicalization issues

    · XPath and LDAP Injection. These attacks work on exactly the same principle as SQL injection (user data is interpreted as code), but for XPath and LDAP queries instead of SQL queries.

    · Redirection to User-Controlled Site (aka Open-Redirect Phishing)

    · Process Command Injection. This is yet another attack that works on the data-interpreted-as-code principle. In this case, the user supplies improperly validated arguments to a command-line process, which can allow the user to execute arbitrary processes on the server.

    CAT.NET also differs from FxCop in the way it performs analysis. Both tools are static IL analysis tools, meaning that they analyze the compiled Common Intermediate Language (CIL) bytecode and not the raw C#/VB.NET/etc source itself. However, FxCop works on an introspection basis, iterating through each assembly type, member, resource, etc, while CAT.NET works by creating a directed call graph and looking for execution paths that represent potential vulnerabilities.

    For example, if you wanted a rule to make sure your code doesn’t use MD5 (because it’s been banned by the SDL), FxCop would be a natural choice: you could simply write one method that would iterate through the all of the members in the assembly looking for instantiations of MD5Cng or MD5CryptoServiceProvider classes. On the other hand, if you wanted a rule to make sure incoming querystring data is validated by a regular expression before being adding to session state, CAT.NET would be a better choice. You would create a new rule XML file, adding HttpRequest.QueryString.Item and HttpRequest.Params.Item as “source” elements, HttpContext.Session.Item as a “sink” element, and System.Text.RegularExpression.Regex as a “filter” element. CAT.NET would then analyze the potential execution paths of the application, flagging any data flows that originate with HttpRequest.QueryString or HttpRequest.Params and end at HttpContext.Session without first passing through RegularExpression.Regex.

    CAT.NET can run standalone or integrated into Visual Studio, but in either case you’ll need to download it from microsoft.com: you can find the 32-bit version of CAT.NET here and the 64-bit version here. Microsoft online services teams have been using CAT.NET internally for quite a while, and I was extremely pleased when the Microsoft IT Information Security Tools team (formerly the Connected Information Security Group) released it externally.

    Code Contracts

    Finally, as an interesting look at an upcoming technology, check out the DevLabs Code Contracts project. Code Contracts let you annotate your code to express required pre- or post-conditions on methods, just like SAL for native code. For example, you could require incoming method parameter values to conform to a specified regular expression, or require outgoing return values to be non-null. You can use Code Contracts both as a static analysis tool, to test for possible contract violations, and as runtime checks to actually enforce the conditions set. Like both FxCop and CAT.NET, Code Contracts can be installed either standalone or integrated with Visual Studio.

    The SDL Optimization Model and Static Analysis

    If you’re following the SDL Optimization model, use of static analysis tools is deemed a requirement for the ‘Advanced’ maturity level.

Page 1 of 1 (5 items)