VIEW SLICE: CWE-630: Weaknesses Examined by SAMATE
(Draft 9)
View Components View Components A |
B |
C |
D |
E |
F |
G |
H |
I |
J |
K |
L |
M |
N |
O |
P |
Q |
R |
S |
T |
U |
V |
W |
X |
Y |
Z
Weakness ID
| Status: Draft 415 (Weakness Variant) | | Description | Summary The product calls free() twice on
the same memory address, potentially leading to
modification of unexpected memory locations. | | Alternate Terms | Double-free | | Likelihood of Exploit | Low to Medium | | Affected Resource | Memory | | Common Consequences | Access control: Doubly freeing memory may result in a write-what-where
condition, allowing an attacker to execute arbitrary code. | | Potential Mitigations | Implementation: Ensure that each allocation is freed only once. After freeing a chunk,
set the pointer to NULL to ensure the pointer cannot be freed again. In complicated error
conditions, be sure that clean-up routines respect the state of allocation properly. If the
language is object oriented, ensure that object destructors delete each chunk of memory only
once. | Demonstrative Examples | Example 1: The following code shows a simple example of a double free vulnerability. char* ptr = (char*)malloc (SIZE); ... if (abrt) { free(ptr); } ... free(ptr); Double free vulnerabilities have two common (and sometimes overlapping) causes: -
Error conditions and other exceptional circumstances - Confusion over which part of the
program is responsible for freeing the memory Although some double free vulnerabilities
are not much more complicated than the previous example, most are spread out across
hundreds of lines of code or even different files. Programmers seem particularly
susceptible to freeing global variables more than once.
Example 2: While contrived, this code should be exploitable on Linux distributions
which do not ship with heap-chunk check summing turned on. #include <stdio.h> #include <unistd.h> #define BUFSIZE1 512 #define BUFSIZE2 ((BUFSIZE1/2) - 8) int main(int argc, char **argv) { char *buf1R1; char *buf2R1; char *buf1R2; buf1R1 = (char *) malloc(BUFSIZE2); buf2R1 = (char *) malloc(BUFSIZE2); free(buf1R1); free(buf2R1); buf1R2 = (char *) malloc(BUFSIZE1); strncpy(buf1R2, argv[1], BUFSIZE1-1); free(buf2R1); free(buf1R2); } | | Observed Examples | | | Context Notes | This is usually resultant from another weakness, such as an unhandled error or race
condition between threads. It could also be primary to weaknesses such as buffer overflows. Also a Consequence. When a program calls free() twice with the same argument, the program's memory
management data structures become corrupted. This corruption can cause the program to crash or, in
some circumstances, cause two later calls to malloc() to return the same pointer. If malloc()
returns the same value twice and the program later gives the attacker control over the data that
is written into this doubly-allocated memory, the program becomes vulnerable to a buffer overflow
attack.
It could be argued that Double Free would be most appropriately located as a child of "Use after Free", but we're considering "Use" and "Release" to be distinct operations, therefore this is more accurately "Release of a Resource after Expiration or Release", which doesn't exist yet.
| | Relationships | | | Source Taxonomies | PLOVER - DFREE - Double-Free Vulnerability 7 Pernicious Kingdoms - Double Free CLASP - Doubly freeing memory | | Applicable Platforms | C C++ |
Weakness ID
| Status: Draft 244 (Weakness Variant) | | Description | Summary Using realloc() to resize buffers that store sensitive information can leave the
sensitive information exposed to attack, because it is not removed from memory. | | Affected Resource | Memory | Demonstrative Examples | The following code calls realloc() on a buffer containing sensitive data: cleartext_buffer = get_secret(); ... cleartext_buffer = realloc(cleartext_buffer, 1024); ... scrub_memory(cleartext_buffer, 1024); There is an attempt to scrub the sensitive data from memory, but realloc() is used,
so a copy of the data can still be exposed in the memory originally allocated for
cleartext_buffer. | | Context Notes | Heap inspection vulnerabilities occur when sensitive data, such as a password or an
encryption key, can be exposed to an attacker because they are not removed from memory. The
realloc() function is commonly used to increase the size of a block of allocated memory. This
operation often requires copying the contents of the old memory block into a new and larger block.
This operation leaves the contents of the original block intact but inaccessible to the program,
preventing the program from being able to scrub sensitive data from memory. If an attacker can
later examine the contents of a memory dump, the sensitive data could be exposed. Be careful using {vfork, fork} in security sensitive code. The process state will not
be cleaned up and will contain traces of data from past use. | | Relationships | | | Source Taxonomies | 7 Pernicious Kingdoms - Heap Inspection | | Applicable Platforms | C C++ | | Time of Introduction | Implementation |
Weakness ID
| Status: Draft 401 (Weakness Base) | | Description | Summary The software does not sufficiently track and release allocated memory after it has been
used, which slowly consumes remaining memory. This is often triggered by improper handling of
malformed data or unexpectedly interrupted sessions. | | Functional Area | Memory management | | Likelihood of Exploit | Medium | | Affected Resource | Memory | | Common Consequences | Availability: If an attacker can determine the cause of the memory leak, then
the attacker may be able to cause the application to leak quickly and therefore cause the
application to crash. | | Potential Mitigations | Pre-design: Use a language or compiler that performs automatic bounds checking. Design: Use an abstraction library to abstract away risky APIs. Not a complete
solution. Pre-design through Build: The Boehm-Demers-Weiser Garbage Collector or valgrind can be
used to detect leaks in code. This is not a complete solution as it is not 100%
effective. | Demonstrative Examples | Example 1: The following C function leaks a block of allocated memory if the call to
read() fails to return the expected number of bytes: C Example: char* getBlock(int fd) { char* buf = (char*) malloc(BLOCK_SIZE); if (!buf) { return NULL; } if (read(fd, buf, BLOCK_SIZE) != BLOCK_SIZE) { return NULL; } return buf; }
Example 2: In C: C Example: bar connection(){ foo = malloc(1024); return foo; } endConnection(bar foo) { free(foo); } int main() { while(1) //thread 1 //On a connection foo=connection(); //thread 2 //When the connection ends endConnection(foo) } } Here the problem is that every time a connection is made, more memory is allocated.
So if one just opened up more and more connections, eventually the machine would run out
of memory. | | Observed Examples | | Reference | Description |
|---|
| CVE-2005-3119 | Memory leak because function does not free() an element of a data structure. | | CVE-2004-0427 | Memory leak when counter variable is not decremented. | | CVE-2002-0574 | Memory leak when counter variable is not decremented. | | CVE-2005-3181 | Kernel uses wrong function to release a data structure, preventing data from being
properly tracked by other code. | | CVE-2004-0222 | Memory leak via unknown manipulations as part of protocol test suite. | | CVE-2001-0136 | Memory leak via a series of the same command. |
| | Context Notes | This is often a resultant weakness due to improper handling of malformed data or early
termination of sessions. Terminology Note: "memory leak" has sometimes been used to describe other kinds of
issues, e.g. for information leaks in which the contents of memory are inadvertently leaked
(CVE-2003-0400 is one such example of this terminology conflict). Memory leaks have two common and sometimes overlapping causes: - Error conditions and
other exceptional circumstances. - Confusion over which part of the program is responsible for
freeing the memory Most memory leaks result in general software reliability problems, but if an
attacker can intentionally trigger a memory leak, the attacker might be able to launch a denial of
service attack (by crashing the program) or take advantage of other unexpected program behavior
resulting from a low memory condition [30]. | | References | [30] J. Whittaker and H. Thompson.
"How to Break Software Security". Addison Wesley. 2003. | | Relationships | | | Source Taxonomies | PLOVER - Memory leak 7 Pernicious Kingdoms - Memory Leak CLASP - Failure to deallocate data | | Applicable Platforms | C C++ | | White Box Definition | A weakness where the code path has: 1. start statement that allocates dynamically allocated memory resource 2. end statement that loses identity of the dynamically allocated memory resource creating situation where dynamically allocated memory resource is never relinquished Where “loses” is defined through the following scenarios: 1. identity of the dynamic allocated memory resource never obtained 2. identity of the dynamic allocated memory resource obtained but got re-written (missing beyond recovery) 3. identity of the dynamic allocated memory resource obtained but never passed on to function for memory resource release 4. the statement assigns another value to the last data element that stored the identity of the dynamically allocated memory resource (no more aliases remain) 5. the last data element that stored the identity of the dynamically allocated resource has reached the end of its scope at the statement
|
Weakness ID
| Status: Incomplete 78 (Weakness Base) | | Description | Summary The software fails to adequately filter OS command syntax from user-controlled input
and then allows potentially injected commands to execute within its context. A software system
that accepts and executes input in the form of operating system commands (e.g. system(), exec(),
open()) could allow an attacker with lesser privileges than the target software to execute
commands with the elevated privileges of the executing process. The problem is exacerbated if the
compromised process fails to follow the principle of least privilege. | | Alternate Terms | Shell injection, shell metacharacters | | Functional Area | Program invocation | | Affected Resource | System Process | | Potential Mitigations | Design: If at all possible, use library calls rather than external processes
to recreate the desired functionality Implementation: Utilize black-list parsing to filter non-relevant OS command syntax from all input. Implementation: Ensure that all external commands called from the program
are statically created, or -- if they must take input from a user -- that the input
and final line generated are vigorously white-list checked. Run time: Run time policy enforcement may be used in a white-list fashion to
prevent use of any non-sanctioned commands. Assign permissions to the software system that prevents the user from
accessing/opening privileged files. | | Observed Examples | | | Context Notes | Fault: unquoted special characters, input restriction error | | References | G. Hoglund and G. McGraw.
"Exploiting Software: How to Break Code". Addison-Wesley. February 2004. | | Relationships | | | Source Taxonomies | PLOVER - OS Command Injection | | Applicable Platforms | All | | Related Attack Patterns | | CAPEC-ID | Attack Pattern Name |
|---|
| 88 | OS Command Injection | | 15 | Command Delimiters | | 6 | Argument Injection | | 43 | Exploiting Multiple Input Interpretation Layers |
| | White Box Definition | A weakness where the code path has: 1. start statement that accepts input 2. end statement that executes an operating system command where a. the input is used as a part of the operating system command b. the privilege of the operating system command is higher than privilege of the input and c. the operating system command is undesirable Where “undesirable” is defined through the following scenarios: 1. not validated 2. incorrectly validated
|
Weakness ID
| Status: Incomplete 89 (Weakness Base) | | Description | Summary The application fails to adequately filter SQL syntax from user-controllable input. This can lead to such input being interpreted as SQL rather than ordinary user data and be executed as part of a dynamically generated SQL query. This is a specific form of an injection problem, one that explicitly affects SQL databases, in which SQL commands are injected into data-plane input in order to effect the execution of dynamically generated SQL statements. | | Likelihood of Exploit | Very High | | Common Consequences | Confidentiality: Since SQL databases generally hold sensitive data, loss of
confidentiality is a frequent problem with SQL injection vulnerabilities. Authentication: If poor SQL commands are used to check user names and
passwords, it may be possible to connect to a system as another user with no previous
knowledge of the password. Authorization: If authorization information is held in a SQL database, it may
be possible to change this information through the successful exploitation of a SQL injection
vulnerability. Integrity: Just as it may be possible to read sensitive information, it is
also possible to make changes or even delete this information with a SQL injection
attack. | | Potential Mitigations | Requirements specification: A non-SQL style database which is not subject to this flaw
may be chosen. Design: Follow the principle of least privilege when creating user accounts to a SQL
database. Users should only have the minimum privileges necessary to use their account. If the
requirements of the system indicate that a user can read and modify their own data, then limit
their privileges so they cannot read/write others' data. Design: Duplicate any filtering done on the client-side on the server side. Implementation: Implement SQL strings using prepared statements that bind variables.
Prepared statements that do not bind variables can be vulnerable to attack. Implementation: Use vigorous white-list style checking on any user input that may be
used in a SQL command. Rather than escape meta-characters, it is safest to disallow them
entirely. Reason: Later use of data that have been entered in the database may neglect to
escape meta-characters before use. Narrowly define the set of safe characters based on the
expected value of the parameter in the request. | Demonstrative Examples | The following code dynamically constructs and executes a SQL query that searches for
items matching a specified name. The query restricts the items displayed to those where
owner matches the user name of the currently-authenticated user. C# Example: ... string userName = ctx.getAuthenticatedUserName(); string query = "SELECT * FROM items WHERE owner = '" + userName + "' AND itemname = '" + ItemName.Text + "'"; sda = new SqlDataAdapter(query, conn); DataTable dt = new DataTable(); sda.Fill(dt); ... The query that this code intends to execute follows: SELECT * FROM items WHERE owner
= <userName> AND itemname = <itemName>; However, because the
query is constructed dynamically by concatenating a constant base query string and a user
input string, the query only behaves correctly if itemName does not contain a single-quote
character. If an attacker with the user name wiley enters the string "name' OR 'a'='a" for
itemName, then the query becomes the following: SELECT * FROM items WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a'; The addition of the OR 'a'='a' condition causes the
where clause to always evaluate to true, so the query becomes logically equivalent to the
much simpler query: SELECT * FROM items; This simplification of the query allows the
attacker to bypass the requirement that the query only return items owned by the
authenticated user; the query now returns all entries stored in the items table,
regardless of their specified owner.
This example examines the effects of a different malicious value passed to the query
constructed and executed in the above example. If an attacker with the user name hacker
enters the string "hacker'); DELETE FROM items; --" for itemName, then the query becomes
the following two queries: SQL Example: SELECT * FROM items WHERE owner = 'wiley' AND itemname = 'name'; DELETE FROM items; --' Many database servers, including Microsoft(R) SQL Server 2000, allow multiple SQL
statements separated by semicolons to be executed at once. While this attack string
results in an error on Oracle and other database servers that do not allow the
batch-execution of statements separated by semicolons, on databases that do allow batch
execution, this type of attack allows the attacker to execute arbitrary commands against
the database. Notice the trailing pair of hyphens (--), which specifies to most database
servers that the remainder of the statement is to be treated as a comment and not executed
[19]. In this case the comment character serves to remove the trailing single-quote left
over from the modified query. On a database where comments are not allowed to be used in
this way, the general attack could still be made effective using a trick similar to the
one shown in Example 1. If an attacker enters the string "name'); DELETE FROM items;
SELECT * FROM items WHERE owner = 'wiley' AND itemname = 'name'; DELETE FROM items; SELECT
* FROM items WHERE 'a'='a'; One traditional approach to preventing SQL injection attacks
is to handle them as an input validation problem and either accept only characters from a
whitelist of safe values or identify and escape a blacklist of potentially malicious
values. Whitelisting can be a very effective means of enforcing strict input validation
rules, but parameterized SQL statements require less maintenance and can offer more
guarantees with respect to security. As is almost always the case, blacklisting is riddled
with loopholes that make it ineffective at preventing SQL injection attacks. For example,
attackers can: - Target fields that are not quoted - Find ways to bypass the need for
certain escaped meta-characters - Use stored procedures to hide the injected
meta-characters Manually escaping characters in input to SQL queries can help, but it will
not make your application secure from SQL injection attacks. Another solution commonly
proposed for dealing with SQL injection attacks is to use stored procedures. Although
stored procedures prevent some types of SQL injection attacks, they fail to protect
against many others. For example, the following PL/SQL procedure is vulnerable to the same
SQL injection attack shown in the first example. procedure get_item ( itm_cv IN OUT
ItmCurTyp, usr in varchar2, itm in varchar2) is open itm_cv for ' SELECT * FROM items
WHERE ' || 'owner = '|| usr || ' AND itemname = ' || itm || '; end get_item; Stored
procedures typically help prevent SQL injection attacks by limiting the types of
statements that can be passed to their parameters. However, there are many ways around the
limitations and many interesting statements that can still be passed to stored procedures.
Again, stored procedures can prevent some exploits, but they will not make your
application secure against SQL injection attacks.
MS SQL has a built in function that enables shell command execution. An
SQL injection in such a context could be disastrous. For example, a query of the
form: SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='$user_input' ORDER BY PRICE Where $user_input is taken from the user and
unfiltered. If the user provides the string: ' exec master..xp_cmdshell 'vol' -- The query will take the following form: " SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='' exec master..xp_cmdshell 'vol' --' ORDER BY PRICE Now, this query can be broken down into: [1] a first SQL query: SELECT ITEM,PRICE
FROM PRODUCT WHERE ITEM_CATEGORY='' [2] a second SQL query, which executes a shell
command: exec master..xp_cmdshell 'vol' [3] an MS SQL comment: --' ORDER BY PRICE As can
be seen, the malicious input changes the semantics of the query into a query, a shell
command execution and a comment. | | Observed Examples | | | Context Notes | SQL injection has become a common issue with database-driven web sites. The flaw is
easily detected, and easily exploited, and as such, any site or software package with even a
minimal user base is likely to be subject to an attempted attack of this kind. Essentially, the
attack is accomplished by placing a meta character into data input to then place SQL commands in
the control plane, which did not exist there before. This flaw depends on the fact that SQL makes
no real distinction between the control and data planes. If successful, SQL Injection attacks can give an attacker access to backend database
contents, the ability to remotely execute system commands, or in some circumstances the means to
take control of the Windows server hosting the database. Dynamically generating queries that include user input can lead to SQL injection
attacks. An attacker can insert SQL commands or modifiers in the user input that can cause the
query to behave in an unsafe manner. Constructing a dynamic SQL statement with user input may allow an attacker to modify
the statement's meaning or to execute arbitrary SQL commands. Factors: resultant to special character mismanagement, MAID, or blacklist/whitelist
problems. Can be primary to authentication errors. | | References | M. Howard and D. LeBlanc.
"Writing Secure Code". 2nd Edition. Microsoft. 2003. | | Relationships | | | Source Taxonomies | PLOVER - SQL injection 7 Pernicious Kingdoms - SQL Injection CLASP - SQL injection | | Applicable Platforms | All | | Related Attack Patterns | | CAPEC-ID | Attack Pattern Name |
|---|
| 66 | SQL Injection | | 7 | Blind SQL Injection |
| | White Box Definition | A weakness where the code path has: 1. start statement that accepts input 2. end statement that performs an SQL command where a. the input is part of the SQL command and b. the SQL command is undesirable Where “undesirable” is defined through the following scenarios: 1. not validated 2. incorrectly validated
|
Weakness ID
| Status: Incomplete 80 (Weakness Variant) | | Description | Summary The web application fails to adequately filter user-controlled input and sanitize its own output for any special characters, such as "<", ">", and "&". This may allow such characters to be treated as control characters, which are executed client-side in the context of the user's session. Although this can be classified as an injection problem, the more pertinent issue is the failure to convert such special characters to respective context-appropriate entities before displaying them to the user. | | Likelihood of Exploit | High to Very High | | Weakness Ordinality | Primary (Weakness exists independent of other weaknesses) | | Causal Nature | Explicit (This is an explicit weakness resulting from behavior of the developer) | | Potential Mitigations | Carefully check each input parameter against a rigorous positive
specification (white list) defining the specific characters and format allowed. All
input should be sanitized, not just parameters that the user is supposed to specify,
but all data in the request, including hidden fields, cookies, headers, the URL
itself, and so forth. A common mistake that leads to continuing XSS vulnerabilities
is to validate only fields that are expected to be redisplayed by the site. We often
encounter data from the request that is reflected by the application server or the
application that the development team did not anticipate. Also, a field that is not
currently reflected may be used by a future developer. Therefore, validating ALL
parts of the HTTP request is recommended. This involves "HTML Entity Encoding" all non-alphanumeric characters from
data that was received from the user and is now being written to the request. With Struts, you should write all data from form beans with the bean's
filter attribute set to true. Additionally, to help mitigate XSS attacks against the user's session
cookie, set the session cookie to be HttpOnly. In browsers that support the HttpOnly
feature (such as Internet Explorer), this attribute prevents the user's session
cookie from being accessed by client-side scripts, including scripts inserted due to
a XSS attack. | | Observed Examples | | | Relationships | | | Source Taxonomies | PLOVER - Basic XSS | | Applicable Platforms | All | | Related Attack Patterns | | CAPEC-ID | Attack Pattern Name |
|---|
| 18 | Embedding Scripts in Nonscript Elements |
| | White Box Definition | A weakness where the code path has: 1. start statement that accepts input from HTML page 2. end statement that publishes the a data item to HTML where a. the input is part of the data item and b. the input is undesirable Where “undesirable” is defined through the following scenarios: 1. not validated 2. incorrectly validated
|
Weakness ID
| Status: Incomplete 259 (Weakness Base) | | Description | Summary Hard coded passwords may compromise system security in a way that cannot be easily
remedied. It is never a good idea to hardcode a password. Not only does hardcoding a password
allow all of the project's developers to view the password, it also makes fixing the problem
extremely difficult. Once the code is in production, the password cannot be changed without
patching the software. If the account protected by the password is compromised, the owners of the
system will be forced to choose between security and availability. | | Likelihood of Exploit | Very High | | Weakness Ordinality | Primary (Weakness exists independent of other weaknesses) | | Causal Nature | Explicit (This is an explicit weakness resulting from behavior of the developer) | | Common Consequences | Authentication: If hard-coded passwords are used, it is almost certain that
malicious users will gain access through the account in question. | | Potential Mitigations | Design (for default accounts): Rather than hard code a default username and password
for first time logins, utilize a "first login" mode which requires the user to enter a unique
strong password. Design (for front-end to back-end connections): Three solutions are possible, although
none are complete. The first suggestion involves the use of generated passwords which are
changed automatically and must be entered at given time intervals by a system administrator.
These passwords will be held in memory and only be valid for the time intervals. Next, the
passwords used should be limited at the back end to only performing actions valid to for the
front end, as opposed to having full access. Finally, the messages sent should be tagged and
checksummed with time sensitive values so as to prevent replay style attacks. | Demonstrative Examples | The following code uses a hardcoded password to connect to a database: ... DriverManager.getConnection(url, "scott", "tiger"); ... This code will run successfully, but anyone who has access to it will have access to
the password. Once the program has shipped, there is no going back from the database user
"scott" with a password of "tiger" unless the program is patched. A devious employee with
access to this information can use it to break into the system. Even worse, if attackers
have access to the bytecode for application, they can use the javap -c command to access
the disassembled code, which will contain the values of the passwords used. The result of
this operation might look something like the following for the example above: javap -c
ConnMngr.class 22: ldc #36; //String jdbc:mysql://ixne.com/rxsql 24: ldc #38; //String
scott 26: ldc #17; //String tiger
C/C++ Example: int VerifyAdmin(char *password) { if (strcmp(password, "Mew!")) { printf("Incorrect Password!\n"); return(0) } printf("Entering Diagnostic Mode...\n"); return(1); } Java Example: int VerifyAdmin(String password) { if (passwd.Eqauls("Mew!")) { return(0) } //Diagnostic Mode return(1); } Every instance of this program can be placed into diagnostic mode with the same
password. Even worse is the fact that if this program is distributed as a binary-only
distribution, it is very difficult to change that password or disable this
"functionality." | | Context Notes | The use of a hard-coded password has many negative implications -- the most significant
of these being a failure of authentication measures under certain circumstances. On many systems,
a default administration account exists which is set to a simple default password which is
hard-coded into the program or device. This hard-coded password is the same for each device or
system of this type and often is not changed or disabled by end users. If a malicious user comes
across a device of this kind, it is a simple matter of looking up the default password (which is
freely available and public on the internet) and logging in with complete access. In systems that
authenticate with a back-end service, hard-coded passwords within closed source or drop-in
solution systems require that the back-end service use a password which can be easily discovered.
Client-side systems with hard-coded passwords pose even more of a threat, since the extraction
of a password from a binary is usually very simple. | | Relationships | | | Source Taxonomies | 7 Pernicious Kingdoms - Password Management: Hard-Coded Password CLASP - Use of hard-coded password | | Applicable Platforms | All | | Time of Introduction | Architecture and Design |
Weakness ID
| Status: Draft 122 (Weakness Variant) | | Description | Summary A heap overflow condition is a buffer overflow, where the buffer that can be overwritten
is allocated in the heap portion of memory, generally meaning that the buffer was allocated using
a routine such as malloc(). | | Likelihood of Exploit | High to Very High | | Weakness Ordinality | Primary (Weakness exists independent of other weaknesses) | | Causal Nature | Explicit (This is an explicit weakness resulting from behavior of the developer) | | Affected Resource | Memory | | Common Consequences | Availability: Buffer overflows generally lead to crashes. Other attacks
leading to lack of availability are possible, including putting the program into an infinite
loop. Access control (memory and instruction processing): Buffer overflows often can
be used to execute arbitrary code, which is usually outside the scope of a program's implicit
security policy. Other: When the consequence is arbitrary code execution, this can often be
used to subvert any other security service. | | Potential Mitigations | Pre-design: Use a language or compiler that performs automatic bounds checking. Design: Use an abstraction library to abstract away risky APIs. Not a complete
solution. Pre-design through Build: Canary style bounds checking, library changes which ensure
the validity of chunk data, and other such fixes are possible, but should not be relied upon. Operational: Use OS-level preventative functionality. Not a complete
solution. | Demonstrative Examples | C Example: #define BUFSIZE 256 int main(int argc, char **argv) { char *buf; buf = (char *)malloc(BUFSIZE); strcpy(buf, argv[1]); } | | Observed Examples | | Reference | Description |
|---|
| CVE-2007-4268 | Chain: integer signedness passes signed comparison, leads to
heap overflow |
| | Context Notes | Heap-based buffer overflows are usually just as dangerous as stack-based buffer
overflows. Besides important user data, heap-based overflows can be used to overwrite function
pointers that may be living in memory, pointing it to the attacker's code. Even in applications
that do not explicitly use function pointers, the run-time will usually leave many in memory. For
example, object methods in C++ are generally implemented using function pointers. Even in C
programs, there is often a global offset table used by the underlying runtime. | | Relationships | | | Source Taxonomies | CLASP - Heap overflow | | Applicable Platforms | C C++ | | Time of Introduction | Implementation | | Related Attack Patterns | | CAPEC-ID | Attack Pattern Name |
|---|
| 92 | Forced Integer Overflow |
| | White Box Definition | A buffer overflow where the buffer from the Buffer Write Operation is dynamically allocated
|
Weakness ID
| Status: Incomplete 170 (Weakness Base) | | Description | Summary The software does not properly terminate a string or array with a null character or
equivalent terminator. Null termination errors frequently occur in two different ways. An
off-by-one error could cause a null to be written out of bounds, leading to an overflow. Or, a
program could use a strncpy() function call incorrectly, which prevents a null terminator from
being added at all. Other scenarios are possible. | | Likelihood of Exploit | High | | Potential Mitigations | If performance constraints permit, special code can be added that validates
null-termination of string buffers, this is a rather naïve and error-prone solution. Switch to bounded string manipulation functions. Inspect buffer lengths involved in
the buffer overrun trace reported with the defect. Add code that fills buffers with nulls (however, the length of buffers still needs to
be inspected, to ensure that the non null-terminated string is not written at the physical end
of the buffer). | Demonstrative Examples | Example 1: The following code reads from cfgfile and copies the input into inputbuf
using strcpy(). The code mistakenly assumes that inputbuf will always contain a NULL
terminator. #define MAXLEN 1024 ... char *pathbuf[MAXLEN]; ... read(cfgfile,inputbuf,MAXLEN); //does not null terminate strcpy(pathbuf,input_buf); //requires null terminated input ... The code in Example 1 will behave correctly if the data read from cfgfile is null
terminated on disk as expected. But if an attacker is able to modify this input so that it
does not contain the expected NULL character, the call to strcpy() will continue copying
from memory until it encounters an arbitrary NULL character. This will likely overflow the
destination buffer and, if the attacker can control the contents of memory immediately
following inputbuf, can leave the application susceptible to a buffer overflow
attack.
Example 2: In the following code, readlink() expands the name of a symbolic link
stored in the buffer path so that the buffer filename contains the absolute path of the
file referenced by the symbolic link. The length of the resulting value is then calculated
using strlen(). ... char buf[MAXPATH]; ... readlink(path, buf, MAXPATH); int length = strlen(filename); ... The code in Example 2 will not behave correctly because the value read into buf by
readlink() will not be null terminated. In testing, vulnerabilities like this one might
not be caught because the unused contents of buf and the memory immediately following it
may be NULL, thereby causing strlen() to appear as if it is behaving correctly. However,
in the wild strlen() will continue traversing memory until it encounters an arbitrary NULL
character on the stack, which results in a value of length that is much larger than the
size of buf and may cause a buffer overflow in subsequent uses of this value. Buffer
overflows aside, whenever a single call to readlink() returns the same value that has been
passed to its third argument, it is impossible to know whether the name is precisely that
many bytes long, or whether readlink() has truncated the name to avoid overrunning the
buffer. Traditionally, strings are represented as a region of memory containing data
terminated with a NULL character. Older string-handling methods frequently rely on this
NULL character to determine the length of the string. If a buffer that does not contain a
NULL terminator is passed to one of these functions, the function will read past the end
of the buffer. Malicious users typically exploit this type of vulnerability by injecting
data with unexpected size or content into the application. They may provide the malicious
input either directly as input to the program or indirectly by modifying application
resources, such as configuration files. In the event that an attacker causes the
application to read beyond the bounds of a buffer, the attacker may be able use a
resulting buffer overflow to inject and execute arbitrary code on the system. | | Observed Examples | | Reference | Description |
|---|
| CVE-2000-0312 | Attacker does not null-terminate argv[] when invoking another program. | | CVE-2003-0777 | Interrupted step causes resultant lack of null termination. | | CVE-2004-1072 | Fault causes resultant lack of null termination, leading to buffer expansion. | | CVE-2001-1389 | Multiple vulnerabilities related to improper null termination. | | CVE-2003-0143 | Product does not null terminate a message buffer after snprintf-like call, leading to
overflow. |
| | Context Notes | Conceptually, this does not just apply to the C language; any language or
representation that involves a terminator could have this sort of problem. Factors: this is usually resultant from other weaknesses such as off-by-one errors, but
it can be primary to boundary condition violations such as buffer overflows. In buffer overflows,
it can act as an expander for assumed-immutable data. Overlaps missing input terminator. | | Relationships | | | Source Taxonomies | PLOVER - Improper Null Termination 7 Pernicious Kingdoms - String Termination Error | | Applicable Platforms | C C++ | | White Box Definition | A weakness where the code path has: 1. end statement that passes a data item to a null-terminated string function 2. start statement that removes the null-terminator from the data item Where “removes” is defined through the following scenarios: 1. data item never ended with null-terminator 2. null-terminator is re-written 3. null-terminator was purposely removed from data item
|
Weakness ID
| Status: Incomplete 468 (Weakness Base) | | Description | Summary In C and C++, one may often accidentally refer to the wrong memory due to the semantics
of when math operations are implicitly scaled. | | Likelihood of Exploit | Medium | | Common Consequences | Often results in buffer overflow conditions. | | Potential Mitigations | Design: Use a platform with high-level memory abstractions. Implementation: Always use array indexing instead of direct pointer manipulation. Other: Use technologies for preventing buffer overflows. | Demonstrative Examples | int *p = x; char * second_char = (char *)(p + 1); In this example, second_char is intended to point to the second byte of p. But,
adding 1 to p actually adds sizeof(int) to p, giving a result that is incorrect (3 bytes
off on 32-bit platforms). If the resulting memory address is read, this could potentially
be an information leak. If it is a write, it could be a security-critical write to
unauthorized memory-- whether or not it is a buffer overflow. Note that the above code may
also be wrong in other ways, particularly in a little endian environment. | | Context Notes | Programmers will often try to index from a pointer by adding a number of bytes, even
though this is wrong, since C and C++ implicitly scale the operand by the size of the data type. | | Relationships | | | Source Taxonomies | CLASP - Unintentional pointer scaling | | Applicable Platforms | C C++ |
Weakness ID
| Status: Draft 99 (Weakness Base) | | Description | Summary The software allows user-controlled input to control resource identifiers. This may enable an attacker to access or modify otherwise protected system resources. | | Likelihood of Exploit | High | | Weakness Ordinality | Primary (Weakness exists independent of other weaknesses) | | Causal Nature | Explicit (This is an explicit weakness resulting from behavior of the developer) | | Potential Mitigations | Assume all input is malicious. Use an appropriate combination of black lists and white
lists to ensure only valid and expected input is processed by the system. | Demonstrative Examples | The following Java code uses input from an HTTP request to create a file name. The
programmer has not considered the possibility that an attacker could provide a file name
such as "../../tomcat/conf/server.xml", which causes the application to delete one of its
own configuration files. Java Example: String rName = request.getParameter("reportName"); File rFile = new File("/usr/local/apfr/reports/" + rName); ... rFile.delete();
The following code uses input from the command line to determine which file to open
and echo back to the user. If the program runs with privileges and malicious users can
create soft links to the file, they can use the program to read the first part of any file
on the system. C++ Example: ifstream ifs(argv[0]); string s; ifs >> s; cout << s; The kind of resource the data affects indicates the kind of content that may be
dangerous. For example, data containing special characters like period, slash, and
backslash, are risky when used in methods that interact with the file system. (Resource
injection, when it is related to file system resources, sometimes goes by the name "path
manipulation.") Similarly, data that contains URLs and URIs is risky for functions that
create remote connections. | | Context Notes | A resource injection issue occurs when the following two conditions are met: 1. An
attacker can specify the identifier used to access a system resource. For example, an attacker
might be able to specify part of the name of a file to be opened or a port number to be used. 2.
By specifying the resource, the attacker gains a capability that would not otherwise be permitted.
For example, the program may give the attacker the ability to overwrite the specified file, run
with a configuration controlled by the attacker, or transmit sensitive information to a
third-party server. Note: Resource injection that involves resources stored on the filesystem goes
by the name path manipulation and is reported in separate category. See the path manipulation
description for further details of this vulnerability. | | Relationships | | | Source Taxonomies | 7 Pernicious Kingdoms - Resource Injection | | Applicable Platforms | All | | Related Attack Patterns | | CAPEC-ID | Attack Pattern Name |
|---|
| 10 | Buffer Overflow via Environment Variables | | 75 | Manipulating Writeable Configuration Files |
| | White Box Definition | A weakness where the code path has: 1. start statement that accepts input followed by 2. a statement that allocates a System Resource where the input is part of the name of the System Resource 3. end statement that accesses the System Resource where a. the System Resource is protected and b. the name of the System Resource violates protection
|
Weakness ID
| Status: Draft 489 (Weakness Base) | | Description | Summary The application can be deployed
with active debugging code
that can create unintended entry points. | | Common Consequences | The severity of the exposed debug application will depend on the particular
instance. At the least, it will give an attacker sensitive information about the settings and
mechanics of web applications on the server. At worst, as is often the case, the debug
application will allow an attacker complete control over the web application and server, as
well as confidential information that either of these access. | Demonstrative Examples | Debug code can be used to bypass authentication. For example, suppose an
application has a login script that receives a username and a password. Assume also
that a third, optional, parameter, called "debug", is interpreted by the script as
requesting a switch to debug mode, and that when this parameter is given the username
and password are not checked. In such a case, it is very simple to bypass the
authentication process if the special behavior of the application regarding the debug
parameter is known. In a case where the form is: <FORM ACTION="/authenticate_login.cgi"> <INPUT TYPE=TEXT name=username> <INPUT TYPE=PASSWORD name=password> <INPUT TYPE=SUBMIT> </FORM> Then a conforming link will look like: http://TARGET/authenticate_login.cgi?username=...&password=... An attacker can change this to: http://TARGET/authenticate_login.cgi?username=&password=&debug=1 Which will grant the attacker access to the site, bypassing the
authentication process. | | Context Notes | A common development practice is to |
|