Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [day] [month] [year] [list]
Date: Thu, 21 Feb 2013 15:33:48 -0500 (EST)
From: "Steven M. Christey" <>
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.


* 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

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

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

* 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

* Kurt - in
   you referred to "linear expansion."  If you mean the "quadratic
   blowup entity expansion" as documented on,
   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

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

   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,

   (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