February, 2009

  • The Security Development Lifecycle

    SDL Threat Modeling Tool 3.1.4 ships!

    • 1 Comments

    Adam here.  We’re pleased to announce version 3.1.4 of the SDL Threat Modeling Tool.  A big thanks to all our beta testers who reported issues in the forum!

    In this release, we fixed many bugs, learned that we needed a little more flexibility in how we handled bug tracking systems (we’ve added an “issue type” at the bug tracking system level) and updated the template format.  You can read more about the tool at the Microsoft SDL Threat Modeling Tool page, or just download 3.1.4.

    Unfortunately, we have no effective mitigation for the threat of bad π jokes.

  • The Security Development Lifecycle

    Early Days of the SDL, Part Four

    • 0 Comments

    Steve Lipner here. By late 2001, our security teams had been reorganized and I was managing both the Microsoft Security Response Center (MSRC) and the “Secure Windows Initiative” (SWI).  MSRC handled Microsoft’s reaction to vulnerabilities and their exploitation, while SWI provided training, guidance on best practices, and consulting for product groups.  The Code Red and Nimda worms and a series of widely-publicized product vulnerabilities had made 2001 a very difficult year for Microsoft, with at least one well-regarded industry analyst advising customers to stop using our IIS web server.  My team took the heat of the negative reaction by customers and the press.

    Michael and Glenn talk about some of the internal milestones that led to Trustworthy Computing and the Windows security push.  The November executive review with Bill Gates and senior executives conveyed both customers’ concerns about our products’ security and the code-level problems that were the underlying cause.  My team offsite shortly after that review came up with the “crazy idea” of stopping Windows development until the security problems were solved – or at least until security was going in a different direction.

    Some of my most vivid memories are of planning and internally “selling” the security push.  Michael and I met with one of the program managers who ran the Windows Server 2003 product, and he advised us that he agreed that security should be a priority and that he could see accommodating a two-day stand-down” in the schedule.  Michael and I said we had a little longer duration in mind – and kept on planning. 

    The Common Language Runtime team had pulled together its security push across a single large team.  We had to figure out how we’d organize, train, and manage the Windows push across a large number of product units and make sure that no group got left behind.  I spent a lot of time in December 2001 developing plans and schedules that would provide product units with specific enough guidance to stay on board, but enough flexibility to accommodate their specific technologies and threats.   I kept presenting our plans to higher and higher levels of management expecting some pushback, but all I heard was “OK, keep on planning”.

    By January, we were committed to the security push.  Jim Allchin, then our group vice president, kicked off a meeting with the 200 or so top managers in Windows, and we briefed them on the objectives and organization of the security push and what we were trying to accomplish.  We told each group to develop an implementation plan for its participation, and my team reviewed the plans and provided feedback and suggestions.  Jason Garms still has a mail message that refers to our spending our entire weekends reviewing plans – one of Jason’s messages was sent at 4:00 am on a Monday morning! 

    By the end of January, the plans were in place and we rolled out training – ten four-hour sessions focused on developers, testers, or program managers.  Each training session was kicked off by one of the vice presidents in the Windows division, and each filled Microsoft’s largest conference room with about 950 people.  Each attendee received a copy of Writing Secure Code first edition.

    Beginning in February, we spent our time (probably 13-16 hours a day) attending the Windows ship (then “war team”) meetings, meeting with product teams, answering questions, and reviewing bugs.  Although we’d done a lot of planning, this was definitely our first time, and a lot of what we were doing was ad hoc.  I still remember the complaints about how vague and hard to implement our threat modeling guidance was – my answer then was “do what you can”, but I still remember those complaints and think about how far we’ve come when I look at the SDL Threat Modeling Tool.

  • The Security Development Lifecycle

    Early Days of the SDL, Part Three

    • 1 Comments

    Glenn here. It’s easy to look back on a career in software and see the highlights in terms of the big features pushed to meet a customer need, the milestones met, and the products shipped; but one of the highlights of mine was a fairly innocuous off-site meeting in October 2001, at a pretty conference centre just a few miles from campus.

    The meeting was originally set up as a strategy meeting for my then (and now) boss, Steve Lipner’s direct reports, but it quickly got diverted onto the subject of how we, as part of Windows, could respond to the spate of worms that had affected our customers in the previous few months.

    I very distinctly recall the discussion turning to Mike Howard’s recent experiences on the “Security Stand-down” for the recent .NET Framework v1.0 release, and somebody remarking that it would be good if we could do something similar for Windows. Perhaps it’s a “movie memory”, but I remember there being silence, or skepticism at that suggestion – how would something like that be possible on a project like Windows? – but as we continued to explore, we somehow managed to convince ourselves that it was an idea worth pursuing.

    That meeting was one small step, probably the first step, on the way to the “Windows Security Push”, but the ideas and drive that came out it set us on the path to the SDL, a key part of our development process.

    I wish I still had the flipchart!

  • The Security Development Lifecycle

    Early Days of the SDL, Part Two

    • 1 Comments

    Hi everyone, Chris Walker here.

    Prior to the Windows Security Push of February 2002, security testing was rather spotty in the Windows organization.  Both the Internet Explorer team and the Internet Information Server (IIS) team had mature efforts oriented to solving the problems that were being reported. But the rest of the organization often viewed security bugs as a distraction from their real work.  

    To combat this attitude, Michael Howard had been working on his Writing Secure Code book, and I had a team looking for security bugs through code reviews.  We had some tools in those days for finding bugs, but they were typically used only by our team, partly because many of them required in-depth knowledge to interpret the results.

    One notable exception was PREfast which had been developed as a collaborative effort by Tim Fleehart (who was in my team at the time) and by Microsoft Research under Jon Pincus. Tim had been using another MSR technology called AST Toolkit to search for code patterns that were questionable.  Since the code that was seen by this technology is after macro expansion, it uncovered more bugs than were immediately obvious from just reading the raw source code.  Building on the AST technology, PREfast added a nice UI and reporting facility.  We had deployed PREfast onto Windows developers’ desktops in the summer of 2001 and some developers were beginning to see its advantages.

    But then the Code Red and Code Red II worms hit Windows in July and August 2001.  It was a wake-up call of major proportions, so in November 2001, Brian Valentine, then VP of Windows, called a bunch of us into a room to say he’d had enough and wanted us to come up with a plan to solve the security problem.  We agreed to meet again with some possible solutions in hand after Thanksgiving.  

    The .Net framework was getting ready to release and the team had done a security push across their own product -- I think this may have been the first product that devoted concentrated time across the whole product to addressing security. So we met with them to learn what part of their process appeared to work and what didn’t and got some great ideas on how to tackle the problem for the Windows team, which was, of course, on a much grander scale.

    Not knowing exactly how much Brian was committed to solving the security problem, we came up with a plan that included as much as possible with the thought that he would dial back the effort to what he thought was a reasonable investment.  To our surprise, when we met again, he told us to do everything we had suggested.  Clearly our priorities had shifted.

    The plan was to have the Windows development team concentrate on finding and fixing security bugs for one month, but first we needed to train them in techniques for finding bugs and teach them about the specific types of code issues most likely to generate security holes.  So we set up a series of training sessions for the entire team, training people in groups of 900 per session.  The introductory session was always opened by a vice president, who set the context for the work and emphasized the imperative nature of the results.  The rest of that first 4 hour session was then spent on a grand tour of actual security problems that we had seen – and since worms were on everyone’s minds, stack buffer overruns were explained in detail.

    Then for each of the three different disciplines (development, testing and program management) there was a separate 2 hour talk. I created a 2 hour talk for testers based on previous talks I had given to various groups when they asked for help.  I had typically customized each talk to match the group’s needs and time allotment.  This particular talk for the Windows Security Push covered both issues that were well known externally and those that were not so well known.  And, because we didn’t know which processes or tools were going to be effective, we tried all of them. We decided to tell people everything we knew about the kinds of problems that could be encountered, and what tools were out there, and then to let them decide what applied to them and prioritize accordingly.  Though it wasn’t required, many developers attended my testing talks, just as many testers attended the developer talks.  (That in part explains the fact that the class attendance over the week exceeded the population of the Windows division).  

    It was decided that everyone in the Windows team should be required to take the training, which meant that even documentation writers, business managers and lab technicians were in the classes, which may have been overkill.  But rules are rules, and it did mean that everyone got a good dose of exactly what we were up against.  

    On the other hand, only Windows team members were actually required to attend, so we missed some of our partners in other groups like Office, Visual Studio, SQL and Exchange.  We didn’t have a very robust tracking system for determining which groups contributed to Windows code at the time, nor did we have a lot of infrastructure set up for measuring various teams' progress.  We did set up a database of source files to be reviewed, and we set up a mechanism to get developers to sign off on high priority files.  But other processes like fuzz testing, or fixing PREfast bugs went unmeasured.

    We did eventually begin tracking the various tools and processes that had been set in motion during the push. In later analysis, we discovered which ones worked the best -- for example, the elimination of strcpy() function in our code was easy and effective -- and those became requirements in the SDL.

  • The Security Development Lifecycle

    Early Days of the SDL, Part One

    • 2 Comments

    Hi everyone, Michael here. Even though 2001 and 2002 are a distant memory for many people, those years are still fresh in my mind; not because of CodeRed or Nimda, even though I had worked in the IIS team , but because of the important security work we started within the company.

    Early in 2001 David LeBlanc and I lamented the deluge of email we constantly received asking pretty basic security questions; so rather than whine and complain we thought we would write a little book that covered some of the basics so we could focus on the ‘hard problems.’ That book was “Writing Secure Code” (aka WSC) named after Steve Maguire’s excellent “Writing Solid Code.” I think it’s fair to say WSC was the secret weapon that helped scale our early security work because we simply gave every engineer at Microsoft a copy and told them to read it!

    Fast forward to October 2001. The .NET team found a small number of security bugs in the runtime and framework, and that made the .NET team nervous. So they bravely decided to have a “Security Stand-down,” which, in short, means stop all work, get more security training and find and fix security bugs. There was no time limit to the work. That’s why I said it was ‘brave’ because the work was done when incoming bugs flat-lined. I, and many others across the company were actively involved in the .NET security work, and while the work was beneficial, and frankly adrenalin-inducing (seriously, it was!), we knew such efforts were not sustainable. Eventually, we came to understand that we had to change our development process.

    At the end of the November 2001, a small cadre of senior Windows folks, Steve Lipner included, met with the Microsoft senior leadership team, Bill Gates among them, to discuss security. At the end of the meeting, Bill said he wanted to learn more about security bugs in detail, so a four-hour follow-up meeting was scheduled for December for me to discuss security vulnerabilities in depth with Bill. At the end of the chat, I gave Bill a copy of Writing Secure Code.

    While all this was going on, Craig Mundie and Bill had been working on an initiative to focus the company on security, privacy and reliability; that became known as Trustworthy Computing, and the memo of Jan 15, 2002 quickly followed, rallying the company. It also gave our group sufficient clout to do what needed to be done to add more security rigor to our development processes.

    At first the process improvements were haphazard; we introduced a very rudimentary version of threat modeling in 2002, started using static analysis tools and teaching developers to review code for security bugs. And most major products at Microsoft underwent “Security Pushes” following the .NET Security Stand-down model. Over time we fine-tuned the best practices into what we have today at Microsoft: The Security Development Lifecycle.

    When we started our little group to focus on “security as in threats, not security as in features” we had no name until Dave Thompson, then VP responsible for security (as in features) in Windows named us the Secure Windows Initiative, a name that has stuck until this year. Many of the original folks are still around; we’re still as active and energetic as we were in 2001 and 2002, just a little grayer and substantially wiser! Our small team, which is now an order of magnitude larger, changed the face of Microsoft security by changing the end-to-end development process, which believe me, is no easy task at a company the size of Microsoft.

    My hat is off to everyone who worked on “Security as in threats” back then, especially those who understood how that is different from “Security as in features.”
  • The Security Development Lifecycle

    SDL War Story Videos

    • 1 Comments

    Watch short interviews with Mike Howard and Steve Lipner about the real-life conflicts that led to the creation of the SDL, plus the challenges and successes in implementing it at Microsoft.

    http://www.microsoft.com/security/bakingsecurityin/video.htm

  • The Security Development Lifecycle

    One Tool Does not Rule them All

    • 2 Comments

    Hello, Michael here...

    Over the last couple of years, I've released information about various Microsoft product security bugs that required security bulletins to explain why the SDL missed the bugs (if indeed it did) and what defenses came into play (if any) and what lessons could be learned from the bug.

    One thing that struck me is how most of the bugs I have discussed led us to improve our fuzzers, which is a more positive approach on "our fuzzers didn't find the bugs"!

    I talked a little about fuzz testing in a prior post, "Improve Security with ‘A Layer of Hurt'." If you read much about security, you'll see that fuzzing is a very effective security and reliability testing technique, but it is far from perfect.  In this short post I want to explain why it's imperfect and that any security-related development and testing process must employ more than one method to find security bugs.

    It's important to realize that the SDL requires development teams to run fuzz tests on much of their application functionality, including any file parsing code, ActiveX controls, RPC interfaces and network parsers. But we have never relied on fuzzing alone to find security bugs. We use fuzzers as well as various static analysis and dynamic analysis tools.

    No one type of security tool - fuzzers included - is the "One tool to rule them all."

    Let give you an example why fuzz testing is far from perfect with some sample highly buggy and contrived C++ code:

    #define COPY_DATA 0
    #define ZERO_DATA 1
    #define QUERY_DATA 2

    DWORD ProcessData(_In_bytecount_(cbBuf) BYTE *pBuf, size_t cbBuf) {

          if (!pBuf || cbBuf<5)
               return ERROR_INVALID_DATA;

     

          // Blob format is:
          //  1-byte 'verb' 
          //  4-byte data 
          //  n-byte data stream

          BYTE verb = pBuf[0];
          DWORD len = pBuf[1] + (pBuf[2]<<8) + (pBuf[3]<<16) + (pBuf[4]<<24);
          BYTE *data = &pBuf[5];

          char dest[20];

          if (verb == COPY_DATA) {
                sprintf(dest,"Foo:%s",data);
          } else if (verb == ZERO_DATA) {

                // Do stuff

          } else if (verb == QUERY_DATA) {

                // Do other stuff

          }

          // 
          // Other processing
          //

          return NO_ERROR;
    }

    Most compilers will compile this with no warning, and fuzzing this code might find the security bug in the call to sprintf but only if the fuzzed data triggers the vulnerable code path. Triggering the code path requires the verb to be zero, and the length of the data to be greater than 15 characters (twenty less the length of "Foo:" less the trailing NULL.) The word ‘length' is important in this case, because sprintf continues copying string data until it hits a NULL in the source string, so if the fuzzer often inserts NULLs in data streams, regardless of the number of bytes in the data stream, then this code might not fail.

    I want to stress the previous paragraph: fuzzing finds bugs only when the data causes execution of the vulnerable code path.

    For example, this byte stream will cause the code above to fail:

    0,12,0,0,0,'h','e','l','o','h','e', 'l','o','h','e', 'l','o'

    But this will not because the first byte, 1, leads down a different code path.

    1,12,0,0,0,'h','e','l','o','h','e', 'l','o','h','e', 'l','o'

    The data below will also not cause the code to fail, even though the data at the end of the buffer is large, because there's a NULL in the second byte.

    0,44,0,0,0,'h',0,'l','l','o','h','e','l','l','o','h','e','l','l','o','h','e','l','l','o','h','e','l','l','o','h','e','l','l','o','h','e','l','l','o','h','e','l','l','o','h','e','l','l','o','h','e','l','l','o','h','e','l','l','o','h','e','l','l','o',0

    Today the code sample above is flagged by the SDL process because sprintf is a banned function and should be replaced by a safer function such as StringCchPrintf or sprintf_s which should mean fuzzing has no bug to find. But it is possible to  miscalculate the buffer size arguments that the safer functions require, which means fuzzing is always valuable, especially if your static analysis tools don't find the bugs either.

    The lesson from this is there is no single correct way to find code bugs, you have to perform fuzz testing as well as static analysis and employ general good code hygiene if you want to raise the security of your software. In fact, it's possible that some developers might believe there is a single tool to solve their security ills and rely on it so much that they miss serious security vulnerabilities.
  • The Security Development Lifecycle

    Clickjacking Defense in IE8

    • 3 Comments

    Bryan here. The Internet Explorer team released the first public release candidate build of IE8 last week, which includes some very handy new security features I’d like to talk about. Steve and I have both blogged about the IE8 Cross-Site Scripting (XSS) Filter when it came out in the last public beta, and I wrote a piece on my own blog praising IE’s XDomainRequest (XDR) mechanism for making more secure cross-domain requests. This post will complete the IE8 security feature blog post hat trick and give some background and usage guidance around the new X-FRAME-OPTIONS clickjacking defense header.

    In case you’re unfamiliar with clickjacking, let me start from the top. All modern browsers support the iframe (inline-frame) HTML tag used to include content from another page in the current page. When the browser renders this tag, it fetches the page specified by the src attribute of the iframe tag and displays that page inside a region of the current page. For example:

    <iframe src="http://www.microsoft.com/" height="200px" width="200px" />

    Including this HTML tag on a web page will draw a 200x200 pixel frame displaying the home page of the Microsoft.com web site on that page. Users can interact with this frame just as if they had typed www.microsoft.com into the browser themselves; they can navigate hyperlinks, press buttons, submit forms, anything.

    Last year, security researchers Jeremiah Grossman and Robert “RSnake” Hansen demonstrated an attack they called “clickjacking”. The attack works like this: the attacker first creates an HTML page that included an iframe sourced to a legitimate site, but he doesn’t just display the top left 200x200 pixels. Instead, he positions and sizes the iframe and other page elements so that only the pixels of a specific control, such as a button, of the victim page are visible. The attacker then presents this partial iframe control in a completely different context from its original context in order to trick users into pressing it. An example will help to explain this better.

    The Contoso Bookstore web site has an excellent selection of computer security books and allows users to buy them with a single button click.

    contoso_bookstore_1

    An attacker now sets up a phony disaster relief web site with an iframe sourced to the Contoso site. He sets the iframe z-index to place it in the “back” of the page, then puts other page elements “over top” of it to cover the original text.

    <iframe

    src="http://www.contoso.com/bookstore/ajaxsecurity/"

    AllowTransparency="yes"

    style="float; position:absolute; left:0px; top:-200px; width: 300px; height: 275px; z-index: 5;"

    border="0"

    frameborder="0"

    scrolling="no" />

    <div style="position:absolute; left:0px; top:0px; width: 250px; height: 200px; background:white; z-index:10">

    <h1>Please help</h1>

    </div>

    disaster_relief_1

    Visitors to the site believe they’re donating to a disaster relief fund, but when they press the button, they’re really pressing the button on the Contoso web site, cleverly matted so that the users have no idea they’re pressing a button displayed in an iframe and not on the main document.

    IE8 mitigates this vulnerability by allowing developers to specify that their content should not be displayed in iframes. Developers can add the HTTP response header X-FRAME-OPTIONS: DENY to a web page to specify that that page should never be displayed in a frame. Alternatively, developers can add the header X-FRAME-OPTIONS: SAMEORIGIN to allow that page to only be displayed in iframes when the main document’s domain matches that page’s domain. So www.contoso.com/bookstore could display an iframe of www.contoso.com/checkout, but evilsite.com could not display that frame.

    (If you’d like more technical details on the X-FRAME-OPTIONS header, be sure to check out Eric Lawrence’s ClickJacking Defenses post on the IE blog.)

    Adding the header to your page, at least in ASP.NET, is trivial:

    this.Response.Headers["X-FRAME-OPTIONS"] = "DENY";

    The question is, When should you add it? In many ways, clickjacking is very similar to cross-site request forgery (XSRF). Both are types of “confused deputy” vulnerabilities in which the server accepts and processes a request because it believes that the user intended to make that request. In an XSRF attack, the fraudulent request comes from malicious HTML or script, while in a clickjacking attack the fraudulent request comes from the user interacting with misleadingly labeled controls, but the effect is the same. Since these vulnerabilities are similar, we can make a generalization and say that the types of pages that require XSRF defense are the same types of pages that require clickjacking defense.

    The value of both XSRF and clickjacking attacks is that the attacker can get the victim to perform an action with the victim’s credentials (usually stored in a cookie). In our earlier example, if the victim hadn’t been logged into the Contoso Bookstore then the attack would not have succeeded since there would be no account to charge the book purchase to. The key takeaway from this is that there’s really no reason to protect anonymously available pages from clickjacking. If the user doesn’t have to log into the site, there’s no need to apply the X-FRAME-OPTIONS header.

    Furthermore, since clickjacking attacks rely on user interface elements, there’s no need to apply the X-FRAME-OPTIONS header to web service methods. No UI, no clickjacking.

    Alternatively, you could avoid worrying about which pages to protect and which to skip and just apply the header for every page in the application. Just add an Application_BeginRequest method to the global.asax file and apply the response header in that method:

    void Application_BeginRequest(object sender, EventArgs e)

    {

      this.Response.Headers["X-FRAME-OPTIONS"] = "DENY";

    }

    Even better, you could apply the header automatically using the HTTP Response Header configuration feature in IIS 7 – no code changes required. You can set custom headers per-application or per-server to help protect all your sites.

    Finally, if you need more functionality than the IIS custom header feature provides – such as not adding an X-FRAME-OPTIONS header if one already exists – you could create an HttpModule and then use IIS to apply that module to your applications.

    public class XFrameOptionsModule : IHttpModule

    {

    #region IHttpModule Members

     

      public void Dispose()

      {

      }

      public void Init(HttpApplication context)

      {

      context.PreSendRequestHeaders += new

        EventHandler(context_PreSendRequestHeaders);

      }

     

    #endregion

     

      void context_PreSendRequestHeaders(object sender, EventArgs e)

      {

        HttpApplication application = sender as HttpApplication;

        if (application == null)

          return;

        if (application.Response.Headers["X-FRAME-OPTIONS"] != null)

          return;

        application.Response.Headers.Add("X-FRAME-OPTIONS", "DENY");

      }

    }

     

    You can compile this code into a DLL and deploy it into the bin directories of any applications you want to protect. Then use IIS to apply the module to those web sites. You can find step-by-step instructions on how to accomplish this here – don’t worry, it’s extremely straightforward.

    I highly recommend that you apply the X-FRAME-OPTIONS header to all web pages that you develop that you do not intend to be framed, whether by changing the application code directly, by configuring response headers in IIS, or by deploying an HttpModule. Clickjacking may not yet appear on anyone’s Top 10 Vulnerabilities List, but let’s nip it in the bud now and make sure it never gets there.

Page 1 of 1 (8 items)