Date: Thu, 21 Feb 2013 15:33:48 -0500 (EST) From: "Steven M. Christey" <coley@...re.org> To: oss-security@...ts.openwall.com Subject: CVE Guidance for Libraries and Resource-Consumption DoS (tl;dr - sorry, no such luck. There's too much to consider.) The recent discussions about XXE and related issues have touched upon a number of issues that must be considered for CVE assignment. INCLUSION (deciding whether to assign a CVE or not): * Whether an "insecure default configuration" in a library should receive a CVE. * How to draw the line between a "resource-consumption DoS" and acceptable, "normal" program behavior that just happens to be computationally intensive. ABSTRACTION (deciding how many CVEs to assign): * Whether a single CVE is assigned to a security concern in a library, or whether the applications using the library should receive their own CVEs. * When multiple issues are "new types" of vulnerabilities (or not well-understood types), it can be difficult to consistently decide when to SPLIT or MERGE. Such "new types" often spawn variants or are described poorly, so it can take some time before understanding and terminology stabilizes. * While DoS issues have been around for ages, their underlying root causes have not been studied as closely as issues like buffer overflows, so it can be difficult to consistently classify different DoS issues as different types. UTILITY: * When clarifying CVE content decisions, we often have to consider how useful they may be to the CVE-using public; how practical they will be to implement without extensive, labor-intensive analysis or expertise; how much they capture the "spirit" of past content decisions; and whether we believe they could cause practical problems in the future without sufficient benefit (the so-called "snowball effect" I've touched on before). * Because CVE is used so widely by many communities, we have sometimes had to accept improperly-applied content decisions instead of REJECTing the CVEs outright. We do not view such issues as establishing a precedent. A good example of this is CVE-2012-0217 (the Intel SYSRET issue), in which many different operating systems should have received different CVEs, but the community's over-use of this CVE would have caused many more problems if we had REJECTed it and split it into many different CVEs. (I know this example may be controversial to some, but the CVE assignment team is unified that this CVE should have been split.) This type of situation may occur again, so - assignment of past CVEs does not imply a blind commitment to be consistent in the future just because there is a precedent. Note that, when encountering a "novel" situation - or, at least, a situation that is rarely encountered - I will sometimes take a "wait and see" approach by doing things one way, and then (later) changing directions. While this is not ideal and can be frustrating to some people, the fact is that we have to assign CVE identifiers to real-world issues now, and the decisions that work for the short term might not necessarily be ideal in the long run. In some cases, the entire community might not understand the issues well enough. Of course, we always try to be right the first time, or at least after a couple examples have come up that raise awareness of the broader context. As a side note - I believe that the increase in chained exploits and overall complexity will pose additional challenges for vulnerability classification, vuln tracking, and vuln databases in the future. As vulnerabilities become more complex, we are likely to revisit some of these content decisions. CVE's "Traditional" Approach for Libraries ------------------------------------------ In general, when an issue appears to occur in a library, we determine whether an application developer can use the library safely, or whether there is no way to use it safely. If the library can't be used safely at all - then we would regard that as an issue in the library. We would assign a single CVE to that library, and we don't assign any new CVEs to applications that use the vulnerable library. If the developer has an opportunity to use the library correctly, but doesn't, then we treat this as a vulnerability in the application. Two classic examples of "library" problems are the C strcpy() function and the PHP include() function. Both of these functions have been responsible for hundreds or thousands of vulnerabilities in applications, but they can both be used safely if the programmer calls them properly (perhaps after some input validation or equivalent protection mechanism). Accordingly, we don't have just one CVE for strcpy() and one CVE for include() - we have hundreds of CVEs for the applications that happen to use these functions insecurely. With some libraries, however, the developer might not be able to have the same high degree of control in avoiding a vulnerability; more details later in this document. The boundaries between library and application responsibility can sometimes be blurred. For example, we have created some CVEs for buffer overflows or similar errors in PHP API functions where the programmer would almost never be expected to call the function with untrusted input. Libraries are "special" because they can be used by many different applications, in many different ways, and this can further complicate decisions. For example, a "secure fix" for one appliction developer could harm usability for a different developer. The perils of preserving a bad API are equalled only by the perils of changing an established API. Note that I'm personally very interested in issues of API design, and how API design choices can make it easier for application developers to introduce vulnerabilities, but from a CVE perspective, these interests are mostly irrelevant. In general, we want CVE to only cover specific, "actionable" problems instead of general warnings about secure coding. XXE etc. - Clarification on Vulnerability Types ----------------------------------------------- I'm going to address the easier issues first. Namely: * We regard (1) entity expansion (aka billion-laughs or XEE) and (2) external entity references to remote http://, file://, or other URLs (aka XXE) to be distinct vulnerability types, and thus worth a SPLIT. * Some of the recent disclosures cover additional issues that might be regarded as different types besides XXE/XXE (DTD retrieval, xpath support, xslt support, xinclude support). These will need to be investigated in more detail before CVE assignments can be completed. * In some cases, where there are two types of DoS, they MIGHT be worth a SPLIT. There are clear cases like a NULL pointer dereference crash versus a reachable assertion or divide by zero. Areas of algorithmic complexity, however, are not as well explored. This is sometimes a judgment call, which can introduce variation in how pepole decide whether to split or merge. An issue like an infinite loop (CPU and maybe memory consumption) might be different than another issue like uncontrolled memory allocation (just memory consumption, although the CPU and disk might get pretty busy too). In scenarios such as this, one general guideline is to consider whether the apparent fix for one issue will necessarily fix the other issue. If you have infinite recursion, then fixing it by limiting the recursion depth would not do anything against an uncontrolled memory allocation, so this would probably be worth a SPLIT. * Kurt - in http://www.openwall.com/lists/oss-security/2013/02/20/10 you referred to "linear expansion." If you mean the "quadratic blowup entity expansion" as documented on http://blog.python.org/2013/02/announcing-defusedxml-fixes-for-xml.html, we are not sure whether this could be treated as different than billion laughs. It's very likely that an implementation may fix billion-laughs in a way that does not also fix "quadratic blowup" issues; as the blog points out, this attack can "avoid triggering countermeasures of parsers against heavily nested entities." So, we are likely to see fixes for one variant, then a new software package will get hit with the other variant - at best, this might mean an incomplete fix (becuase of different affected versions, a SPLIT would be clear in such a scenario). But, the quadratic blowup represents larger questions about when we decide that algorithmic complexity is just normal behavior versus a vulnerability. Clarification on Resource-Consumption DoS ----------------------------------------- When does an application cross the line from being "easily exploited" to "just going slowly because it's been given so much data"? This is a CVE inclusion question, and there are no clear answers when it comes to resource consumption. We are almost certain to include an issue as a DoS when any of the following hold: (1) there is a worst-case complexity that's "really bad" compared to the average case (or at least, common usage) (2) the amount of effort required by the attacker is much less than the amount of effort for the affected program (e.g., ZIP bombs or Smurf/packet-storm attacks) (3) un-released resource issues (like memory leaks or file-descriptor exhaustion) where the attacker can realistically increase the overall resources of the program incrementally, such as consuming only a small amount of memory for each "session" (4) the attacker can exceed a resource-consumption "policy" that the software attempts to explicitly enforce (this includes bypassing quotas, or if the application doesn't correctly implement an administrator-specified configuration) Protection Mechanisms and "Default Configurations" in Libraries --------------------------------------------------------------- The following guidance generally applies to the responsibilities of libraries versus applications in avoiding vulnerabilities, but we pay special attention to resource consumption issues, since that's the topic of the day. * If the issue is an insecure "default configuration" in a library, please consult the MITRE CNA first. We do not yet have clear guidelines about whether to assign CVE identifiers. There are still too many considerations. There are definitely some benefits to some users, especially software integrators, for assigning CVEs. However, there are also some complications; for example, some XML libraries have a safer mode that must be set at compile time. On platforms that have the "shared libraries" and "packages" concepts, this is problematic because XML-application-package-A has no way to force a situation in which XML-library-package-B is recompiled. It could instead inline the third-party library code, but that has risks of its own. Sometimes the documentation suggests a source-code fix and there is no compilation option. Certainly it's too burdensome for the application code to examine the library code at run time to try to figure out what compilation options were used. In cases like this, where there is little recourse to the application developer to diagnose and fix the issue, we are likely to assign a CVE. Even if the XML library is configurable at run time, platforms with packages won't necessarily be able to handle this well. You can't have N applications that want to have independent control of the configuration file of one library. Finally, applications typically have to work with multiple versions of a library, especially multiple popular versions, so it might be reasonable to ask an application to take on some responsibility. So for now, we will treat these on a case-by-case basis. Some possibly-related precedents are: CVE-2010-4173 (requiring system-wide configuration, although it apparently is effectively for use by a single user); CVE-2010-2085 and CVE-2010-1459 (which are effectively for a framework, not a library, but we don't have application-specified CVEs; and CVE-2005-1992 (which is a "defualt configuration" in a programming language library). For now, if there is a "default configuration" or compiler-configured security setting in a library, please consult the MITRE CNA. * If a library DOES NOT have a built-in mechanism for input that can reasonably be expected to be untrusted, then it can be generically abused and the programmer has no easy way of working around it. So, the library should get a single CVE. For example, an XML library should be expected to operate on an untrusted XML file. By contrast, the glibc malloc implementation can't be considered responsible for detecting abusive arguments (allocation of 4+ gigabytes of memory may be perfectly legitimate in some cases.) * If a library DOES have a mechanism or "policy" for limiting resource consumption or other vulnerable conditions, then it does not get a CVE (although a bypass of such a mechanism still qualifies.) When a protection mechanism is available, responsibility shifts to applications. An application should receive a CVE if all of the following hold: (A) the library provides an API mechanism through which safe operation can be achieved, (B) the application does not use that mechanism for safe operation, and (C) the application does not use any other mechanism for safe operation (e.g., resource-limited child processes). Any application that uses the library without (1) using its resource-consumption limits or (2) otherwise implementing its own protection mechanisms (such as spawning child processes with memory limits), should get a CVE. This second item is important - we shouldn't "blame" an application just because it uses its own protection mechanism instead of the library's mechanism. We know this means that a large number of applications can be "blamed" and will receive a CVE. But, no library can be reasonably expected to make universal decisions on resource limits for ALL of its potential users - that would hurt usability. We hope that this post is helpful and informative in explaining how we interpret CVE's content decisions as the vulnerability information landscape continues to evolve. Steve Christey and the CVE assignment team MITRE CVE Numbering Authority
Powered by blists - more mailing lists
Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.
Powered by Openwall GNU/*/Linux - Powered by OpenVZ