Weaknesses in the 2010 CWE/SANS Top 25 Most Dangerous Programming Errors
Definition in a New Window
View ID: 800 (View: Graph)
Status: Incomplete
View Data
View Objective
CWE entries in this view (graph) are listed in the 2010 CWE/SANS Top 25 Programming Errors.
View Metrics
CWEs in this view
Total CWEs
Total
45
out of
920
Views
0
out of
29
Categories
4
out of
177
Weaknesses
39
out of
705
Compound_Elements
2
out of
9
View Audience
Stakeholder
Description
Developers
By following the Top 25, developers will be able to significantly
reduce the number of weaknesses that occur in their software.
Software_Customers
If a software developer claims to be following the Top 25, then
customers can use the weaknesses in this view in order to formulate
independent evidence of that claim.
Educators
Educators can use this view in multiple ways. For example, if there is
a focus on teaching weaknesses, the educator could focus on the Top
25.
Allocation of Resources Without Limits or Throttling
Definition in a New Window
Weakness ID: 770 (Weakness Base)
Status: Incomplete
Description
Description Summary
The software allocates a reusable resource or group of resources on behalf of an actor without imposing any restrictions on how many resources can be allocated, in violation of the intended security policy for that actor.
When allocating resources without limits, an attacker could prevent
other systems, applications, or processes from accessing the same type
of resource.
Likelihood of Exploit
Medium to High
Detection Methods
Manual Static Analysis
Manual static analysis can be useful for finding this weakness, but it
might not achieve desired code coverage within limited time constraints.
If denial-of-service is not considered a significant risk, or if there
is strong emphasis on consequences such as code execution, then manual
analysis may not focus on this weakness at all.
Fuzzing
While fuzzing is typically geared toward finding low-level
implementation bugs, it can inadvertently find uncontrolled resource
allocation problems. This can occur when the fuzzer generates a large
number of test cases but does not restart the targeted software in
between test cases. If an individual test case produces a crash, but it
does not do so reliably, then an inability to limit resource allocation
may be the cause.
When the allocation is directly affected by numeric inputs, then
fuzzing may produce indications of this weakness.
Effectiveness: Opportunistic
Automated Dynamic Analysis
Certain automated dynamic analysis techniques may be effective in
producing side effects of uncontrolled resource allocation problems,
especially with resources such as processes, memory, and connections.
The technique may involve generating a large number of requests to the
software within a short time frame. Manual analysis is likely required
to interpret the results.
Automated Static Analysis
Specialized configuration or tuning may be required to train automated
tools to recognize this weakness.
Automated static analysis typically has limited utility in recognizing
unlimited allocation problems, except for the missing release of
program-independent system resources such as files, sockets, and
processes, or unchecked arguments to memory. For system resources,
automated static analysis may be able to detect circumstances in which
resources are not released after they have expired, or if too much of a
resource is requested at once, as can occur with memory. Automated
analysis of configuration files may be able to detect settings that do
not specify a maximum value.
Automated static analysis tools will not be appropriate for detecting
exhaustion of custom resources, such as an intended security policy in
which a bulletin board user is only allowed to make a limited number of
posts per day.
Demonstrative Examples
Example 1
This code allocates a socket and forks each time it receives a new
connection.
(Bad Code)
Example Languages: C and C++
sock=socket(AF_INET, SOCK_STREAM, 0);
while (1) {
newsock=accept(sock, ...);
printf("A connection has been accepted\n");
pid = fork();
}
The program does not track how many connections have been made, and it
does not limit the number of connections. Because forking is a
relatively expensive operation, an attacker would be able to cause the
system to run out of CPU, processes, or memory by making a large number
of connections. Alternatively, an attacker could consume all available
connections, preventing others from accessing the system
remotely.
Example 2
In the following example a server socket connection is used to
accept a request to store data on the local file system using a specified
filename. The method openSocketConnection establishes a server socket to
accept requests from a client. When a client establishes a connection to
this service the getNextMessage method is first used to retrieve from the
socket the name of the file to store the data, the openFileToWrite method
will validate the filename and open a file to write to on the local file
system. The getNextMessage is then used within a while loop to continuously
read data from the socket and output the data to the file until there is no
longer any data from the socket.
(Bad Code)
Example Languages: C and C++
int writeDataFromSocketToFile(char *host, int port)
{
char filename[FILENAME_SIZE];
char buffer[BUFFER_SIZE];
int socket = openSocketConnection(host, port);
if (socket < 0) {
printf("Unable to open socket connection");
return(FAIL);
}
if (getNextMessage(socket, filename, FILENAME_SIZE) >
0) {
if (openFileToWrite(filename) > 0) {
while (getNextMessage(socket, buffer, BUFFER_SIZE)
> 0){
if (!(writeToFile(buffer) > 0))
break;
}
}
closeFile();
}
closeSocket(socket);
}
This example creates a situation where data can be dumped to a file on
the local file system without any limits on the size of the file. This
could potentially exhaust file or disk resources and/or limit other
clients' ability to access the service.
Example 3
In the following example, the processMessage method receives a two
dimensional character array containing the message to be processed. The
two-dimensional character array contains the length of the message in the
first character array and the message body in the second character array.
The getMessageLength method retrieves the integer value of the length from
the first character array. After validating that the message length is
greater than zero, the body character array pointer points to the start of
the second character array of the two-dimensional character array and memory
is allocated for the new body character array.
(Bad Code)
Example Languages: C and C++
/* process message accepts a two-dimensional character array of
the form [length][body] containing the message to be processed
*/
int processMessage(char **message)
{
char *body;
int length = getMessageLength(message[0]);
if (length > 0) {
body = &message[1][0];
processMessageBody(body);
return(SUCCESS);
}
else {
printf("Unable to process message; invalid message
length");
return(FAIL);
}
}
This example creates a situation where the length of the body
character array can be very large and will consume excessive memory,
exhausting system resources. This can be avoided by restricting the
length of the second character array with a maximum length check
Also, consider changing the type from 'int' to 'unsigned int', so that you are always guaranteed that the number is positive. This might not be possible if the protocol specifically requires allowing negative values, or if you cannot control the return value from getMessageLength(), but it could simplify the check to ensure the input is positive, and eliminate other errors such as signed-to-unsigned conversion errors (CWE-195) that may occur elsewhere in the code.
(Good Code)
Example Languages: C and C++
unsigned int length = getMessageLength(message[0]);
if ((length > 0) && (length <
MAX_LENGTH)) {...}
Example 4
In the following example, a server object creates a server socket
and accepts client connections to the socket. For every client connection to
the socket a separate thread object is generated using the
ClientSocketThread class that handles request made by the client through the
socket.
(Bad Code)
Example
Language: Java
public void acceptConnections() {
try {
ServerSocket serverSocket = new
ServerSocket(SERVER_PORT);
int counter = 0;
boolean hasConnections = true;
while (hasConnections) {
Socket client = serverSocket.accept();
Thread t = new Thread(new
ClientSocketThread(client));
In this example there is no limit to the number of client connections
and client threads that are created. Allowing an unlimited number of
client connections and threads could potentially overwhelm the system
and system resources.
The server should limit the number of client connections and the
client threads that are created. This can be easily done by creating a
thread pool object that limits the number of threads that are
generated.
(Good Code)
Example
Language: Java
public static final int SERVER_PORT = 4444;
public static final int MAX_CONNECTIONS = 10;
...
public void acceptConnections() {
try {
ServerSocket serverSocket = new
ServerSocket(SERVER_PORT);
int counter = 0;
boolean hasConnections = true;
while (hasConnections) {
hasConnections = checkForMoreConnections();
Socket client = serverSocket.accept();
Thread t = new Thread(new
ClientSocketThread(client));
ExecutorService pool =
Executors.newFixedThreadPool(MAX_CONNECTIONS);
pool.execute(t);
}
serverSocket.close();
} catch (IOException ex) {...}
}
Example 5
An unnamed web site allowed a user to purchase tickets for an event.
A menu option allowed the user to purchase up to 10 tickets, but the back
end did not restrict the actual number of tickets that could be
purchased.
CMS does not restrict the number of searches that
can occur simultaneously, leading to resource
exhaustion.
Potential Mitigations
Phase: Requirements
Clearly specify the minimum and maximum expectations for capabilities,
and dictate which behaviors are acceptable when resource allocation
reaches limits.
Phase: Architecture and Design
Limit the amount of resources that are accessible to unprivileged users. Set per-user limits for resources. Allow the system administrator to define these limits. Be careful to avoid CWE-410.
Phase: Architecture and Design
Design throttling mechanisms into the system architecture. The best
protection is to limit the amount of resources that an unauthorized user
can cause to be expended. A strong authentication and access control
model will help prevent such attacks from occurring in the first place,
and it will help the administrator to identify who is committing the
abuse. The login application should be protected against DoS attacks as
much as possible. Limiting the database access, perhaps by caching
result sets, can help minimize the resources expended. To further limit
the potential for a DoS attack, consider tracking the rate of requests
received from users and blocking requests that exceed a defined rate
threshold.
Phase: Implementation
Strategy: Input Validation
Assume all input is malicious. Use an "accept known good" input
validation strategy, i.e., use a whitelist of acceptable inputs that
strictly conform to specifications. Reject any input that does not
strictly conform to specifications, or transform it into something that
does.
When performing input validation, consider all potentially relevant
properties, including length, type of input, the full range of
acceptable values, missing or extra inputs, syntax, consistency across
related fields, and conformance to business rules. As an example of
business rule logic, "boat" may be syntactically valid because it only
contains alphanumeric characters, but it is not valid if the input is
only expected to contain colors such as "red" or "blue."
Do not rely exclusively on looking for malicious or malformed inputs
(i.e., do not rely on a blacklist). A blacklist is likely to miss at
least one undesirable input, especially if the code's environment
changes. This can give attackers enough room to bypass the intended
validation. However, blacklists can be useful for detecting potential
attacks or determining which inputs are so malformed that they should be
rejected outright.
This will only be applicable to cases where user input can influence
the size or frequency of resource allocations.
Phase: Architecture and Design
For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.
Phase: Architecture and Design
Mitigation of resource exhaustion attacks requires that the target
system either:
recognizes the attack and denies that user further access for a
given amount of time, typically by using increasing time
delays
uniformly throttles all requests in order to make it more
difficult to consume resources more quickly than they can again be
freed.
The first of these solutions is an issue in itself though, since it
may allow attackers to prevent the use of the system by a particular
valid user. If the attacker impersonates the valid user, he may be able
to prevent the user from accessing the server in question.
The second solution can be difficult to effectively institute -- and
even when properly done, it does not provide a full solution. It simply
requires more resources on the part of the attacker.
Phase: Architecture and Design
Ensure that protocols have specific limits of scale placed on
them.
Phases: Architecture and Design; Implementation
If the program must fail, ensure that it fails gracefully (fails
closed). There may be a temptation to simply let the program fail poorly
in cases such as low memory conditions, but an attacker may be able to
assert control before the software has fully exited. Alternately, an
uncontrolled failure could cause cascading problems with other
downstream components; for example, the program could send a signal to a
downstream process so the process immediately knows that a problem has
occurred and has a better chance of recovery.
Ensure that all failures in resource allocation place the system into
a safe posture.
Phases: Operation; Architecture and Design
Strategy: Limit Resource Consumption
Use resource-limiting settings provided by the operating system or
environment. For example, when managing system resources in POSIX,
setrlimit() can be used to set limits for certain types of resources,
and getrlimit() can determine how many resources are available. However,
these functions are not available on all operating systems.
When the current levels get close to the maximum that is defined for the application (see CWE-770), then limit the allocation of further resources to privileged users; alternately, begin releasing resources for less-privileged users. While this mitigation may protect the system from attack, it will not necessarily stop attackers from adversely impacting other users.
Ensure that the application performs the appropriate error checks and error handling in case resources become unavailable (CWE-703).
Vulnerability theory is largely about how behaviors and resources
interact. "Resource exhaustion" can be regarded as either a consequence or
an attack, depending on the perspective. This entry is an attempt to reflect
one of the underlying weaknesses that enable these attacks (or consequences)
to take place.
Taxonomy Mappings
Mapped Taxonomy Name
Node ID
Fit
Mapped Node Name
CERT Java Secure Coding
FIO04-J
Close resources when they are no longer
needed
CERT Java Secure Coding
SER12-J
Avoid memory and resource leaks during
serialization
CERT Java Secure Coding
MSC05-J
Do not exhaust heap space
CERT C++ Secure Coding
MEM12-CPP
Do not assume infinite heap space
CERT C++ Secure Coding
FIO42-CPP
Ensure files are properly closed when they are no longer
needed
Joao Antunes, Nuno Ferreira Neves
and Paulo Verissimo. "Detection and Prediction of Resource-Exhaustion
Vulnerabilities". Proceedings of the IEEE International Symposium on
Software Reliability Engineering (ISSRE). November 2008. <http://homepages.di.fc.ul.pt/~nuno/PAPERS/ISSRE08.pdf>.
[REF-11] M. Howard and
D. LeBlanc. "Writing Secure Code". Chapter 17, "Protecting Against Denial of Service Attacks"
Page 517. 2nd Edition. Microsoft. 2002.
[REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 10, "Resource Limits", Page 574.. 1st Edition. Addison Wesley. 2006.
Maintenance Notes
"Resource exhaustion" (CWE-400) is currently treated as a weakness, although it is more like a category of weaknesses that all have the same type of consequence. While this entry treats CWE-400 as a parent in view 1000, the relationship is probably more appropriately described as a chain.
The software uses a sequential operation to read or write a buffer, but it uses an incorrect length value that causes it to access memory that is outside of the bounds of the buffer.
Extended Description
When the length value exceeds the size of the destination, a buffer overflow could occur.
Time of Introduction
Implementation
Applicable Platforms
Languages
C: (Often)
C++: (Often)
Assembly
Common Consequences
Scope
Effect
Integrity
Confidentiality
Availability
Technical Impact: Execute unauthorized code or
commands
Buffer overflows often can be used to execute arbitrary code, which is
usually outside the scope of a program's implicit security policy. This
can often be used to subvert any other security service.
Buffer overflows generally lead to crashes. Other attacks leading to
lack of availability are possible, including putting the program into an
infinite loop.
Likelihood of Exploit
Medium to High
Detection Methods
Automated Static Analysis
This weakness can often be detected using automated static analysis
tools. Many modern tools use data flow analysis or constraint-based
techniques to minimize the number of false positives.
Automated static analysis generally does not account for environmental
considerations when reporting out-of-bounds memory operations. This can
make it difficult for users to determine which warnings should be
investigated first. For example, an analysis tool might report buffer
overflows that originate from command line arguments in a program that
is not expected to run with setuid or other special privileges.
Effectiveness: High
Detection techniques for buffer-related errors are more mature than
for most other weakness types.
Automated Dynamic Analysis
This weakness can be detected using dynamic tools and techniques that
interact with the software using large test suites with many diverse
inputs, such as fuzz testing (fuzzing), robustness testing, and fault
injection. The software's operation may slow down, but it should not
become unstable, crash, or generate incorrect results.
Effectiveness: Moderate
Without visibility into the code, black box methods may not be able to
sufficiently distinguish this weakness from others, requiring manual
methods to diagnose the underlying problem.
Manual Analysis
Manual analysis can be useful for finding this weakness, but it might
not achieve desired code coverage within limited time constraints. This
becomes difficult for weaknesses that must be considered for all inputs,
since the attack surface can be too large.
Demonstrative Examples
Example 1
This example takes an IP address from a user, verifies that it is
well formed and then looks up the hostname and copies it into a
buffer.
(Bad Code)
Example
Language: C
void host_lookup(char *user_supplied_addr){
struct hostent *hp;
in_addr_t *addr;
char hostname[64];
in_addr_t inet_addr(const char *cp);
/*routine that ensures user_supplied_addr is in the right
format for conversion */
validate_addr_form(user_supplied_addr);
addr = inet_addr(user_supplied_addr);
hp = gethostbyaddr( addr, sizeof(struct in_addr),
AF_INET);
strcpy(hostname, hp->h_name);
}
This function allocates a buffer of 64 bytes to store the hostname
under the assumption that the maximum length value of hostname is 64
bytes, however there is no guarantee that the hostname will not be
larger than 64 bytes. If an attacker specifies an address which resolves
to a very large hostname, then we may overwrite sensitive data or even
relinquish control flow to the attacker.
Note that this example also contains an unchecked return value (CWE-252) that can lead to a NULL pointer dereference (CWE-476).
Example 2
In the following example, the source character string is copied to
the dest character string using the method strncpy.
(Bad Code)
Example Languages: C and C++
...
char source[21] = "the character string";
char dest[12];
strncpy(dest, source, sizeof(source)-1);
...
However, in the call to strncpy the source character string is used
within the sizeof call to determine the number of characters to copy.
This will create a buffer overflow as the size of the source character
string is greater than the dest character string. The dest character
string should be used within the sizeof call to ensure that the correct
number of characters are copied, as shown below.
(Good Code)
Example Languages: C and C++
...
char source[21] = "the character string";
char dest[12];
strncpy(dest, source, sizeof(dest)-1);
...
Example 3
In this example, the method outputFilenameToLog outputs a filename
to a log file. The method arguments include a pointer to a character string
containing the file name and an integer for the number of characters in the
string. The filename is copied to a buffer where the buffer size is set to a
maximum size for inputs to the log file. The method then calls another
method to save the contents of the buffer to the log file.
(Bad Code)
Example Languages: C and C++
#define LOG_INPUT_SIZE 40
// saves the file name to a log file
int outputFilenameToLog(char *filename, int length) {
int success;
// buffer with size set to maximum size for input to log
file
char buf[LOG_INPUT_SIZE];
// copy filename to buffer
strncpy(buf, filename, length);
// save to log file
success = saveToLogFile(buf);
return success;
}
However, in this case the string copy method, strncpy, mistakenly uses
the length method argument to determine the number of characters to copy
rather than using the size of the local character string, buf. This can
lead to a buffer overflow if the number of characters contained in
character string pointed to by filename is larger then the number of
characters allowed for the local character string. The string copy
method should use the buf character string within a sizeof call to
ensure that only characters up to the size of the buf array are copied
to avoid a buffer overflow, as shown below.
Language interpreter API function doesn't validate
length argument, leading to information
exposure
Potential Mitigations
Phase: Requirements
Strategy: Language Selection
Use a language that does not allow this weakness to occur or provides
constructs that make this weakness easier to avoid.
For example, many languages that perform their own memory management,
such as Java and Perl, are not subject to buffer overflows. Other
languages, such as Ada and C#, typically provide overflow protection,
but the protection can be disabled by the programmer.
Be wary that a language's interface to native code may still be
subject to overflows, even if the language itself is theoretically safe.
Phase: Architecture and Design
Strategy: Libraries or Frameworks
Use a vetted library or framework that does not allow this weakness to
occur or provides constructs that make this weakness easier to
avoid.
Examples include the Safe C String Library (SafeStr) by Messier and Viega [R.805.6], and the Strsafe.h library from Microsoft [R.805.7]. These libraries provide safer versions of overflow-prone string-handling functions.
This is not a complete solution, since many buffer overflows are not
related to strings.
Phase: Build and Compilation
Strategy: Compilation or Build Hardening
Run or compile the software using features or extensions that
automatically provide a protection mechanism that mitigates or
eliminates buffer overflows.
For example, certain compilers and extensions provide automatic buffer
overflow detection mechanisms that are built into the compiled code.
Examples include the Microsoft Visual Studio /GS flag, Fedora/Red Hat
FORTIFY_SOURCE GCC flag, StackGuard, and ProPolice.
Effectiveness: Defense in Depth
This is not necessarily a complete solution, since these mechanisms
can only detect certain types of overflows. In addition, an attack could
still cause a denial of service, since the typical response is to exit
the application.
Phase: Implementation
Consider adhering to the following rules when allocating and managing
an application's memory:
Double check that your buffer is as large as you specify.
When using functions that accept a number of bytes to copy, such
as strncpy(), be aware that if the destination buffer size is equal
to the source buffer size, it may not NULL-terminate the
string.
Check buffer boundaries if accessing the buffer in a loop and make
sure you are not in danger of writing past the allocated
space.
If necessary, truncate all input strings to a reasonable length
before passing them to the copy and concatenation functions.
Phase: Architecture and Design
For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.
Phase: Operation
Strategy: Environment Hardening
Use a feature like Address Space Layout Randomization (ASLR) [R.805.2] [R.805.4].
Effectiveness: Defense in Depth
This is not a complete solution. However, it forces the attacker to
guess an unknown value that changes every program execution. In
addition, an attack could still cause a denial of service, since the
typical response is to exit the application.
Phase: Operation
Strategy: Environment Hardening
Use a CPU and operating system that offers Data Execution Protection (NX) or its equivalent [R.805.3] [R.805.6].
Effectiveness: Defense in Depth
This is not a complete solution, since buffer overflows could be used
to overwrite nearby variables to modify the software's state in
dangerous ways. In addition, it cannot be used in cases in which
self-modifying code is required. Finally, an attack could still cause a
denial of service, since the typical response is to exit the
application.
Phases: Architecture and Design; Operation
Strategy: Environment Hardening
Run your code using the lowest privileges that are required to accomplish the necessary tasks [R.805.9]. If possible, create isolated accounts with limited privileges that are only used for a single task. That way, a successful attack will not immediately give the attacker access to the rest of the software or its environment. For example, database applications rarely need to run as the database administrator, especially in day-to-day operations.
Phases: Architecture and Design; Operation
Strategy: Sandbox or Jail
Run the code in a "jail" or similar sandbox environment that enforces
strict boundaries between the process and the operating system. This may
effectively restrict which files can be accessed in a particular
directory or which commands can be executed by the software.
OS-level examples include the Unix chroot jail, AppArmor, and SELinux.
In general, managed code may provide some protection. For example,
java.io.FilePermission in the Java SecurityManager allows the software
to specify restrictions on file operations.
This may not be a feasible solution, and it only limits the impact to
the operating system; the rest of the application may still be subject
to compromise.
Be careful to avoid CWE-243 and other weaknesses related to jails.
Effectiveness: Limited
The effectiveness of this mitigation depends on the prevention
capabilities of the specific sandbox or jail being used and might only
help to reduce the scope of an attack, such as restricting the attacker
to certain system calls or limiting the portion of the file system that
can be accessed.
Weakness Ordinalities
Ordinality
Description
Resultant
(where
the weakness is typically related to the presence of some other
weaknesses)
Primary
(where
the weakness exists independent of other weaknesses)
Buffer Copy without Checking Size of Input ('Classic Buffer Overflow')
Definition in a New Window
Weakness ID: 120 (Weakness Base)
Status: Incomplete
Description
Description Summary
The program copies an input buffer to an output buffer without verifying that the size of the input buffer is less than the size of the output buffer, leading to a buffer overflow.
Extended Description
A buffer overflow condition exists when a program attempts to put more data in a buffer than it can hold, or when a program attempts to put data in a memory area outside of the boundaries of a buffer. The simplest type of error, and the most common cause of buffer overflows, is the "classic" case in which the program copies the buffer without restricting how much is copied. Other variants exist, but the existence of a classic overflow strongly suggests that the programmer is not considering even the most basic of security protections.
Alternate Terms
buffer overrun:
Some prominent vendors and researchers use the term "buffer overrun,"
but most people use "buffer overflow."
Unbounded Transfer
Terminology Notes
Many issues that are now called "buffer overflows" are substantively
different than the "classic" overflow, including entirely different bug
types that rely on overflow exploit techniques, such as integer signedness
errors, integer overflows, and format string bugs. This imprecise
terminology can make it difficult to determine which variant is being
reported.
Time of Introduction
Implementation
Applicable Platforms
Languages
C
C++
Assembly
Common Consequences
Scope
Effect
Integrity
Confidentiality
Availability
Technical Impact: Execute unauthorized code or
commands
Buffer overflows often can be used to execute arbitrary code, which is
usually outside the scope of a program's implicit security policy. This
can often be used to subvert any other security service.
Buffer overflows generally lead to crashes. Other attacks leading to
lack of availability are possible, including putting the program into an
infinite loop.
Likelihood of Exploit
High to Very High
Detection Methods
Automated Static Analysis
This weakness can often be detected using automated static analysis
tools. Many modern tools use data flow analysis or constraint-based
techniques to minimize the number of false positives.
Automated static analysis generally does not account for environmental
considerations when reporting out-of-bounds memory operations. This can
make it difficult for users to determine which warnings should be
investigated first. For example, an analysis tool might report buffer
overflows that originate from command line arguments in a program that
is not expected to run with setuid or other special privileges.
Effectiveness: High
Detection techniques for buffer-related errors are more mature than
for most other weakness types.
Automated Dynamic Analysis
This weakness can be detected using dynamic tools and techniques that
interact with the software using large test suites with many diverse
inputs, such as fuzz testing (fuzzing), robustness testing, and fault
injection. The software's operation may slow down, but it should not
become unstable, crash, or generate incorrect results.
Manual Analysis
Manual analysis can be useful for finding this weakness, but it might
not achieve desired code coverage within limited time constraints. This
becomes difficult for weaknesses that must be considered for all inputs,
since the attack surface can be too large.
Demonstrative Examples
Example 1
The following code asks the user to enter their last name and then
attempts to store the value entered in the last_name array.
(Bad Code)
Example
Language: C
char last_name[20];
printf ("Enter your last name: ");
scanf ("%s", last_name);
The problem with the code above is that it does not restrict or limit
the size of the name entered by the user. If the user enters
"Very_very_long_last_name" which is 24 characters long, then a buffer
overflow will occur since the array can only hold 20 characters total.
Example 2
The following code attempts to create a local copy of a buffer to
perform some manipulations to the data.
(Bad Code)
Example
Language: C
void manipulate_string(char* string){
char buf[24];
strcpy(buf, string);
...
}
However, the programmer does not ensure that the size of the data
pointed to by string will fit in the local buffer and blindly copies the
data with the potentially dangerous strcpy() function. This may result
in a buffer overflow condition if an attacker can influence the contents
of the string parameter.
Example 3
The excerpt below calls the gets() function in C, which is
inherently unsafe.
(Bad Code)
Example
Language: C
char buf[24];
printf("Please enter your name and press
<Enter>\n");
gets(buf);
...
}
However, the programmer uses the function gets() which is inherently
unsafe because it blindly copies all input from STDIN to the buffer
without restricting how much is copied. This allows the user to provide
a string that is larger than the buffer size, resulting in an overflow
condition.
Example 4
In the following example, a server accepts connections from a client
and processes the client request. After accepting a client connection, the
program will obtain client information using the gethostbyaddr method, copy
the hostname of the client that connected to a local variable and output the
hostname of the client to a log file.
(Bad Code)
Example Languages: C and C++
...
struct hostent *clienthp;
char hostname[MAX_LEN];
// create server socket, bind to server address and listen on
socket
...
// accept client connections and process requests
int count = 0;
for (count = 0; count < MAX_CONNECTIONS; count++)
{
int clientlen = sizeof(struct sockaddr_in);
int clientsocket = accept(serversocket, (struct sockaddr
*)&clientaddr, &clientlen);
logOutput("Accepted client connection from host ",
hostname);
// process client request
...
close(clientsocket);
}
}
close(serversocket);
...
However, the hostname of the client that connected may be longer than
the allocated size for the local hostname variable. This will result in
a buffer overflow when copying the client hostname to the local variable
using the strcpy method.
By replacing a valid cookie value with an
extremely long string of characters, an attacker may overflow the
application's buffers.
Potential Mitigations
Phase: Requirements
Strategy: Language Selection
Use a language that does not allow this weakness to occur or provides
constructs that make this weakness easier to avoid.
For example, many languages that perform their own memory management,
such as Java and Perl, are not subject to buffer overflows. Other
languages, such as Ada and C#, typically provide overflow protection,
but the protection can be disabled by the programmer.
Be wary that a language's interface to native code may still be
subject to overflows, even if the language itself is theoretically safe.
Phase: Architecture and Design
Strategy: Libraries or Frameworks
Use a vetted library or framework that does not allow this weakness to
occur or provides constructs that make this weakness easier to
avoid.
Examples include the Safe C String Library (SafeStr) by Messier and Viega [R.120.4], and the Strsafe.h library from Microsoft [R.120.3]. These libraries provide safer versions of overflow-prone string-handling functions.
This is not a complete solution, since many buffer overflows are not
related to strings.
Phase: Build and Compilation
Strategy: Compilation or Build Hardening
Run or compile the software using features or extensions that
automatically provide a protection mechanism that mitigates or
eliminates buffer overflows.
For example, certain compilers and extensions provide automatic buffer
overflow detection mechanisms that are built into the compiled code.
Examples include the Microsoft Visual Studio /GS flag, Fedora/Red Hat
FORTIFY_SOURCE GCC flag, StackGuard, and ProPolice.
Effectiveness: Defense in Depth
This is not necessarily a complete solution, since these mechanisms
can only detect certain types of overflows. In addition, an attack could
still cause a denial of service, since the typical response is to exit
the application.
Phase: Implementation
Consider adhering to the following rules when allocating and managing
an application's memory:
Double check that your buffer is as large as you specify.
When using functions that accept a number of bytes to copy, such
as strncpy(), be aware that if the destination buffer size is equal
to the source buffer size, it may not NULL-terminate the
string.
Check buffer boundaries if accessing the buffer in a loop and make
sure you are not in danger of writing past the allocated
space.
If necessary, truncate all input strings to a reasonable length
before passing them to the copy and concatenation functions.
Phase: Implementation
Strategy: Input Validation
Assume all input is malicious. Use an "accept known good" input
validation strategy, i.e., use a whitelist of acceptable inputs that
strictly conform to specifications. Reject any input that does not
strictly conform to specifications, or transform it into something that
does.
When performing input validation, consider all potentially relevant
properties, including length, type of input, the full range of
acceptable values, missing or extra inputs, syntax, consistency across
related fields, and conformance to business rules. As an example of
business rule logic, "boat" may be syntactically valid because it only
contains alphanumeric characters, but it is not valid if the input is
only expected to contain colors such as "red" or "blue."
Do not rely exclusively on looking for malicious or malformed inputs
(i.e., do not rely on a blacklist). A blacklist is likely to miss at
least one undesirable input, especially if the code's environment
changes. This can give attackers enough room to bypass the intended
validation. However, blacklists can be useful for detecting potential
attacks or determining which inputs are so malformed that they should be
rejected outright.
Phase: Architecture and Design
For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.
Phase: Operation
Strategy: Environment Hardening
Use a feature like Address Space Layout Randomization (ASLR) [R.120.5] [R.120.7].
Effectiveness: Defense in Depth
This is not a complete solution. However, it forces the attacker to
guess an unknown value that changes every program execution. In
addition, an attack could still cause a denial of service, since the
typical response is to exit the application.
Phase: Operation
Strategy: Environment Hardening
Use a CPU and operating system that offers Data Execution Protection (NX) or its equivalent [R.120.7] [R.120.9].
Effectiveness: Defense in Depth
This is not a complete solution, since buffer overflows could be used
to overwrite nearby variables to modify the software's state in
dangerous ways. In addition, it cannot be used in cases in which
self-modifying code is required. Finally, an attack could still cause a
denial of service, since the typical response is to exit the
application.
Phases: Build and Compilation; Operation
Most mitigating technologies at the compiler or OS level to date
address only a subset of buffer overflow problems and rarely provide
complete protection against even that subset. It is good practice to
implement strategies to increase the workload of an attacker, such as
leaving the attacker to guess an unknown value that changes every
program execution.
Phase: Implementation
Replace unbounded copy functions with analogous functions that support
length arguments, such as strcpy with strncpy. Create these if they are
not available.
Effectiveness: Moderate
This approach is still susceptible to calculation errors, including issues such as off-by-one errors (CWE-193) and incorrectly calculating buffer lengths (CWE-131).
Phase: Architecture and Design
Strategy: Enforcement by Conversion
When the set of acceptable objects, such as filenames or URLs, is
limited or known, create a mapping from a set of fixed input values
(such as numeric IDs) to the actual filenames or URLs, and reject all
other inputs.
Phases: Architecture and Design; Operation
Strategy: Environment Hardening
Run your code using the lowest privileges that are required to accomplish the necessary tasks [R.120.10]. If possible, create isolated accounts with limited privileges that are only used for a single task. That way, a successful attack will not immediately give the attacker access to the rest of the software or its environment. For example, database applications rarely need to run as the database administrator, especially in day-to-day operations.
Phases: Architecture and Design; Operation
Strategy: Sandbox or Jail
Run the code in a "jail" or similar sandbox environment that enforces
strict boundaries between the process and the operating system. This may
effectively restrict which files can be accessed in a particular
directory or which commands can be executed by the software.
OS-level examples include the Unix chroot jail, AppArmor, and SELinux.
In general, managed code may provide some protection. For example,
java.io.FilePermission in the Java SecurityManager allows the software
to specify restrictions on file operations.
This may not be a feasible solution, and it only limits the impact to
the operating system; the rest of the application may still be subject
to compromise.
Be careful to avoid CWE-243 and other weaknesses related to jails.
Effectiveness: Limited
The effectiveness of this mitigation depends on the prevention
capabilities of the specific sandbox or jail being used and might only
help to reduce the scope of an attack, such as restricting the attacker
to certain system calls or limiting the portion of the file system that
can be accessed.
Weakness Ordinalities
Ordinality
Description
Resultant
(where
the weakness is typically related to the presence of some other
weaknesses)
Primary
(where
the weakness exists independent of other weaknesses)
At the code level, stack-based and heap-based overflows do not differ
significantly, so there usually is not a need to distinguish them. From the
attacker perspective, they can be quite different, since different
techniques are required to exploit them.
Affected Resources
Memory
Functional Areas
Memory Management
Causal Nature
Explicit
Taxonomy Mappings
Mapped Taxonomy Name
Node ID
Fit
Mapped Node Name
PLOVER
Unbounded Transfer ('classic overflow')
7 Pernicious Kingdoms
Buffer Overflow
CLASP
Buffer overflow
OWASP Top Ten 2004
A1
CWE_More_Specific
Unvalidated Input
OWASP Top Ten 2004
A5
CWE_More_Specific
Buffer Overflows
CERT C Secure Coding
STR35-C
Do not copy data from an unbounded source to a fixed-length
array
WASC
7
Buffer Overflow
CERT C++ Secure Coding
STR35-CPP
Do not copy data from an unbounded source to a fixed-length
array
A weakness where the code path includes a Buffer Write Operation such
that:
1. the expected size of the buffer is greater than the actual size of
the buffer where expected size is equal to the sum of the size of the
data item and the position in the buffer
Where Buffer Write Operation is a statement that writes a data item of a
certain size into a buffer at a certain position and at a certain
index
References
[R.120.1] [REF-11] M. Howard and
D. LeBlanc. "Writing Secure Code". Chapter 5, "Public Enemy #1: The Buffer Overrun" Page
127. 2nd Edition. Microsoft. 2002.
[R.120.2] [REF-17] Michael Howard, David LeBlanc
and John Viega. "24 Deadly Sins of Software Security". "Sin 5: Buffer Overruns." Page 89. McGraw-Hill. 2010.
[R.120.11] [REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 3, "Nonexecutable Stack", Page
76.. 1st Edition. Addison Wesley. 2006.
[R.120.12] [REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 5, "Protection Mechanisms", Page
189.. 1st Edition. Addison Wesley. 2006.
[R.120.13] [REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 8, "C String Handling", Page 388.. 1st Edition. Addison Wesley. 2006.
Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')
Definition in a New Window
Weakness ID: 362 (Weakness Class)
Status: Draft
Description
Description Summary
The program contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently.
Extended Description
This can have security implications when the expected synchronization is in security-critical code, such as recording whether a user is authenticated or modifying important state information that should not be influenced by an outsider.
A race condition occurs within concurrent environments, and is effectively a property of a code sequence. Depending on the context, a code sequence may be in the form of a function call, a small number of instructions, a series of program invocations, etc.
A race condition violates these properties, which are closely related:
Exclusivity - the code sequence is given exclusive access to the shared resource, i.e., no other code sequence can modify properties of the shared resource before the original sequence has completed execution.
Atomicity - the code sequence is behaviorally atomic, i.e., no other thread or process can concurrently execute the same sequence of instructions (or a subset) against the same resource.
A race condition exists when an "interfering code sequence" can still access the shared resource, violating exclusivity. Programmers may assume that certain code sequences execute too quickly to be affected by an interfering code sequence; when they are not, this violates atomicity. For example, the single "x++" statement may appear atomic at the code layer, but it is actually non-atomic at the instruction layer, since it involves a read (the original value of x), followed by a computation (x+1), followed by a write (save the result to x).
The interfering code sequence could be "trusted" or "untrusted." A trusted interfering code sequence occurs within the program; it cannot be modified by the attacker, and it can only be invoked indirectly. An untrusted interfering code sequence can be authored directly by the attacker, and typically it is external to the vulnerable program.
Time of Introduction
Architecture and Design
Implementation
Applicable Platforms
Languages
C: (Sometimes)
C++: (Sometimes)
Java: (Sometimes)
Language-independent
Architectural Paradigms
Concurrent Systems Operating on Shared Resources: (Often)
When a race condition makes it possible to bypass a resource cleanup routine or trigger multiple initialization routines, it may lead to resource exhaustion (CWE-400).
When a race condition allows multiple control flows to access a
resource simultaneously, it might lead the program(s) into unexpected
states, possibly resulting in a crash.
Confidentiality
Integrity
Technical Impact: Read files or
directories; Read application
data
When a race condition is combined with predictable resource names and loose permissions, it may be possible for an attacker to overwrite or access confidential data (CWE-59).
Likelihood of Exploit
Medium
Detection Methods
Black Box
Black box methods may be able to identify evidence of race conditions
via methods such as multiple simultaneous connections, which may cause
the software to become instable or crash. However, race conditions with
very narrow timing windows would not be detectable.
White Box
Common idioms are detectable in white box analysis, such as time-of-check-time-of-use (TOCTOU) file operations (CWE-367), or double-checked locking (CWE-609).
Automated Dynamic Analysis
This weakness can be detected using dynamic tools and techniques that
interact with the software using large test suites with many diverse
inputs, such as fuzz testing (fuzzing), robustness testing, and fault
injection. The software's operation may slow down, but it should not
become unstable, crash, or generate incorrect results.
Race conditions may be detected with a stress-test by calling the
software simultaneously from a large number of threads or processes, and
look for evidence of any unexpected behavior.
Insert breakpoints or delays in between relevant code statements to
artificially expand the race window so that it will be easier to
detect.
Effectiveness: Moderate
Demonstrative Examples
Example 1
This code could be used in an e-commerce application that supports
transfers between accounts. It takes the total amount of the transfer, sends
it to the new account, and deducts the amount from the original
account.
(Bad Code)
Example
Language: Perl
$transfer_amount = GetTransferAmount();
$balance = GetBalanceFromDatabase();
if ($transfer_amount < 0) {
FatalError("Bad Transfer Amount");
}
$newbalance = $balance - $transfer_amount;
if (($balance - $transfer_amount) < 0) {
FatalError("Insufficient Funds");
}
SendNewBalanceToDatabase($newbalance);
NotifyUser("Transfer of $transfer_amount succeeded.");
NotifyUser("New balance: $newbalance");
A race condition could occur between the calls to
GetBalanceFromDatabase() and SendNewBalanceToDatabase().
Suppose the balance is initially 100.00. An attack could be
constructed as follows:
(Attack)
Example
Language: PseudoCode
The attacker makes two simultaneous calls of the program, CALLER-1
and CALLER-2. Both callers are for the same user account.
CALLER-1 (the attacker) is associated with PROGRAM-1 (the instance
that handles CALLER-1). CALLER-2 is associated with
PROGRAM-2.
CALLER-1 makes a transfer request of 80.00.
PROGRAM-1 calls GetBalanceFromDatabase and sets $balance to
100.00
PROGRAM-1 calculates $newbalance as 20.00, then calls
SendNewBalanceToDatabase().
Due to high server load, the PROGRAM-1 call to
SendNewBalanceToDatabase() encounters a delay.
CALLER-2 makes a transfer request of 1.00.
PROGRAM-2 calls GetBalanceFromDatabase() and sets $balance to
100.00. This happens because the previous PROGRAM-1 request was not
processed yet.
PROGRAM-2 determines the new balance as 99.00.
After the initial delay, PROGRAM-1 commits its balance to the
database, setting it to 20.00.
PROGRAM-2 sends a request to update the database, setting the
balance to 99.00
At this stage, the attacker should have a balance of 19.00 (due to
81.00 worth of transfers), but the balance is 99.00, as recorded in the
database.
To prevent this weakness, the programmer has several options,
including using a lock to prevent multiple simultaneous requests to the
web application, or using a synchronization mechanism that includes all
the code between GetBalanceFromDatabase() and
SendNewBalanceToDatabase().
Example 2
The following function attempts to acquire a lock in order to
perform operations on a shared resource.
(Bad Code)
Example
Language: C
void f(pthread_mutex_t *mutex) {
pthread_mutex_lock(mutex);
/* access shared resource */
pthread_mutex_unlock(mutex);
}
However, the code does not check the value returned by
pthread_mutex_lock() for errors. If pthread_mutex_lock() cannot acquire
the mutex for any reason, the function may introduce a race condition
into the program and result in undefined behavior.
In order to avoid data races, correctly written programs must check
the result of thread synchronization functions and appropriately handle
all errors, either by attempting to recover from them or reporting it to
higher levels.
chain: time-of-check time-of-use (TOCTOU) race
condition in program allows bypass of protection mechanism that was designed
to prevent symlink attacks.
chain: time-of-check time-of-use (TOCTOU) race
condition in program allows bypass of protection mechanism that was designed
to prevent symlink attacks.
chain: race condition might allow resource to be
released before operating on it, leading to NULL dereference
Potential Mitigations
Phase: Architecture and Design
In languages that support it, use synchronization primitives. Only
wrap these around critical code to minimize the impact on
performance.
Phase: Architecture and Design
Use thread-safe capabilities such as the data access abstraction in
Spring.
Phase: Architecture and Design
Minimize the usage of shared resources in order to remove as much
complexity as possible from the control flow and to reduce the
likelihood of unexpected conditions occurring.
Additionally, this will minimize the amount of synchronization necessary and may even help to reduce the likelihood of a denial of service where an attacker may be able to repeatedly trigger a critical section (CWE-400).
Phase: Implementation
When using multithreading and operating on shared variables, only use
thread-safe functions.
Phase: Implementation
Use atomic operations on shared variables. Be wary of innocent-looking
constructs such as "x++". This may appear atomic at the code layer, but
it is actually non-atomic at the instruction layer, since it involves a
read, followed by a computation, followed by a write.
Phase: Implementation
Use a mutex if available, but be sure to avoid related weaknesses such as CWE-412.
Phase: Implementation
Avoid double-checked locking (CWE-609) and other implementation errors that arise when trying to avoid the overhead of synchronization.
Phase: Implementation
Disable interrupts or signals over critical parts of the code, but
also make sure that the code does not go into a large or infinite
loop.
Phase: Implementation
Use the volatile type modifier for critical variables to avoid
unexpected compiler optimization or reordering. This does not
necessarily solve the synchronization problem, but it can help.
Phases: Architecture and Design; Operation
Strategy: Environment Hardening
Run your code using the lowest privileges that are required to accomplish the necessary tasks [R.362.11]. If possible, create isolated accounts with limited privileges that are only used for a single task. That way, a successful attack will not immediately give the attacker access to the rest of the software or its environment. For example, database applications rarely need to run as the database administrator, especially in day-to-day operations.
Race conditions in web applications are under-studied and probably
under-reported. However, in 2008 there has been growing interest in this
area.
Much of the focus of race condition research has been in Time-of-check Time-of-use (TOCTOU) variants (CWE-367), but many race conditions are related to synchronization problems that do not necessarily require a time-of-check.
Taxonomy Mappings
Mapped Taxonomy Name
Node ID
Fit
Mapped Node Name
PLOVER
Race Conditions
CERT C Secure Coding
FIO31-C
Do not simultaneously open the same file multiple
times
CERT Java Secure Coding
VNA03-J
Do not assume that a group of calls to independently atomic
methods is atomic
CERT C++ Secure Coding
FIO31-CPP
Do not simultaneously open the same file multiple
times
Leveraging Time-of-Check and Time-of-Use (TOCTOU) Race Conditions
References
[R.362.1] [REF-17] Michael Howard, David LeBlanc
and John Viega. "24 Deadly Sins of Software Security". "Sin 13: Race Conditions." Page 205. McGraw-Hill. 2010.
[R.362.2] Andrei Alexandrescu. "volatile - Multithreaded Programmer's Best
Friend". Dr. Dobb's. 2008-02-01. <http://www.ddj.com/cpp/184403766>.
The relationship between race conditions and synchronization problems (CWE-662) needs to be further developed. They are not necessarily two perspectives of the same core concept, since synchronization is only one technique for avoiding race conditions, and synchronization can be used for other purposes besides race condition prevention.
Compound Element ID: 352 (Compound Element Variant: Composite)
Status: Draft
Description
Description Summary
The web application does not, or can not, sufficiently verify whether a well-formed, valid, consistent request was intentionally provided by the user who submitted the request.
Extended Description
When a web server is designed to receive a request from a client without any mechanism for verifying that it was intentionally sent, then it might be possible for an attacker to trick a client into making an unintentional request to the web server which will be treated as an authentic request. This can be done via a URL, image load, XMLHttpRequest, etc. and can result in exposure of data or unintended code execution.
The consequences will vary depending on the nature of the
functionality that is vulnerable to CSRF. An attacker could effectively
perform any operations as the victim. If the victim is an administrator
or privileged user, the consequences may include obtaining complete
control over the web application - deleting or stealing data,
uninstalling the product, or using it to launch other attacks against
all of the product's users. Because the attacker has the identity of the
victim, the scope of CSRF is limited only by the victim's privileges.
Likelihood of Exploit
Medium to High
Detection Methods
Manual Analysis
This weakness can be detected using tools and techniques that require
manual (human) analysis, such as penetration testing, threat modeling,
and interactive tools that allow the tester to record and modify an
active session.
Specifically, manual analysis can be useful for finding this weakness,
and for minimizing false positives assuming an understanding of business
logic. However, it might not achieve desired code coverage within
limited time constraints. For black-box analysis, if credentials are not
known for privileged accounts, then the most security-critical portions
of the application may not receive sufficient attention.
Consider using OWASP CSRFTester to identify potential issues and aid
in manual analysis.
Effectiveness: High
These may be more effective than strictly automated techniques. This
is especially the case with weaknesses that are related to design and
business rules.
Automated Static Analysis
CSRF is currently difficult to detect reliably using automated
techniques. This is because each application has its own implicit
security policy that dictates which requests can be influenced by an
outsider and automatically performed on behalf of a user, versus which
requests require strong confidence that the user intends to make the
request. For example, a keyword search of the public portion of a web
site is typically expected to be encoded within a link that can be
launched automatically when the user clicks on the link.
Effectiveness: Limited
Demonstrative Examples
Example 1
This example PHP code attempts to secure the form submission process
by validating that the user submitting the form has a valid session. A CSRF
attack would not be prevented by this countermeasure because the attacker
forges a request through the user's web browser in which a valid session
already exists.
The following HTML is intended to allow a user to update a
profile.
echo "Your profile has been successfully updated.";
}
This code may look protected since it checks for a valid session.
However, CSRF attacks can be staged from virtually any tag or HTML
construct, including image tags, links, embed or object tags, or other
attributes that load background images.
The attacker can then host code that will silently change the username
and email address of any user that visits the page while remaining
logged in to the target web application. The code might be an
innocent-looking web page such as:
Notice how the form contains hidden fields, so when it is loaded into
the browser, the user will not notice it. Because SendAttack() is
defined in the body's onload attribute, it will be automatically called
when the victim loads the web page.
Assuming that the user is already logged in to victim.example.com,
profile.php will see that a valid user session has been established,
then update the email address to the attacker's own address. At this
stage, the user's identity has been compromised, and messages sent
through this profile could be sent to the attacker's address.
web interface allows password changes or stopping
a virtual machine via CSRF
Potential Mitigations
Phase: Architecture and Design
Strategy: Libraries or Frameworks
Use a vetted library or framework that does not allow this weakness to
occur or provides constructs that make this weakness easier to
avoid.
For example, use anti-CSRF packages such as the OWASP CSRFGuard. [R.352.3]
Another example is the ESAPI Session Management control, which includes a component for CSRF. [R.352.9]
Phase: Implementation
Ensure that the application is free of cross-site scripting issues (CWE-79), because most CSRF defenses can be bypassed using attacker-controlled script.
Phase: Architecture and Design
Generate a unique nonce for each form, place the nonce into the form, and verify the nonce upon receipt of the form. Be sure that the nonce is not predictable (CWE-330). [R.352.5]
Note that this can be bypassed using XSS (CWE-79).
Phase: Architecture and Design
Identify especially dangerous operations. When the user performs a
dangerous operation, send a separate confirmation request to ensure that
the user intended to perform that operation.
Note that this can be bypassed using XSS (CWE-79).
Phase: Architecture and Design
Use the "double-submitted cookie" method as described by Felten and
Zeller:
When a user visits a site, the site should generate a pseudorandom
value and set it as a cookie on the user's machine. The site should
require every form submission to include this value as a form value and
also as a cookie value. When a POST request is sent to the site, the
request should only be considered valid if the form value and the cookie
value are the same.
Because of the same-origin policy, an attacker cannot read or modify
the value stored in the cookie. To successfully submit a form on behalf
of the user, the attacker would have to correctly guess the pseudorandom
value. If the pseudorandom value is cryptographically strong, this will
be prohibitively difficult.
This technique requires Javascript, so it may not work for browsers that have Javascript disabled. [R.352.4]
Note that this can probably be bypassed using XSS (CWE-79), or when using web technologies that enable the attacker to read raw headers from HTTP requests.
Phase: Architecture and Design
Do not use the GET method for any request that triggers a state
change.
Phase: Implementation
Check the HTTP Referer header to see if the request originated from an
expected page. This could break legitimate functionality, because users
or proxies may have disabled sending the Referer for privacy
reasons.
Note that this can be bypassed using XSS (CWE-79). An attacker could use XSS to generate a spoofed Referer, or to generate a malicious request from a page whose Referer would be allowed.
[R.352.1] [REF-17] Michael Howard, David LeBlanc
and John Viega. "24 Deadly Sins of Software Security". "Sin 2: Web-Server Related Vulnerabilities (XSS, XSRF, and
Response Splitting)." Page 37. McGraw-Hill. 2010.
The product downloads source code or an executable from a remote location and executes the code without sufficiently verifying the origin and integrity of the code.
Extended Description
An attacker can execute malicious code by compromising the host server, performing DNS spoofing, or modifying the code in transit.
Time of Introduction
Architecture and Design
Implementation
Applicable Platforms
Languages
Language-independent
Common Consequences
Scope
Effect
Integrity
Availability
Confidentiality
Other
Technical Impact: Execute unauthorized code or
commands; Alter execution
logic; Other
Executing untrusted code could compromise the control flow of the
program. The untrusted code could execute attacker-controlled commands,
read or modify sensitive resources, or prevent the software from
functioning correctly for legitimate users.
Likelihood of Exploit
Medium
Detection Methods
Manual Analysis
This weakness can be detected using tools and techniques that require
manual (human) analysis, such as penetration testing, threat modeling,
and interactive tools that allow the tester to record and modify an
active session.
Specifically, manual static analysis is typically required to find the
behavior that triggers the download of code, and to determine whether
integrity-checking methods are in use.
These may be more effective than strictly automated techniques. This
is especially the case with weaknesses that are related to design and
business rules.
Black Box
Use monitoring tools that examine the software's process as it
interacts with the operating system and the network. This technique is
useful in cases when source code is unavailable, if the software was not
developed by you, or if you want to verify that the build phase did not
introduce any new weaknesses. Examples include debuggers that directly
attach to the running process; system-call tracing utilities such as
truss (Solaris) and strace (Linux); system activity monitors such as
FileMon, RegMon, Process Monitor, and other Sysinternals utilities
(Windows); and sniffers and protocol analyzers that monitor network
traffic.
Attach the monitor to the process and also sniff the network
connection. Trigger features related to product updates or plugin
installation, which is likely to force a code download. Monitor when
files are downloaded and separately executed, or if they are otherwise
read back into the process. Look for evidence of cryptographic library
calls that use integrity checking.
Demonstrative Examples
Example 1
This example loads an external class from a local
subdirectory.
(Bad Code)
Example
Language: Java
URL[] classURLs= new URL[]{
new URL("file:subdir/")
};
URLClassLoader loader = new URLClassLoader(classURLs);
Class loadedClass = Class.forName("loadMe", true, loader);
This code does not ensure that the class loaded is the intended one,
for example by verifying the class's checksum. An attacker may be able
to modify the class file to execute malicious code.
Example 2
This code includes an external script to get database credentials,
then authenticates a user against the database, allowing access to the
application.
(Bad Code)
Example
Language: PHP
//assume the password is already encrypted, avoiding
CWE-312
//dbInfo.php makes $dbhost, $dbuser, $dbpass, $dbname
available
mysql_connect($dbhost, $dbuser, $dbpass) or die ('Error
connecting to mysql');
mysql_select_db($dbname);
$query = 'Select * from users where username='.$username.'
And password='.$password;
$result = mysql_query($query);
if(mysql_numrows($result) == 1){
mysql_close();
return true;
}
else{
mysql_close();
return false;
}
}
This code does not verify that the external domain accessed is the
intended one. An attacker may somehow cause the external domain name to
resolve to an attack server, which would provide the information for a
false database. The attacker may then steal the usernames and encrypted
passwords from real user login attempts, or simply allow himself to
access the application without a real user account.
This example is also vulnerable to a Man in the Middle (CWE-300) attack.
VOIP phone downloads applications from web sites
without verifying integrity.
Potential Mitigations
Phase: Implementation
Perform proper forward and reverse DNS lookups to detect DNS spoofing.
This is only a partial solution since it will not prevent your code
from being modified on the hosting site or in transit.
Phases: Architecture and Design; Operation
Encrypt the code with a reliable encryption scheme before
transmitting.
This will only be a partial solution, since it will not detect DNS
spoofing and it will not prevent your code from being modified on the
hosting site.
Phase: Architecture and Design
Strategy: Libraries or Frameworks
Use a vetted library or framework that does not allow this weakness to
occur or provides constructs that make this weakness easier to
avoid.
Speficially, it may be helpful to use tools or frameworks to perform
integrity checking on the transmitted code.
When providing the code that is to be downloaded, such as for automatic updates of the software, then use cryptographic signatures for the code and modify the download clients to verify the signatures. Ensure that the implementation does not contain CWE-295, CWE-320, CWE-347, and related weaknesses.
Use code signing technologies such as Authenticode. See references [R.494.1] [R.494.2] [R.494.3].
Phases: Architecture and Design; Operation
Strategy: Environment Hardening
Run your code using the lowest privileges that are required to accomplish the necessary tasks [R.494.7]. If possible, create isolated accounts with limited privileges that are only used for a single task. That way, a successful attack will not immediately give the attacker access to the rest of the software or its environment. For example, database applications rarely need to run as the database administrator, especially in day-to-day operations.
Phases: Architecture and Design; Operation
Strategy: Sandbox or Jail
Run the code in a "jail" or similar sandbox environment that enforces
strict boundaries between the process and the operating system. This may
effectively restrict which files can be accessed in a particular
directory or which commands can be executed by the software.
OS-level examples include the Unix chroot jail, AppArmor, and SELinux.
In general, managed code may provide some protection. For example,
java.io.FilePermission in the Java SecurityManager allows the software
to specify restrictions on file operations.
This may not be a feasible solution, and it only limits the impact to
the operating system; the rest of the application may still be subject
to compromise.
Be careful to avoid CWE-243 and other weaknesses related to jails.
Effectiveness: Limited
The effectiveness of this mitigation depends on the prevention
capabilities of the specific sandbox or jail being used and might only
help to reduce the scope of an attack, such as restricting the attacker
to certain system calls or limiting the portion of the file system that
can be accessed.
This is critical for mobile code, but it is likely to become more and more
common as developers continue to adopt automated, network-based product
distributions and upgrades. Software-as-a-Service (SaaS) might introduce
additional subtleties. Common exploitation scenarios may include ad server
compromises and bad upgrades.
Taxonomy Mappings
Mapped Taxonomy Name
Node ID
Fit
Mapped Node Name
CLASP
Invoking untrusted mobile code
CERT Java Secure Coding
SEC06-J
Do not rely on the default automatic signature verification
provided by URLClassLoader and java.util.jar
[R.494.5] [REF-17] Michael Howard, David LeBlanc
and John Viega. "24 Deadly Sins of Software Security". "Sin 18: The Sins of Mobile Code." Page
267. McGraw-Hill. 2010.
The software provides an Applications Programming Interface (API) or similar interface for interaction with external actors, but the interface includes a dangerous method or function that is not properly restricted.
Extended Description
This weakness can lead to a wide variety of resultant weaknesses, depending on the behavior of the exposed method. It can apply to any number of technologies and approaches, such as ActiveX controls, Java functions, IOCTLs, and so on.
The exposure can occur in a few different ways:
1) The function/method was never intended to be exposed to outside actors.
2) The function/method was only intended to be accessible to a limited set of actors, such as Internet-based access from a single web site.
Time of Introduction
Architecture and Design
Implementation
Applicable Platforms
Languages
Language-Independent
Common Consequences
Scope
Effect
Integrity
Confidentiality
Availability
Access Control
Other
Technical Impact: Gain privileges / assume
identity; Read application
data; Modify application
data; Execute unauthorized code or
commands; Other
Exposing critical functionality essentially provides an attacker with
the privilege level of the exposed functionality. This could result in
the modification or exposure of sensitive data or possibly even
execution of arbitrary code.
Likelihood of Exploit
Low to Medium
Demonstrative Examples
Example 1
In the following Java example the method removeDatabase will delete
the database with the name specified in the input parameter.
(Bad Code)
Example
Language: Java
public void removeDatabase(String databaseName) {
try {
Statement stmt = conn.createStatement();
stmt.execute("DROP DATABASE " + databaseName);
} catch (SQLException ex) {...}
}
The method in this example is declared public and therefore is exposed
to any class in the application. Deleting a database should be
considered a critical operation within an application and access to this
potentially dangerous method should be restricted. Within Java this can
be accomplished simply by declaring the method private thereby exposing
it only to the enclosing class as in the following example.
security tool ActiveX control allows download or
upload of files
Potential Mitigations
Phase: Architecture and Design
If you must expose a method, make sure to perform input validation on
all arguments, limit access to authorized parties, and protect against
all possible vulnerabilities.
Phases: Architecture and Design; Implementation
Strategy: Identify and Reduce Attack Surface
Identify all exposed functionality. Explicitly list all functionality
that must be exposed to some user or set of users. Identify which
functionality may be:
accessible to all users
restricted to a small set of privileged users
prevented from being directly accessible at all
Ensure that the implemented code follows these expectations. This
includes setting the appropriate access modifiers where applicable
(public, private, protected, etc.) or not marking ActiveX controls
safe-for-scripting.
Weakness Ordinalities
Ordinality
Description
Primary
(where
the weakness exists independent of other weaknesses)
Under-reported and under-studied. This weakness could appear in any
technology, language, or framework that allows the programmer to provide a
functional interface to external parties, but it is not heavily reported. In
2007, CVE began showing a notable increase in reports of exposed method
vulnerabilities in ActiveX applications, as well as IOCTL access to OS-level
resources. These weaknesses have been documented for Java applications in
various secure programming sources, but there are few reports in CVE, which
suggests limited awareness in most parts of the vulnerability research
community.
External Initialization of Trusted Variables or Data Stores
Definition in a New Window
Weakness ID: 454 (Weakness Base)
Status: Draft
Description
Description Summary
The software initializes critical internal variables or data stores using inputs that can be modified by untrusted actors.
Extended Description
A software system should be reluctant to trust variables that have been initialized outside of its trust boundary, especially if they are initialized by users. They may have been initialized incorrectly. If an attacker can initialize the variable, then he/she can influence what the vulnerable system will do.
Time of Introduction
Architecture and Design
Implementation
Applicable Platforms
Languages
PHP: (Sometimes)
Language-independent
Platform Notes
This is often found in PHP due to register_globals and the common practice
of storing library/include files under the web document root so that they
are available using a direct request.
Common Consequences
Scope
Effect
Integrity
Technical Impact: Modify application
data
An attacker could gain access to and modify sensitive data or system
information.
Demonstrative Examples
Example 1
In the Java example below, a system property controls the debug
level of the application.
(Bad Code)
Example
Language: Java
int debugLevel =
Integer.getInteger("com.domain.application.debugLevel").intValue();
If an attacker is able to modify the system property, then it may be
possible to coax the application into divulging sensitive information by
virtue of the fact that additional debug information is printed/exposed
as the debug level increases.
Example 2
This code checks the HTTP POST request for a debug switch, and
enables a debug mode if the switch is set.
(Bad Code)
Example
Language: PHP
$debugEnabled = false;
if ($_POST["debug"] == "true"){
$debugEnabled = true;
}
/.../
function login($username, $password){
if($debugEnabled){
echo 'Debug Activated';
phpinfo();
$isAdmin = True;
return True;
}
}
Any user can activate the debug mode, gaining administrator
privileges. An attacker may also use the information printed by the
phpinfo() function to further exploit the system. .
This example also exhibits Information Exposure Through Debug Information (CWE-215)
Specify arbitrary modules using environment
variable.
Potential Mitigations
Phase: Implementation
Strategy: Input Validation
A software system should be reluctant to trust variables that have
been initialized outside of its trust boundary. Ensure adequate checking
(e.g. input validation) is performed when relying on input from outside
a trust boundary.
Phase: Architecture and Design
Avoid any external control of variables. If necessary, restrict the
variables that can be modified using a whitelist, and use a different
namespace or naming convention if possible.
The software uses a CAPTCHA challenge, but the challenge can be guessed or automatically recognized by a non-human actor.
Extended Description
An automated attacker could bypass the intended protection of the CAPTCHA challenge and perform actions at a higher frequency than humanly possible, such as launching spam attacks.
There can be several different causes of a guessable CAPTCHA:
An audio or visual image that does not have sufficient distortion from the unobfuscated source image.
A question is generated that with a format that can be automatically recognized, such as a math question.
A question for which the number of possible answers is limited, such as birth years or favorite sports teams.
A general-knowledge or trivia question for which the answer can be accessed using a data base, such as country capitals or popular actors.
Other data associated with the CAPTCHA may provide hints about its contents, such as an image whose filename contains the word that is used in the CAPTCHA.
Time of Introduction
Architecture and Design
Implementation
Applicable Platforms
Languages
Language-independent
Technology Classes
Web-Server: (Sometimes)
Common Consequences
Scope
Effect
Access Control
Other
Technical Impact: Bypass protection
mechanism; Other
When authorization, authentication, or another protection mechanism
relies on CAPTCHA entities to ensure that only human actors can access
certain functionality, then an automated attacker such as a bot may
access the restricted functionality by guessing the CAPTCHA.
Likelihood of Exploit
Medium to High
Weakness Ordinalities
Ordinality
Description
Primary
(where
the weakness exists independent of other weaknesses)
The software does not perform or incorrectly performs an authorizationcheck when an actor attempts to access a resource or perform an action.
Extended Description
Assuming a user with a given identity, authorization is the process of determining whether that user can access a given resource, based on the user's privileges and any permissions or other access-control specifications that apply to the resource.
When access control checks are not applied consistently - or not at all - users are able to access data or perform actions that they should not be allowed to perform. This can lead to a wide range of problems, including information exposures, denial of service, and arbitrary code execution.
Alternate Terms
AuthZ:
"AuthZ" is typically used as an abbreviation of "authorization" within
the web application security community. It is also distinct from
"AuthC," which is an abbreviation of "authentication." The use of "Auth"
as an abbreviation is discouraged, since it could be used for either
authentication or authorization.
Time of Introduction
Architecture and Design
Implementation
Operation
Applicable Platforms
Languages
Language-independent
Technology Classes
Web-Server: (Often)
Database-Server: (Often)
Modes of Introduction
A developer may introduce authorization weaknesses because of a lack of
understanding about the underlying technologies. For example, a developer
may assume that attackers cannot modify certain inputs such as headers or
cookies.
Authorization weaknesses may arise when a single-user application is
ported to a multi-user environment.
Common Consequences
Scope
Effect
Confidentiality
Technical Impact: Read application
data; Read files or
directories
An attacker could read sensitive data, either by reading the data
directly from a data store that is not properly restricted, or by
accessing insufficiently-protected, privileged functionality to read the
data.
Integrity
Technical Impact: Modify application
data; Modify files or
directories
An attacker could modify sensitive data, either by writing the data
directly to a data store that is not properly restricted, or by
accessing insufficiently-protected, privileged functionality to write
the data.
Access Control
Technical Impact: Gain privileges / assume
identity
An attacker could gain privileges by modifying or reading critical
data directly, or by accessing insufficiently-protected, privileged
functionality.
Likelihood of Exploit
High
Detection Methods
Automated Static Analysis
Automated static analysis is useful for detecting commonly-used idioms
for authorization. A tool may be able to analyze related configuration
files, such as .htaccess in Apache web servers, or detect the usage of
commonly-used authorization libraries.
Generally, automated static analysis tools have difficulty detecting
custom authorization schemes. In addition, the software's design may
include some functionality that is accessible to any user and does not
require an authorization check; an automated technique that detects the
absence of authorization may report false positives.
Effectiveness: Limited
Automated Dynamic Analysis
Automated dynamic analysis may find many or all possible interfaces
that do not require authorization, but manual analysis is required to
determine if the lack of authorization violates business logic
Manual Analysis
This weakness can be detected using tools and techniques that require
manual (human) analysis, such as penetration testing, threat modeling,
and interactive tools that allow the tester to record and modify an
active session.
Specifically, manual static analysis is useful for evaluating the
correctness of custom authorization mechanisms.
Effectiveness: Moderate
These may be more effective than strictly automated techniques. This
is especially the case with weaknesses that are related to design and
business rules. However, manual efforts might not achieve desired code
coverage within limited time constraints.
Demonstrative Examples
Example 1
This function runs an arbitrary SQL query on a given database,
returning the result of the query.
(Bad Code)
Example
Language: PHP
function runEmployeeQuery($dbName, $name){
mysql_select_db($dbName,$globalDbHandle) or die("Could not
open Database".$dbName);
//Use a prepared statement to avoid CWE-89
$preparedStatement = $globalDbHandle->prepare('SELECT
* FROM employees WHERE name = :name');
While this code is careful to avoid SQL Injection, the function does
not confirm the user sending the query is authorized to do so. An
attacker may be able to obtain sensitive employee information from the
database.
Example 2
The following program could be part of a bulletin board system that
allows users to send private messages to each other. This program intends to
authenticate the user before deciding whether a private message should be
displayed. Assume that LookupMessageObject() ensures that the $id argument
is numeric, constructs a filename based on that id, and reads the message
details from that file. Also assume that the program stores all private
messages for all users in the same directory.
# For purposes of this example, assume that CWE-309
and
# CWE-523 do not apply.
if (! AuthenticateUser($q->param('username'),
$q->param('password'))) {
ExitError("invalid username or password");
}
my $id = $q->param('id');
DisplayPrivateMessage($id);
While the program properly exits if authentication fails, it does not
ensure that the message is addressed to the user. As a result, an
authenticated attacker could provide any arbitrary identifier and read
private messages that were intended for other users.
One way to avoid this problem would be to ensure that the "to" field
in the message object matches the username of the authenticated user.
Chain: SNMP product does not properly parse a
configuration option for which hosts are allowed to connect, allowing
unauthorized IP addresses to connect.
Chain: product does not properly check the result of a reverse DNS lookup because of operator precedence (CWE-783), allowing bypass of DNS-based access restrictions.
Potential Mitigations
Phase: Architecture and Design
Divide the software into anonymous, normal, privileged, and
administrative areas. Reduce the attack surface by carefully mapping
roles with data and functionality. Use role-based access control (RBAC)
to enforce the roles at the appropriate boundaries.
Note that this approach may not protect against horizontal
authorization, i.e., it will not protect a user from attacking others
with the same role.
Phase: Architecture and Design
Ensure that you perform access control checks related to your business
logic. These checks may be different than the access control checks that
you apply to more generic resources such as files, connections,
processes, memory, and database records. For example, a database may
restrict access for medical records to a specific database user, but
each record might only be intended to be accessible to the patient and
the patient's doctor.
Phase: Architecture and Design
Strategy: Libraries or Frameworks
Use a vetted library or framework that does not allow this weakness to
occur or provides constructs that make this weakness easier to
avoid.
For example, consider using authorization frameworks such as the JAAS Authorization Framework [R.285.5] and the OWASP ESAPI Access Control feature [R.285.4].
Phase: Architecture and Design
For web applications, make sure that the access control mechanism is
enforced correctly at the server side on every page. Users should not be
able to access any unauthorized functionality or information by simply
requesting direct access to that page.
One way to do this is to ensure that all pages containing sensitive
information are not cached, and that all such pages restrict access to
requests that are accompanied by an active and authenticated session
token associated with a user who has the required permissions to access
that page.
Phases: System Configuration; Installation
Use the access control capabilities of your operating system and
server environment and define your access control lists accordingly. Use
a "default deny" policy when defining these ACLs.
Background Details
An access control list (ACL) represents who/what has permissions to a
given object. Different operating systems implement (ACLs) in different
ways. In UNIX, there are three types of permissions: read, write, and
execute. Users are divided into three classes for file access: owner, group
owner, and all other users where each class has a separate set of rights. In
Windows NT, there are four basic types of permissions for files: "No
access", "Read access", "Change access", and "Full control". Windows NT
extends the concept of three types of users in UNIX to include a list of
users and groups along with their associated permissions. A user can create
an object (file) and assign specified permissions to that object.
[R.285.6] [REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 2, "Common Vulnerabilities of Authorization", Page
39.. 1st Edition. Addison Wesley. 2006.
[R.285.7] [REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 11, "ACL Inheritance", Page 649.. 1st Edition. Addison Wesley. 2006.
Improper Check for Unusual or Exceptional Conditions
Definition in a New Window
Weakness ID: 754 (Weakness Class)
Status: Incomplete
Description
Description Summary
The software does not check or improperly checks for unusual or exceptional conditions that are not expected to occur frequently during day to day operation of the software.
Extended Description
The programmer may assume that certain events or conditions will never occur or do not need to be worried about, such as low memory conditions, lack of access to resources due to restrictive permissions, or misbehaving clients or components. However, attackers may intentionally trigger these unusual conditions, thus violating the programmer's assumptions, possibly introducing instability, incorrectbehavior, or a vulnerability.
Note that this entry is not exclusively about the use of exceptions and exception handling, which are mechanisms for both checking and handling unusual or unexpected conditions.
Time of Introduction
Implementation
Applicable Platforms
Languages
Language-independent
Common Consequences
Scope
Effect
Integrity
Availability
Technical Impact: DoS: crash / exit /
restart; Unexpected state
The data which were produced as a result of a function call could be
in a bad state upon return. If the return value is not checked, then
this bad data may be used in operations, possibly leading to a crash or
other unintended behaviors.
Likelihood of Exploit
Medium
Detection Methods
Automated Static Analysis
Automated static analysis may be useful for detecting unusual
conditions involving system resources or common programming idioms, but
not for violations of business rules.
Effectiveness: Moderate
Manual Dynamic Analysis
Identify error conditions that are not likely to occur during normal
usage and trigger them. For example, run the program under low memory
conditions, run with insufficient privileges or permissions, interrupt a
transaction before it is completed, or disable connectivity to basic
network services such as DNS. Monitor the software for any unexpected
behavior. If you trigger an unhandled exception or similar error that
was discovered and handled by the application's environment, it may
still indicate unexpected conditions that were not handled by the
application itself.
Demonstrative Examples
Example 1
Consider the following code segment:
(Bad Code)
Example
Language: C
char buf[10], cp_buf[10];
fgets(buf, 10, stdin);
strcpy(cp_buf, buf);
The programmer expects that when fgets() returns, buf will contain a
null-terminated string of length 9 or less. But if an I/O error occurs,
fgets() will not null-terminate buf. Furthermore, if the end of the file
is reached before any characters are read, fgets() returns without
writing anything to buf. In both of these situations, fgets() signals
that something unusual has happened by returning NULL, but in this code,
the warning will not be noticed. The lack of a null terminator in buf
can result in a buffer overflow in the subsequent call to strcpy().
Example 2
The following code does not check to see if memory allocation
succeeded before attempting to use the pointer returned by
malloc().
(Bad Code)
Example
Language: C
buf = (char*) malloc(req_size);
strncpy(buf, xfer, req_size);
The traditional defense of this coding error is: "If my program runs
out of memory, it will fail. It doesn't matter whether I handle the
error or simply allow the program to die with a segmentation fault when
it tries to dereference the null pointer." This argument ignores three
important considerations:
Depending upon the type and size of the application, it may be
possible to free memory that is being used elsewhere so that
execution can continue.
It is impossible for the program to perform a graceful exit if
required. If the program is performing an atomic operation, it can
leave the system in an inconsistent state.
The programmer has lost the opportunity to record diagnostic
information. Did the call to malloc() fail because req_size was too
large or because there were too many requests being handled at the
same time? Or was it caused by a memory leak that has built up over
time? Without handling the error, there is no way to know.
Example 3
The following code loops through a set of users, reading a private
data file for each user. The programmer assumes that the files are always 1
kilobyte in size and therefore ignores the return value from Read(). If an
attacker can create a smaller file, the program will recycle the remainder
of the data from the previous user and handle it as though it belongs to the
attacker.
(Bad Code)
Example
Language: Java
char[] byteArray = new char[1024];
for (IEnumerator i=users.GetEnumerator(); i.MoveNext()
;i.Current()) {
String userName = (String) i.Current();
String pFileName = PFILE_ROOT + "/" + userName;
StreamReader sr = new StreamReader(pFileName);
sr.Read(byteArray,0,1024);//the file is always 1k bytes
sr.Close();
processPFile(userName, byteArray);
}
(Bad Code)
Example
Language: Java
FileInputStream fis;
byte[] byteArray = new byte[1024];
for (Iterator i=users.iterator(); i.hasNext();) {
String userName = (String) i.next();
String pFileName = PFILE_ROOT + "/" + userName;
FileInputStream fis = new FileInputStream(pFileName);
fis.read(byteArray); // the file is always 1k bytes
fis.close();
processPFile(userName, byteArray);
}
Example 4
The following code does not check to see if the string returned by
getParameter() is null before calling the member function compareTo(),
potentially causing a NULL dereference.
The following code does not check to see if the string returned by the
Item property is null before calling the member function Equals(),
potentially causing a NULL dereference.
(Bad Code)
Example
Language: Java
String itemName = request.Item(ITEM_NAME);
if (itemName.Equals(IMPORTANT_ITEM)) {
...
}
...
The traditional defense of this coding error is: "I know the requested
value will always exist because.... If it does not exist, the program
cannot perform the desired behavior so it doesn't matter whether I
handle the error or simply allow the program to die dereferencing a null
value." But attackers are skilled at finding unexpected paths through
programs, particularly when exceptions are involved.
Example 5
The following code shows a system property that is set to null and
later dereferenced by a programmer who mistakenly assumes it will always be
defined.
(Bad Code)
Example
Language: Java
System.clearProperty("os.name");
...
String os = System.getProperty("os.name");
if (os.equalsIgnoreCase("Windows 95")) System.out.println("Not
supported");
The traditional defense of this coding error is: "I know the requested
value will always exist because.... If it does not exist, the program
cannot perform the desired behavior so it doesn't matter whether I
handle the error or simply allow the program to die dereferencing a null
value." But attackers are skilled at finding unexpected paths through
programs, particularly when exceptions are involved.
Example 6
The following VB.NET code does not check to make sure that it has
read 50 bytes from myfile.txt. This can cause DoDangerousOperation() to
operate on an unexpected value.
(Bad Code)
Example
Language: .NET
Dim MyFile As New FileStream("myfile.txt", FileMode.Open,
FileAccess.Read, FileShare.Read)
Dim MyArray(50) As Byte
MyFile.Read(MyArray, 0, 50)
DoDangerousOperation(MyArray(20))
In .NET, it is not uncommon for programmers to misunderstand Read()
and related methods that are part of many System.IO classes. The stream
and reader classes do not consider it to be unusual or exceptional if
only a small amount of data becomes available. These classes simply add
the small amount of data to the return buffer, and set the return value
to the number of bytes or characters read. There is no guarantee that
the amount of data returned is equal to the amount of data requested.
Example 7
This example takes an IP address from a user, verifies that it is
well formed and then looks up the hostname and copies it into a
buffer.
(Bad Code)
Example
Language: C
void host_lookup(char *user_supplied_addr){
struct hostent *hp;
in_addr_t *addr;
char hostname[64];
in_addr_t inet_addr(const char *cp);
/*routine that ensures user_supplied_addr is in the right
format for conversion */
validate_addr_form(user_supplied_addr);
addr = inet_addr(user_supplied_addr);
hp = gethostbyaddr( addr, sizeof(struct in_addr),
AF_INET);
strcpy(hostname, hp->h_name);
}
If an attacker provides an address that appears to be well-formed, but the address does not resolve to a hostname, then the call to gethostbyaddr() will return NULL. When this occurs, a NULL pointer dereference (CWE-476) will occur in the call to strcpy().
Note that this example is also vulnerable to a buffer overflow (see CWE-119).
Example 8
In the following C/C++ example the method outputStringToFile opens
a file in the local filesystem and outputs a string to the file. The input
parameters output and filename contain the string to output to the file and
the name of the file respectively.
(Bad Code)
Example
Language: C++
int outputStringToFile(char *output, char *filename) {
openFileToWrite(filename);
writeToFile(output);
closeFile(filename);
}
However, this code does not check the return values of the methods
openFileToWrite, writeToFile, closeFile to verify that the file was
properly opened and closed and that the string was successfully written
to the file. The return values for these methods should be checked to
determine if the method was successful and allow for detection of errors
or unexpected conditions as in the following example.
(Good Code)
Example
Language: C++
int outputStringToFile(char *output, char *filename) {
int isOutput = SUCCESS;
int isOpen = openFileToWrite(filename);
if (isOpen == FAIL) {
printf("Unable to open file %s", filename);
isOutput = FAIL;
}
else {
int isWrite = writeToFile(output);
if (isWrite == FAIL) {
printf("Unable to write to file %s", filename);
isOutput = FAIL;
}
int isClose = closeFile(filename);
if (isClose == FAIL)
isOutput = FAIL;
}
return isOutput;
}
Example 9
In the following Java example the method readFromFile uses a
FileReader object to read the contents of a file. The FileReader object is
created using the File object readFile, the readFile object is initialized
using the setInputFile method. The setInputFile method should be called
before calling the readFromFile method.
(Bad Code)
Example
Language: Java
private File readFile = null;
public void setInputFile(String inputFile) {
// create readFile File object from string containing name
of file
}
public void readFromFile() {
try {
reader = new FileReader(readFile);
// read input file
} catch (FileNotFoundException ex) {...}
}
However, the readFromFile method does not check to see if the
readFile object is null, i.e. has not been initialized, before creating
the FileReader object and reading from the input file. The readFromFile
method should verify whether the readFile object is null and output an
error message and raise an exception if the readFile object is null, as
in the following code.
(Good Code)
Example
Language: Java
private File readFile = null;
public void setInputFile(String inputFile) {
// create readFile File object from string containing name
of file
}
public void readFromFile() {
try {
if (readFile == null) {
System.err.println("Input file has not been set, call
setInputFile method before calling
openInputFile");
Program does not check return value when invoking
functions to drop privileges, which could leave users with higher privileges
than expected by forcing those functions to
fail.
Program does not check return value when invoking
functions to drop privileges, which could leave users with higher privileges
than expected by forcing those functions to
fail.
Potential Mitigations
Phase: Requirements
Strategy: Language Selection
Use a language that does not allow this weakness to occur or provides
constructs that make this weakness easier to avoid.
Choose languages with features such as exception handling that force the programmer to anticipate unusual conditions that may generate exceptions. Custom exceptions may need to be developed to handle unusual business-logic conditions. Be careful not to pass sensitive exceptions back to the user (CWE-209, CWE-248).
Phase: Implementation
Check the results of all functions that return a value and verify that
the value is expected.
Effectiveness: High
Checking the return value of the function will typically be sufficient, however beware of race conditions (CWE-362) in a concurrent environment.
Phase: Implementation
If using exception handling, catch and throw specific exceptions instead of overly-general exceptions (CWE-396, CWE-397). Catch and handle exceptions as locally as possible so that exceptions do not propagate too far up the call stack (CWE-705). Avoid unchecked or uncaught exceptions where feasible (CWE-248).
Effectiveness: High
Using specific exceptions, and ensuring that exceptions are checked,
helps programmers to anticipate and appropriately handle many unusual
events that could occur.
Phase: Implementation
Ensure that error messages only contain minimal details that are
useful to the intended audience, and nobody else. The messages need to
strike the balance between being too cryptic and not being cryptic
enough. They should not necessarily reveal the methods that were used to
determine the error. Such detailed information can be used to refine the
original attack to increase the chances of success.
If errors must be tracked in some detail, capture them in log messages
- but consider what could occur if the log messages can be viewed by
attackers. Avoid recording highly sensitive information such as
passwords in any form. Avoid inconsistent messaging that might
accidentally tip off an attacker about internal state, such as whether a
username is valid or not.
Exposing additional information to a potential attacker in the context
of an exceptional condition can help the attacker determine what attack
vectors are most likely to succeed beyond DoS.
Phase: Implementation
Strategy: Input Validation
Assume all input is malicious. Use an "accept known good" input
validation strategy, i.e., use a whitelist of acceptable inputs that
strictly conform to specifications. Reject any input that does not
strictly conform to specifications, or transform it into something that
does.
When performing input validation, consider all potentially relevant
properties, including length, type of input, the full range of
acceptable values, missing or extra inputs, syntax, consistency across
related fields, and conformance to business rules. As an example of
business rule logic, "boat" may be syntactically valid because it only
contains alphanumeric characters, but it is not valid if the input is
only expected to contain colors such as "red" or "blue."
Do not rely exclusively on looking for malicious or malformed inputs
(i.e., do not rely on a blacklist). A blacklist is likely to miss at
least one undesirable input, especially if the code's environment
changes. This can give attackers enough room to bypass the intended
validation. However, blacklists can be useful for detecting potential
attacks or determining which inputs are so malformed that they should be
rejected outright.
Performing extensive input validation does not help with handling
unusual conditions, but it will minimize their occurrences and will make
it more difficult for attackers to trigger them.
Phases: Architecture and Design; Implementation
If the program must fail, ensure that it fails gracefully (fails
closed). There may be a temptation to simply let the program fail poorly
in cases such as low memory conditions, but an attacker may be able to
assert control before the software has fully exited. Alternately, an
uncontrolled failure could cause cascading problems with other
downstream components; for example, the program could send a signal to a
downstream process so the process immediately knows that a problem has
occurred and has a better chance of recovery.
Phase: Architecture and Design
Use system limits, which should help to prevent resource exhaustion.
However, the software should still handle low resource conditions since
they may still occur.
Background Details
Many functions will return some value about the success of their actions.
This will alert the program whether or not to handle any errors caused by
that function.
Sometimes, when a return value can be used to indicate an error, an
unchecked return value is a code-layer instance of a missing
application-layer check for exceptional conditions. However, return values
are not always needed to communicate exceptional conditions. For example,
expiration of resources, values passed by reference, asynchronously modified
data, sockets, etc. may indicate exceptional conditions without the use of a
return value.
Taxonomy Mappings
Mapped Taxonomy Name
Node ID
Fit
Mapped Node Name
CERT C++ Secure Coding
MEM32-CPP
Detect and handle memory allocation errors
CERT C++ Secure Coding
ERR39-CPP
Guarantee exception safety
CERT C Secure Coding
MEM32-C
Detect and handle memory allocation errors
References
[REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 7, "Program Building Blocks" Page
341. 1st Edition. Addison Wesley. 2006.
[REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 1, "Exceptional Conditions," Page
22. 1st Edition. Addison Wesley. 2006.
[REF-17] Michael Howard, David LeBlanc
and John Viega. "24 Deadly Sins of Software Security". "Sin 11: Failure to Handle Errors Correctly." Page
183. McGraw-Hill. 2010.
Improper Control of Filename for Include/Require Statement in PHP Program ('PHP Remote File Inclusion')
Definition in a New Window
Weakness ID: 98 (Weakness Base)
Status: Draft
Description
Description Summary
The PHP application receives input from an upstream component, but it does not restrict or incorrectly restricts the input before its usage in "require," "include," or similar functions.
Extended Description
In certain versions and configurations of PHP, this can allow an attacker to specify a URL to a remote location from which the software will obtain the code to execute. In other cases in association with path traversal, the attacker can specify a local file that may contain executable statements that can be parsed by PHP.
Alternate Terms
Remote file include
RFI:
The Remote File Inclusion (RFI) acronym is often used by vulnerability
researchers.
Local file inclusion:
This term is frequently used in cases in which remote download is disabled, or when the first part of the filename is not under the attacker's control, which forces use of relative path traversal (CWE-23) attack techniques to access files that may contain previously-injected PHP code, such as web access logs.
Time of Introduction
Implementation
Architecture and Design
Applicable Platforms
Languages
PHP: (Often)
Common Consequences
Scope
Effect
Integrity
Confidentiality
Availability
Technical Impact: Execute unauthorized code or
commands
The attacker may be able to specify arbitrary code to be executed from
a remote location. Alternatively, it may be possible to use normal
program behavior to insert php code into files on the local machine
which can then be included and force the code to execute since php
ignores everything in the file except for the content between php
specifiers.
Likelihood of Exploit
High to Very High
Detection Methods
Manual Analysis
Manual white-box analysis can be very effective for finding this
issue, since there is typically a relatively small number of include or
require statements in each program.
Effectiveness: High
Automated Static Analysis
The external control or influence of filenames can often be detected
using automated static analysis that models data flow within the
software.
Automated static analysis might not be able to recognize when proper
input validation is being performed, leading to false positives - i.e.,
warnings that do not have any security consequences or require any code
changes. If the program uses a customized input validation library, then
some tools may allow the analyst to create custom signatures to detect
usage of those routines.
Demonstrative Examples
Example 1
The following code attempts to include a function contained in a
separate PHP page on the server. It builds the path to the file by using the
supplied 'module_name' parameter and appending the string '/function.php' to
it.
victim.php
(Bad Code)
Example
Language: PHP
$dir = $_GET['module_name'];
include($dir . "/function.php");
The problem with the above code is that the value of $dir is not
restricted in any way, and a malicious user could manipulate the
'module_name' parameter to force inclusion of an unanticipated file. For
example, an attacker could request the above PHP page (example.php) with
a 'module_name' of "http://malicious.example.com" by using the following
request string:
Upon receiving this request, the code would set 'module_name' to the
value "http://malicious.example.com" and would attempt to include
http://malicious.example.com/function.php, along with any malicious code
it contains.
For the sake of this example, assume that the malicious version of
function.php looks like the following:
(Bad Code)
system($_GET['cmd']);
An attacker could now go a step further in our example and provide a
request string as follows:
The code will attempt to include the malicious function.php file from
the remote site. In turn, this file executes the command specified in
the 'cmd' parameter from the query string. The end result is an attempt
by tvictim.php to execute the potentially malicious command, in this
case:
(Attack)
/bin/ls -l
Note that the above PHP example can be mitigated by setting
allow_url_fopen to false, although this will not fully protect the code.
See potential mitigations.
PHP file inclusion issue, both remote and local;
local include uses ".." and "%00" characters as a manipulation, but many
remote file inclusion issues probably have this
vector.
chain: library file sends a redirect if it is
directly requested but continues to execute, allowing remote file inclusion
and path traversal.
Potential Mitigations
Phase: Architecture and Design
Strategy: Libraries or Frameworks
Use a vetted library or framework that does not allow this weakness to
occur or provides constructs that make this weakness easier to
avoid.
Phase: Architecture and Design
Strategy: Enforcement by Conversion
When the set of acceptable objects, such as filenames or URLs, is
limited or known, create a mapping from a set of fixed input values
(such as numeric IDs) to the actual filenames or URLs, and reject all
other inputs.
For example, ID 1 could map to "inbox.txt" and ID 2 could map to "profile.txt". Features such as the ESAPI AccessReferenceMap [R.98.1] provide this capability.
Phase: Architecture and Design
For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.
Phases: Architecture and Design; Operation
Strategy: Sandbox or Jail
Run the code in a "jail" or similar sandbox environment that enforces
strict boundaries between the process and the operating system. This may
effectively restrict which files can be accessed in a particular
directory or which commands can be executed by the software.
OS-level examples include the Unix chroot jail, AppArmor, and SELinux.
In general, managed code may provide some protection. For example,
java.io.FilePermission in the Java SecurityManager allows the software
to specify restrictions on file operations.
This may not be a feasible solution, and it only limits the impact to
the operating system; the rest of the application may still be subject
to compromise.
Be careful to avoid CWE-243 and other weaknesses related to jails.
Effectiveness: Limited
The effectiveness of this mitigation depends on the prevention
capabilities of the specific sandbox or jail being used and might only
help to reduce the scope of an attack, such as restricting the attacker
to certain system calls or limiting the portion of the file system that
can be accessed.
Phases: Architecture and Design; Operation
Strategy: Environment Hardening
Run your code using the lowest privileges that are required to accomplish the necessary tasks [R.98.2]. If possible, create isolated accounts with limited privileges that are only used for a single task. That way, a successful attack will not immediately give the attacker access to the rest of the software or its environment. For example, database applications rarely need to run as the database administrator, especially in day-to-day operations.
Phase: Implementation
Strategy: Input Validation
Assume all input is malicious. Use an "accept known good" input
validation strategy, i.e., use a whitelist of acceptable inputs that
strictly conform to specifications. Reject any input that does not
strictly conform to specifications, or transform it into something that
does.
When performing input validation, consider all potentially relevant
properties, including length, type of input, the full range of
acceptable values, missing or extra inputs, syntax, consistency across
related fields, and conformance to business rules. As an example of
business rule logic, "boat" may be syntactically valid because it only
contains alphanumeric characters, but it is not valid if the input is
only expected to contain colors such as "red" or "blue."
Do not rely exclusively on looking for malicious or malformed inputs
(i.e., do not rely on a blacklist). A blacklist is likely to miss at
least one undesirable input, especially if the code's environment
changes. This can give attackers enough room to bypass the intended
validation. However, blacklists can be useful for detecting potential
attacks or determining which inputs are so malformed that they should be
rejected outright.
When validating filenames, use stringent whitelists that limit the character set to be used. If feasible, only allow a single "." character in the filename to avoid weaknesses such as CWE-23, and exclude directory separators such as "/" to avoid CWE-36. Use a whitelist of allowable file extensions, which will help to avoid CWE-434.
Do not rely exclusively on a filtering mechanism that removes potentially dangerous characters. This is equivalent to a blacklist, which may be incomplete (CWE-184). For example, filtering "/" is insufficient protection if the filesystem also supports the use of "\" as a directory separator. Another possible error could occur when the filtering is applied in a way that still produces dangerous data (CWE-182). For example, if "../" sequences are removed from the ".../...//" string in a sequential fashion, two instances of "../" would be removed from the original string, but the remaining characters would still form the "../" string.
Phases: Architecture and Design; Operation
Strategy: Identify and Reduce Attack Surface
Store library, include, and utility files outside of the web document
root, if possible. Otherwise, store them in a separate directory and use
the web server's access control capabilities to prevent attackers from
directly requesting them. One common practice is to define a fixed
constant in each calling program, then check for the existence of the
constant in the library/include file; if the constant does not exist,
then the file was directly requested, and it can exit
immediately.
This significantly reduces the chance of an attacker being able to
bypass any protection mechanisms that are in the base program but not in
the include files. It will also reduce the attack surface.
Phases: Architecture and Design; Implementation
Strategy: Identify and Reduce Attack Surface
Understand all the potential areas where untrusted inputs can enter
your software: parameters or arguments, cookies, anything read from the
network, environment variables, reverse DNS lookups, query results,
request headers, URL components, e-mail, files, filenames, databases,
and any external systems that provide data to the application. Remember
that such inputs may be obtained indirectly through API calls.
Many file inclusion problems occur because the programmer assumed that
certain inputs could not be modified, especially for cookies and URL
components.
Phase: Operation
Strategy: Firewall
Use an application firewall that can detect attacks against this
weakness. It can be beneficial in cases in which the code cannot be
fixed (because it is controlled by a third party), as an emergency
prevention measure while more comprehensive software assurance measures
are applied, or to provide defense in depth.
Effectiveness: Moderate
An application firewall might not cover all possible input vectors. In
addition, attack techniques might be available to bypass the protection
mechanism, such as using malformed inputs that can still be processed by
the component that receives those inputs. Depending on functionality, an
application firewall might inadvertently reject or modify legitimate
requests. Finally, some manual effort may be required for
customization.
Phases: Operation; Implementation
Strategy: Environment Hardening
Develop and run your code in the most recent versions of PHP
available, preferably PHP 6 or later. Many of the highly risky features
in earlier PHP interpreters have been removed, restricted, or disabled
by default.
Phases: Operation; Implementation
Strategy: Environment Hardening
When using PHP, configure the application so that it does not use register_globals. During implementation, develop the application so that it does not rely on this feature, but be wary of implementing a register_globals emulation that is subject to weaknesses such as CWE-95, CWE-621, and similar issues.
Often, programmers do not protect direct access to files intended only
to be included by core programs. These include files may assume that
critical variables have already been initialized by the calling program.
As a result, the use of register_globals combined with the ability to
directly access the include file may allow attackers to conduct file
inclusion attacks. This remains an extremely common pattern as of
2009.
Phase: Operation
Strategy: Environment Hardening
Set allow_url_fopen to false, which limits the ability to include
files from remote locations.
Effectiveness: High
Be aware that some versions of PHP will still accept ftp:// and other URI schemes. In addition, this setting does not protect the code from path traversal attacks (CWE-22), which are frequently successful against the same vulnerable code that allows remote file inclusion.
This is frequently a functional consequence of other weaknesses. It is
usually multi-factor with other factors (e.g. MAID), although not all
inclusion bugs involve assumed-immutable data. Direct request weaknesses
frequently play a role.
Can overlap directory traversal in local inclusion problems.
Research Gaps
Under-researched and under-reported. Other interpreted languages with
"require" and "include" functionality could also product vulnerable
applications, but as of 2007, PHP has been the focus. Any web-accessible
language that uses executable file extensions is likely to have this type of
issue, such as ASP, since .asp extensions are typically executable.
Languages such as Perl are less likely to exhibit these problems because the
.pl extension isn't always configured to be executable by the web
server.
The software does not properly limit the number or frequency of interactions that it has with an actor, such as the number of incoming requests.
Extended Description
This can allow the actor to perform actions more frequently than expected. The actor could be a human or an automated process such as a virus or bot. This could be used to cause a denial of service, compromise program logic (such as limiting humans to a single vote), or other consequences. For example, an authentication routine might not limit the number of times an attacker can guess a password. Or, a web site might conduct a poll but only expect humans to vote a maximum of once a day.
Alternate Terms
Insufficient anti-automation:
The term "insufficient anti-automation" focuses primarly on non-human
actors such as viruses or bots, but the scope of this CWE entry is
broader.
Brute force:
Vulnerabilities that can be targeted using brute force attacks are
often symptomatic of this weakness.
Time of Introduction
Architecture and Design
Implementation
Operation
Applicable Platforms
Languages
Language-independent
Common Consequences
Scope
Effect
Availability
Access Control
Other
Technical Impact: DoS: resource consumption
(other); Bypass protection
mechanism; Other
Demonstrative Examples
Example 1
In the following code a username and password is read from a socket
and an attempt is made to authenticate the username and password. The code
will continuously checked the socket for a username and password until it
has been authenticated.
(Bad Code)
Example Languages: C and C++
char username[USERNAME_SIZE];
char password[PASSWORD_SIZE];
while (isValidUser == 0) {
if (getNextMessage(socket, username, USERNAME_SIZE) >
0) {
if (getNextMessage(socket, password, PASSWORD_SIZE)
> 0) {
This code does not place any restriction on the number of
authentication attempts made. There should be a limit on the number of
authentication attempts made to prevent brute force attacks as in the
following example code.
(Good Code)
Example Languages: C and C++
int count = 0;
while ((isValidUser == 0) && (count <
MAX_ATTEMPTS)) {
if (getNextMessage(socket, username, USERNAME_SIZE) >
0) {
if (getNextMessage(socket, password, PASSWORD_SIZE)
> 0) {
The software uses a resource that contains sensitive data, but it does not properly remove that data before it stores, transfers, or shares the resource with actors in another control sphere.
Extended Description
Resources that may contain sensitive data include documents, packets, messages, databases, etc. While this data may be useful to an individual user or small set of users who share the resource, it may need to be removed before the resource can be shared outside of the trusted group. The process of removal is sometimes called cleansing or scrubbing.
For example, software that is used for editing documents might not remove sensitive data such as reviewer comments or the local pathname where the document is stored. Or, a proxy might not remove an internal IP address from headers before making an outgoing request to an Internet site.
Terminology Notes
The terms "cleansing" and "scrubbing" have multiple uses within computing.
In information security, these are used for the removal of sensitive data,
but they are also used for the modification of incoming/outgoing data so
that it conforms to specifications.
Time of Introduction
Architecture and Design
Implementation
Operation
Applicable Platforms
Languages
Language-independent
Common Consequences
Scope
Effect
Confidentiality
Technical Impact: Read files or
directories; Read application
data
Sensitive data may be exposed to an unauthorized actor in another
control sphere. This may have a wide range of secondary consequences
which will depend on what data is exposed. One possibility is the
exposure of system data allowing an attacker to craft a specific, more
effective attack.
Demonstrative Examples
Example 1
This code either generates a public HTML user information page or a
JSON response containing the same user information.
(Bad Code)
Example
Language: PHP
// API flag, output JSON if set
$json = $_GET['json']
$username = $_GET['user']
if(!$json)
{
$record = getUserRecord($username);
foreach($record as $fieldName => $fieldValue)
{
if($fieldName == "email_address") {
// skip displaying user emails
continue;
}
else{
writeToHtmlPage($fieldName,$fieldValue);
}
}
}
else
{
$record = getUserRecord($username);
echo json_encode($record);
}
The programmer is careful to not display the user's e-mail address
when displaying the public HTML page. However, the e-mail address is not
removed from the JSON response, exposing the user's e-mail address.
NAT feature in firewall leaks internal IP
addresses in ICMP error messages.
Potential Mitigations
Phase: Requirements
Clearly specify which information should be regarded as private or
sensitive, and require that the product offers functionality that allows
the user to cleanse the sensitive information from the resource before
it is published or exported to other parties.
Phase: Architecture and Design
Strategy: Separation of Privilege
Compartmentalize the system to have "safe" areas where trust
boundaries can be unambiguously drawn. Do not allow sensitive data to go
outside of the trust boundary and always be careful when interfacing
with a compartment outside of the safe area.
Ensure that appropriate compartmentalization is built into the system
design and that the compartmentalization serves to allow for and further
reinforce privilege separation functionality. Architects and designers
should rely on the principle of least privilege to decide when it is
appropriate to use and to drop system privileges.
Phase: Implementation
Strategy: Identify and Reduce Attack Surface
Use naming conventions and strong types to make it easier to spot when
sensitive data is being used. When creating structures, objects, or
other complex entities, separate the sensitive and non-sensitive data as
much as possible.
Effectiveness: Defense in Depth
This makes it easier to spot places in the code where data is being
used that is unencrypted.
Phase: Implementation
Avoid errors related to improper resource shutdown or release (CWE-404), which may leave the sensitive data within the resource if it is in an incomplete state.
This entry is intended to be different from resultant information leaks,
including those that occur from improper buffer initialization and reuse,
improper encryption, interaction errors, and multiple interpretation errors.
This entry could be regarded as a privacy leak, depending on the type of
information that is leaked.
There is a close association between CWE-226 and CWE-212. The difference is partially that of perspective. CWE-226 is geared towards the final stage of the resource lifecycle, in which the resource is deleted, eliminated, expired, or otherwise released for reuse. Technically, this involves a transfer to a different control sphere, in which the original contents of the resource are no longer relevant. CWE-212, however, is intended for sensitive data in resources that are intentionally shared with others, so they are still active. This distinction is useful from the perspective of the CWE research view (CWE-1000).
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
Definition in a New Window
Weakness ID: 22 (Weakness Class)
Status: Draft
Description
Description Summary
The software uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the software does not properly neutralizespecial elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
Extended Description
Many file operations are intended to take place within a restricted directory. By using special elements such as ".." and "/" separators, attackers can escape outside of the restricted location to access files or directories that are elsewhere on the system. One of the most common special elements is the "../" sequence, which in most modern operating systems is interpreted as the parent directory of the current location. This is referred to as relative path traversal. Path traversal also covers the use of absolute pathnames such as "/usr/local/bin", which may also be useful in accessing unexpected files. This is referred to as absolute path traversal.
In many programming languages, the injection of a null byte (the 0 or NUL) may allow an attacker to truncate a generated filename to widen the scope of attack. For example, the software may add ".txt" to any pathname, thus limiting the attacker to text files, but a null injection may effectively remove this restriction.
Alternate Terms
Directory traversal
Path traversal:
"Path traversal" is preferred over "directory traversal," but both
terms are attack-focused.
Terminology Notes
Like other weaknesses, terminology is often based on the types of
manipulations used, instead of the underlying weaknesses. Some people use
"directory traversal" only to refer to the injection of ".." and equivalent
sequences whose specific meaning is to traverse directories.
Other variants like "absolute pathname" and "drive letter" have the
*effect* of directory traversal, but some people may not call it such, since
it doesn't involve ".." or equivalent.
Time of Introduction
Architecture and Design
Implementation
Applicable Platforms
Languages
Language-independent
Common Consequences
Scope
Effect
Integrity
Confidentiality
Availability
Technical Impact: Execute unauthorized code or
commands
The attacker may be able to create or overwrite critical files that
are used to execute code, such as programs or libraries.
Integrity
Technical Impact: Modify files or
directories
The attacker may be able to overwrite or create critical files, such
as programs, libraries, or important data. If the targeted file is used
for a security mechanism, then the attacker may be able to bypass that
mechanism. For example, appending a new account at the end of a password
file may allow an attacker to bypass authentication.
Confidentiality
Technical Impact: Read files or
directories
The attacker may be able read the contents of unexpected files and
expose sensitive data. If the targeted file is used for a security
mechanism, then the attacker may be able to bypass that mechanism. For
example, by reading a password file, the attacker could conduct brute
force password guessing attacks in order to break into an account on the
system.
Availability
Technical Impact: DoS: crash / exit /
restart
The attacker may be able to overwrite, delete, or corrupt unexpected
critical files such as programs, libraries, or important data. This may
prevent the software from working at all and in the case of a protection
mechanisms such as authentication, it has the potential to lockout every
user of the software.
Likelihood of Exploit
High to Very High
Detection Methods
Automated Static Analysis
Automated techniques can find areas where path traversal weaknesses
exist. However, tuning or customization may be required to remove or
de-prioritize path-traversal problems that are only exploitable by the
software's administrator - or other privileged users - and thus
potentially valid behavior or, at worst, a bug instead of a
vulnerability.
Effectiveness: High
Manual Static Analysis
Manual white box techniques may be able to provide sufficient code
coverage and reduction of false positives if all file access operations
can be assessed within limited time constraints.
Effectiveness: High
Demonstrative Examples
Example 1
The following code could be for a social networking application in
which each user's profile information is stored in a separate file. All
files are stored in a single directory.
While the programmer intends to access files such as
"/users/cwe/profiles/alice" or "/users/cwe/profiles/bob", there is no
verification of the incoming user parameter. An attacker could provide a
string such as:
(Attack)
../../../etc/passwd
The program would generate a profile pathname like this:
(Result)
/users/cwe/profiles/../../../etc/passwd
When the file is opened, the operating system resolves the "../"
during path canonicalization and actually accesses this file:
(Result)
/etc/passwd
As a result, the attacker could read the entire text of the password
file.
Notice how this code also contains an error message information leak (CWE-209) if the user parameter does not produce a file that exists: the full pathname is provided. Because of the lack of output encoding of the file that is retrieved, there might also be a cross-site scripting problem (CWE-79) if profile contains any HTML, but other code would need to be examined.
Example 2
In the example below, the path to a dictionary file is read from a
system property and used to initialize a File object.
However, the path is not validated or modified to prevent it from
containing relative or absolute path sequences before creating the File
object. This allows anyone who can control the system property to
determine what file is used. Ideally, the path should be resolved
relative to some kind of application or user home directory.
Example 3
The following code takes untrusted input and uses a regular
expression to filter "../" from the input. It then appends this result to
the /home/user/ directory and attempts to read the file in the final
resulting path.
(Bad Code)
Example
Language: Perl
my $Username = GetUntrustedInput();
$Username =~ s/\.\.\///;
my $filename = "/home/user/" . $Username;
ReadAndSendFile($filename);
Since the regular expression does not have the /g global match
modifier, it only removes the first instance of "../" it comes across.
So an input value such as:
(Attack)
../../../etc/passwd
will have the first "../" stripped, resulting in:
(Result)
../../etc/passwd
This value is then concatenated with the /home/user/ directory:
(Result)
/home/user/../../etc/passwd
which causes the /etc/passwd file to be retrieved once the operating system has resolved the ../ sequences in the pathname. This leads to relative path traversal (CWE-23).
Example 4
The following code attempts to validate a given input path by
checking it against a white list and once validated delete the given file.
In this specific case, the path is considered valid if it starts with the
string "/safe_dir/".
(Bad Code)
Example
Language: Java
String path = getInputPath();
if (path.startsWith("/safe_dir/"))
{
File f = new File(path);
f.delete()
}
An attacker could provide an input such as this:
(Attack)
/safe_dir/../important.dat
The software assumes that the path is valid because it starts with the
"/safe_path/" sequence, but the "../" sequence will cause the program to
delete the important.dat file in the parent directory
Example 5
The following code demonstrates the unrestricted upload of a file
with a Java servlet and a path traversal vulnerability. The HTML code is the
same as in the previous example with the action attribute of the form
sending the upload file request to the Java servlet instead of the PHP
code.
When submitted the Java servlet's doPost method will receive the
request, extract the name of the file from the Http request header, read
the file contents from the request and output the file to the local
upload directory.
(Bad Code)
Example
Language: Java
public class FileUploadServlet extends HttpServlet {
BufferedWriter bw = new BufferedWriter(new
FileWriter(uploadLocation+filename, true));
for (String line; (line=br.readLine())!=null; )
{
if (line.indexOf(boundary) == -1) {
bw.write(line);
bw.newLine();
bw.flush();
}
} //end of for loop
bw.close();
} catch (IOException ex) {...}
// output successful upload response HTML
page
}
// output unsuccessful upload response HTML
page
else
{...}
}
...
}
This code does not check the filename that is provided in the header, so an attacker can use "../" sequences to write to files outside of the intended directory. Depending on the executing environment, the attacker may be able to specify arbitrary files to write to, leading to a wide variety of consequences, from code execution, XSS (CWE-79), or system crash.
Also, this code does not perform a check on the type of the file being uploaded. This could allow an attacker to upload any executable file or other file with malicious code (CWE-434).
chain: library file sends a redirect if it is
directly requested but continues to execute, allowing remote file inclusion
and path traversal.
Potential Mitigations
Phase: Implementation
Strategy: Input Validation
Assume all input is malicious. Use an "accept known good" input
validation strategy, i.e., use a whitelist of acceptable inputs that
strictly conform to specifications. Reject any input that does not
strictly conform to specifications, or transform it into something that
does.
When performing input validation, consider all potentially relevant
properties, including length, type of input, the full range of
acceptable values, missing or extra inputs, syntax, consistency across
related fields, and conformance to business rules. As an example of
business rule logic, "boat" may be syntactically valid because it only
contains alphanumeric characters, but it is not valid if the input is
only expected to contain colors such as "red" or "blue."
Do not rely exclusively on looking for malicious or malformed inputs
(i.e., do not rely on a blacklist). A blacklist is likely to miss at
least one undesirable input, especially if the code's environment
changes. This can give attackers enough room to bypass the intended
validation. However, blacklists can be useful for detecting potential
attacks or determining which inputs are so malformed that they should be
rejected outright.
When validating filenames, use stringent whitelists that limit the character set to be used. If feasible, only allow a single "." character in the filename to avoid weaknesses such as CWE-23, and exclude directory separators such as "/" to avoid CWE-36. Use a whitelist of allowable file extensions, which will help to avoid CWE-434.
Do not rely exclusively on a filtering mechanism that removes potentially dangerous characters. This is equivalent to a blacklist, which may be incomplete (CWE-184). For example, filtering "/" is insufficient protection if the filesystem also supports the use of "\" as a directory separator. Another possible error could occur when the filtering is applied in a way that still produces dangerous data (CWE-182). For example, if "../" sequences are removed from the ".../...//" string in a sequential fashion, two instances of "../" would be removed from the original string, but the remaining characters would still form the "../" string.
Phase: Architecture and Design
For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.
Phase: Implementation
Strategy: Input Validation
Inputs should be decoded and canonicalized to the application's current internal representation before being validated (CWE-180). Make sure that the application does not decode the same input twice (CWE-174). Such errors could be used to bypass whitelist validation schemes by introducing dangerous inputs after they have been checked.
Use a built-in path canonicalization function (such as realpath() in C) that produces the canonical version of the pathname, which effectively removes ".." sequences and symbolic links (CWE-23, CWE-59). This includes:
realpath() in C
getCanonicalPath() in Java
GetFullPath() in ASP.NET
realpath() or abs_path() in Perl
realpath() in PHP
Phase: Architecture and Design
Strategy: Libraries or Frameworks
Use a vetted library or framework that does not allow this weakness to
occur or provides constructs that make this weakness easier to
avoid.
Phase: Operation
Strategy: Firewall
Use an application firewall that can detect attacks against this
weakness. It can be beneficial in cases in which the code cannot be
fixed (because it is controlled by a third party), as an emergency
prevention measure while more comprehensive software assurance measures
are applied, or to provide defense in depth.
Effectiveness: Moderate
An application firewall might not cover all possible input vectors. In
addition, attack techniques might be available to bypass the protection
mechanism, such as using malformed inputs that can still be processed by
the component that receives those inputs. Depending on functionality, an
application firewall might inadvertently reject or modify legitimate
requests. Finally, some manual effort may be required for
customization.
Phases: Architecture and Design; Operation
Strategy: Environment Hardening
Run your code using the lowest privileges that are required to accomplish the necessary tasks [R.22.5]. If possible, create isolated accounts with limited privileges that are only used for a single task. That way, a successful attack will not immediately give the attacker access to the rest of the software or its environment. For example, database applications rarely need to run as the database administrator, especially in day-to-day operations.
Phase: Architecture and Design
Strategy: Enforcement by Conversion
When the set of acceptable objects, such as filenames or URLs, is
limited or known, create a mapping from a set of fixed input values
(such as numeric IDs) to the actual filenames or URLs, and reject all
other inputs.
For example, ID 1 could map to "inbox.txt" and ID 2 could map to "profile.txt". Features such as the ESAPI AccessReferenceMap [R.22.3] provide this capability.
Phases: Architecture and Design; Operation
Strategy: Sandbox or Jail
Run the code in a "jail" or similar sandbox environment that enforces
strict boundaries between the process and the operating system. This may
effectively restrict which files can be accessed in a particular
directory or which commands can be executed by the software.
OS-level examples include the Unix chroot jail, AppArmor, and SELinux.
In general, managed code may provide some protection. For example,
java.io.FilePermission in the Java SecurityManager allows the software
to specify restrictions on file operations.
This may not be a feasible solution, and it only limits the impact to
the operating system; the rest of the application may still be subject
to compromise.
Be careful to avoid CWE-243 and other weaknesses related to jails.
Effectiveness: Limited
The effectiveness of this mitigation depends on the prevention
capabilities of the specific sandbox or jail being used and might only
help to reduce the scope of an attack, such as restricting the attacker
to certain system calls or limiting the portion of the file system that
can be accessed.
Phases: Architecture and Design; Operation
Strategy: Identify and Reduce Attack Surface
Store library, include, and utility files outside of the web document
root, if possible. Otherwise, store them in a separate directory and use
the web server's access control capabilities to prevent attackers from
directly requesting them. One common practice is to define a fixed
constant in each calling program, then check for the existence of the
constant in the library/include file; if the constant does not exist,
then the file was directly requested, and it can exit
immediately.
This significantly reduces the chance of an attacker being able to
bypass any protection mechanisms that are in the base program but not in
the include files. It will also reduce the attack surface.
Phase: Implementation
Ensure that error messages only contain minimal details that are
useful to the intended audience, and nobody else. The messages need to
strike the balance between being too cryptic and not being cryptic
enough. They should not necessarily reveal the methods that were used to
determine the error. Such detailed information can be used to refine the
original attack to increase the chances of success.
If errors must be tracked in some detail, capture them in log messages
- but consider what could occur if the log messages can be viewed by
attackers. Avoid recording highly sensitive information such as
passwords in any form. Avoid inconsistent messaging that might
accidentally tip off an attacker about internal state, such as whether a
username is valid or not.
In the context of path traversal, error messages which disclose path
information can help attackers craft the appropriate attack strings to
move through the file system hierarchy.
Phases: Operation; Implementation
Strategy: Environment Hardening
When using PHP, configure the application so that it does not use register_globals. During implementation, develop the application so that it does not rely on this feature, but be wary of implementing a register_globals emulation that is subject to weaknesses such as CWE-95, CWE-621, and similar issues.
Other Notes
Incomplete diagnosis or reporting of vulnerabilities can make it difficult
to know which variant is affected. For example, a researcher might say that
"..\" is vulnerable, but not test "../" which may also be vulnerable.
Any combination of the items below can provide its own variant, e.g.
"//../" is not listed (CVE-2004-0325).
Weakness Ordinalities
Ordinality
Description
Primary
(where
the weakness exists independent of other weaknesses)
Resultant
(where
the weakness is typically related to the presence of some other
weaknesses)
Pathname equivalence can be regarded as a type of canonicalization
error.
Some pathname equivalence issues are not directly related to directory
traversal, rather are used to bypass security-relevant checks for whether a
file/directory can be accessed by the attacker (e.g. a trailing "/" on a
filename could bypass access rules that don't expect a trailing /, causing a
server to provide the file when it normally would not).
Research Gaps
Many variants of path traversal attacks are probably under-studied with respect to root cause. CWE-790 and CWE-182 begin to cover part of this gap.
Affected Resources
File/Directory
Relevant Properties
Equivalence
Functional Areas
File processing
Causal Nature
Explicit
Taxonomy Mappings
Mapped Taxonomy Name
Node ID
Fit
Mapped Node Name
PLOVER
Path Traversal
OWASP Top Ten 2007
A4
CWE_More_Specific
Insecure Direct Object Reference
OWASP Top Ten 2004
A2
CWE_More_Specific
Broken Access Control
CERT C Secure Coding
FIO02-C
Canonicalize path names originating from untrusted
sources
WASC
33
Path Traversal
CERT C++ Secure Coding
FIO02-CPP
Canonicalize path names originating from untrusted
sources
[R.22.1] [REF-11] M. Howard and
D. LeBlanc. "Writing Secure Code". Chapter 11, "Directory Traversal and Using Parent Paths (..)"
Page 370. 2nd Edition. Microsoft. 2002.
[R.22.6] [REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 9, "Filenames and Paths", Page
503.. 1st Edition. Addison Wesley. 2006.
Improper Link Resolution Before File Access ('Link Following')
Definition in a New Window
Weakness ID: 59 (Weakness Base)
Status: Draft
Description
Description Summary
The software attempts to access a file based on the filename, but it does not properly prevent that filename from identifying a link or shortcut that resolves to an unintended resource.
Alternate Terms
insecure temporary file:
Some people use the phrase "insecure temporary file" when referring to
a link following weakness, but other weaknesses can produce insecure
temporary files without any symlink involvement at all.
Time of Introduction
Implementation
Applicable Platforms
Languages
All
Operating Systems
Windows: (Sometimes)
UNIX: (Often)
Common Consequences
Scope
Effect
Confidentiality
Integrity
Access Control
Technical Impact: Read files or
directories; Modify files or
directories; Bypass protection
mechanism
An attacker may be able to traverse the file system to unintended
locations and read or overwrite the contents of unexpected files. If the
files are used for a security mechanism than an attacker may be able to
bypass the mechanism.
Some versions of Perl follows symbolic links when
running with the -e option, which allows local users to overwrite arbitrary
files via a symlink attack.
Text editor follows symbolic links when creating
a rescue copy during an abnormal exit, which allows local users to overwrite
the files of other users.
Window manager does not properly handle when
certain symbolic links point to "stale" locations, which could allow local
users to create or truncate arbitrary files.
Setuid product allows file reading by replacing a
file being edited with a symlink to the targeted file, leaking the result in
error messages when parsing fails.
Mail client allows remote attackers to bypass the
user warning for executable attachments such as .exe, .com, and .bat by
using a .lnk file that refers to the attachment, aka "Stealth Attachment."
Browser allows remote malicious web sites to
overwrite arbitrary files by tricking the user into downloading a .LNK
(link) file twice, which overwrites the file that was referenced in the
first .LNK file.
File system allows local attackers to hide file
usage activities via a hard link to the target file, which causes the link
to be recorded in the audit trail instead of the target file.
Web server plugin allows local users to overwrite
arbitrary files via a symlink attack on predictable temporary filenames.
Potential Mitigations
Phase: Architecture and Design
Strategy: Separation of Privilege
Follow the principle of least privilege when assigning access rights
to entities in a software system.
Denying access to a file can prevent an attacker from replacing that
file with a link to a sensitive file. Ensure good compartmentalization
in the system to provide protected areas that can be trusted.
Background Details
Soft links are a UNIX term that is synonymous with simple shortcuts on
windows based platforms.
Other Notes
Windows simple shortcuts, sometimes referred to as soft links, can be
exploited remotely since an ".LNK" file can be uploaded like a normal
file.
Weakness Ordinalities
Ordinality
Description
Resultant
(where
the weakness is typically related to the presence of some other
weaknesses)
Link following vulnerabilities are Multi-factor Vulnerabilities (MFV).
They are the combination of multiple elements: file or directory
permissions, filename predictability, race conditions, and in some cases, a
design limitation in which there is no mechanism for performing atomic file
creation operations.
Some potential factors are race conditions, permissions, and
predictability.
Research Gaps
UNIX hard links, and Windows hard/soft links are under-studied and
under-reported.
Affected Resources
File/Directory
Functional Areas
File processing, temporary files
Causal Nature
Explicit
Taxonomy Mappings
Mapped Taxonomy Name
Node ID
Fit
Mapped Node Name
PLOVER
Link Following
CERT C Secure Coding
FIO02-C
Canonicalize path names originating from untrusted
sources
CERT C Secure Coding
POS01-C
Check for the existence of links when dealing with
files
CERT C++ Secure Coding
FIO02-CPP
Canonicalize path names originating from untrusted
sources
[REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 9, "Symbolic Link Attacks", Page
518.. 1st Edition. Addison Wesley. 2006.
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
Definition in a New Window
Weakness ID: 79 (Weakness Base)
Status: Usable
Description
Description Summary
The software does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
1. Untrusted data enters a web application, typically from a web request.
2. The web application dynamically generates a web page that contains this untrusted data.
3. During page generation, the application does not prevent the data from containing content that is executable by a web browser, such as JavaScript, HTML tags, HTML attributes, mouse events, Flash, ActiveX, etc.
4. A victim visits the generated web page through a web browser, which contains malicious script that was injected using the untrusted data.
5. Since the script comes from a web page that was sent by the web server, the victim's web browser executes the malicious script in the context of the web server's domain.
6. This effectively violates the intention of the web browser's same-origin policy, which states that scripts in one domain should not be able to access resources or run code in a different domain.
There are three main kinds of XSS:
Type 1: Reflected XSS (or Non-Persistent)
The server reads data directly from the HTTP request and reflects it back in the HTTP response. Reflected XSS exploits occur when an attacker causes a victim to supply dangerous content to a vulnerable web application, which is then reflected back to the victim and executed by the web browser. The most common mechanism for delivering malicious content is to include it as a parameter in a URL that is posted publicly or e-mailed directly to the victim. URLs constructed in this manner constitute the core of many phishing schemes, whereby an attacker convinces a victim to visit a URL that refers to a vulnerable site. After the site reflects the attacker's content back to the victim, the content is executed by the victim's browser.
Type 2: Stored XSS (or Persistent)
The application stores dangerous data in a database, message forum, visitor log, or other trusted data store. At a later time, the dangerous data is subsequently read back into the application and included in dynamic content. From an attacker's perspective, the optimal place to inject malicious content is in an area that is displayed to either many users or particularly interesting users. Interesting users typically have elevated privileges in the application or interact with sensitive data that is valuable to the attacker. If one of these users executes malicious content, the attacker may be able to perform privileged operations on behalf of the user or gain access to sensitive data belonging to the user. For example, the attacker might inject XSS into a log message, which might not be handled properly when an administrator views the logs.
Type 0: DOM-Based XSS
In DOM-based XSS, the client performs the injection of XSS into the page; in the other types, the server performs the injection. DOM-based XSS generally involves server-controlled, trusted script that is sent to the client, such as Javascript that performs sanity checks on a form before the user submits it. If the server-supplied script processes user-supplied data and then injects it back into the web page (such as with dynamic HTML), then DOM-based XSS is possible.
Once the malicious script is injected, the attacker can perform a variety of malicious activities. The attacker could transfer private information, such as cookies that may include session information, from the victim's machine to the attacker. The attacker could send malicious requests to a web site on behalf of the victim, which could be especially dangerous to the site if the victim has administrator privileges to manage that site. Phishing attacks could be used to emulate trusted web sites and trick the victim into entering a password, allowing the attacker to compromise the victim's account on that web site. Finally, the script could exploit a vulnerability in the web browser itself possibly taking over the victim's machine, sometimes referred to as "drive-by hacking."
In many cases, the attack can be launched without the victim even being aware of it. Even with careful users, attackers frequently use a variety of methods to encode the malicious portion of the attack, such as URL encoding or Unicode, so the request looks less suspicious.
Alternate Terms
XSS
CSS:
"CSS" was once used as the acronym for this problem, but this could
cause confusion with "Cascading Style Sheets," so usage of this acronym
has declined significantly.
Time of Introduction
Architecture and Design
Implementation
Applicable Platforms
Languages
Language-independent
Architectural Paradigms
Web-based: (Often)
Technology Classes
Web-Server: (Often)
Platform Notes
XSS flaws are very common in web applications since they require a great
deal of developer discipline to avoid them.
Common Consequences
Scope
Effect
Access Control
Confidentiality
Technical Impact: Bypass protection
mechanism; Read application
data
The most common attack performed with cross-site scripting involves
the disclosure of information stored in user cookies. Typically, a
malicious user will craft a client-side script, which -- when parsed by
a web browser -- performs some activity (such as sending all site
cookies to a given E-mail address). This script will be loaded and run
by each user visiting the web site. Since the site requesting to run the
script has access to the cookies in question, the malicious script does
also.
Integrity
Confidentiality
Availability
Technical Impact: Execute unauthorized code or
commands
In some circumstances it may be possible to run arbitrary code on a
victim's computer when cross-site scripting is combined with other
flaws.
Confidentiality
Integrity
Availability
Access Control
Technical Impact: Execute unauthorized code or
commands; Bypass protection
mechanism; Read application
data
The consequence of an XSS attack is the same regardless of whether it
is stored or reflected. The difference is in how the payload arrives at
the server.
XSS can cause a variety of problems for the end user that range in
severity from an annoyance to complete account compromise. Some
cross-site scripting vulnerabilities can be exploited to manipulate or
steal cookies, create requests that can be mistaken for those of a valid
user, compromise confidential information, or execute malicious code on
the end user systems for a variety of nefarious purposes. Other damaging
attacks include the disclosure of end user files, installation of Trojan
horse programs, redirecting the user to some other page or site, running
"Active X" controls (under Microsoft Internet Explorer) from sites that
a user perceives as trustworthy, and modifying presentation of
content.
Likelihood of Exploit
High to Very High
Enabling Factors for Exploitation
Cross-site scripting attacks may occur anywhere that possibly malicious
users are allowed to post unregulated material to a trusted web site for the
consumption of other valid users, commonly on places such as bulletin-board
web sites which provide web based mailing list-style functionality.
Stored XSS got its start with web sites that offered a "guestbook" to
visitors. Attackers would include JavaScript in their guestbook entries, and
all subsequent visitors to the guestbook page would execute the malicious
code. As the examples demonstrate, XSS vulnerabilities are caused by code
that includes unvalidated data in an HTTP response.
Detection Methods
Automated Static Analysis
Use automated static analysis tools that target this type of weakness.
Many modern techniques use data flow analysis to minimize the number of
false positives. This is not a perfect solution, since 100% accuracy and
coverage are not feasible, especially when multiple components are
involved.
Effectiveness: Moderate
Black Box
Use the XSS Cheat Sheet [R.79.6] or automated test-generation tools to help launch a wide variety of attacks against your web application. The Cheat Sheet contains many subtle XSS variations that are specifically targeted against weak XSS defenses.
Effectiveness: Moderate
With Stored XSS, the indirection caused by the data store can make it
more difficult to find the problem. The tester must first inject the XSS
string into the data store, then find the appropriate application
functionality in which the XSS string is sent to other users of the
application. These are two distinct steps in which the activation of the
XSS can take place minutes, hours, or days after the XSS was originally
injected into the data store.
Demonstrative Examples
Example 1
This code displays a welcome message on a web page based on the
HTTP GET username parameter. This example covers a Reflected XSS (Type 1)
scenario.
Because the parameter can be arbitrary, the url of the page could be
modified so $username contains scripting syntax, such as
(Attack)
http://trustedSite.example.com/welcome.php?username=<Script
Language="Javascript">alert("You've been
attacked!");</Script>
This results in a harmless alert dialogue popping up. Initially this
might not appear to be much of a vulnerability. After all, why would
someone enter a URL that causes malicious code to run on their own
computer? The real danger is that an attacker will create the malicious
URL, then use e-mail or social engineering tricks to lure victims into
visiting a link to the URL. When victims click the link, they
unwittingly reflect the malicious content through the vulnerable web
application back to their own computers.
More realistically, the attacker can embed a fake login box on the
page, tricking the user into sending his password to the
attacker:
The trustworthy domain of the URL may falsely assure the user that it
is OK to follow the link. However, an astute user may notice the
suspicious text appended to the URL. An attacker may further obfuscate
the URL (the following example links are broken into multiple lines for
readability):
Both of these attack links will result in the fake login box appearing
on the page, and users are more likely to ignore indecipherable text at
the end of URLs.
Example 2
This example also displays a Reflected XSS (Type 1)
scenario.
The following JSP code segment reads an employee ID, eid, from an HTTP
request and displays it to the user.
(Bad Code)
Example
Language: JSP
<% String eid = request.getParameter("eid");
%>
...
Employee ID: <%= eid %>
The following ASP.NET code segment reads an employee ID number from an
HTTP request and displays it to the user.
The code in this example operates correctly if the Employee ID
variable contains only standard alphanumeric text. If it has a value
that includes meta-characters or source code, then the code will be
executed by the web browser as it displays the HTTP response.
Example 3
This example covers a Stored XSS (Type 2) scenario.
The following JSP code segment queries a database for an employee with
a given ID and prints the corresponding employee's name.
(Bad Code)
Example
Language: JSP
<%
...
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from emp where
id="+eid);
if (rs != null) {
rs.next();
String name = rs.getString("name");
%>
Employee Name: <%= name %>
The following ASP.NET code segment queries a database for an employee
with a given employee ID and prints the name corresponding with the
ID.
string query = "select * from emp where id=" + eid;
sda = new SqlDataAdapter(query, conn);
sda.Fill(dt);
string name = dt.Rows[0]["Name"];
...
EmployeeName.Text = name;
This code can appear less dangerous because the value of name is read
from a database, whose contents are apparently managed by the
application. However, if the value of name originates from user-supplied
data, then the database can be a conduit for malicious content. Without
proper input validation on all data stored in the database, an attacker
can execute malicious commands in the user's web browser.
Example 4
The following example consists of two separate pages in a web
application, one devoted to creating user accounts and another devoted to
listing active users currently logged in. It also displays a Stored XSS
(Type 2) scenario.
The code is careful to avoid a SQL injection attack (CWE-89) but does not stop valid HTML from being stored in the database. This can be exploited later when ListUsers.php retrieves the information:
ListUsers.php
(Bad Code)
$query = 'Select * From users Where loggedIn=true';
$results = mysql_query($query);
if (!$results) {
exit;
}
//Print list of users to page
echo '<div id="userlist">Currently Active
Users:';
The attacker can set his name to be arbitrary HTML, which will then be
displayed to all visitors of the Active Users page. This HTML can, for
example, be a password stealing Login message.
Chain: library file is not protected against a direct request (CWE-425), leading to reflected XSS.
Potential Mitigations
Phase: Architecture and Design
Strategy: Libraries or Frameworks
Use a vetted library or framework that does not allow this weakness to
occur or provides constructs that make this weakness easier to
avoid.
Examples of libraries and frameworks that make it easier to generate
properly encoded output include Microsoft's Anti-XSS library, the OWASP
ESAPI Encoding module, and Apache Wicket.
Phases: Implementation; Architecture and Design
Understand the context in which your data will be used and the
encoding that will be expected. This is especially important when
transmitting data between different components, or when generating
outputs that can contain multiple encodings at the same time, such as
web pages or multi-part mail messages. Study all expected communication
protocols and data representations to determine the required encoding
strategies.
For any data that will be output to another web page, especially any
data that was received from external inputs, use the appropriate
encoding on all non-alphanumeric characters.
Parts of the same output document may require different encodings,
which will vary depending on whether the output is in the:
HTML body
Element attributes (such as src="XYZ")
URIs
JavaScript sections
Cascading Style Sheets and style property
etc. Note that HTML Entity Encoding is only appropriate for the HTML
body.
Consult the XSS Prevention Cheat Sheet [R.79.16] for more details on the types of encoding and escaping that are needed.
Phases: Architecture and Design; Implementation
Strategy: Identify and Reduce Attack Surface
Understand all the potential areas where untrusted inputs can enter
your software: parameters or arguments, cookies, anything read from the
network, environment variables, reverse DNS lookups, query results,
request headers, URL components, e-mail, files, filenames, databases,
and any external systems that provide data to the application. Remember
that such inputs may be obtained indirectly through API calls.
Effectiveness: Limited
This technique has limited effectiveness, but can be helpful when it
is possible to store client state and sensitive information on the
server side instead of in cookies, headers, hidden form fields,
etc.
Phase: Architecture and Design
For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.
Phase: Architecture and Design
Strategy: Parameterization
If available, use structured mechanisms that automatically enforce the
separation between data and code. These mechanisms may be able to
provide the relevant quoting, encoding, and validation automatically,
instead of relying on the developer to provide this capability at every
point where output is generated.
Phase: Implementation
Strategy: Output Encoding
Use and specify an output encoding that can be handled by the
downstream component that is reading the output. Common encodings
include ISO-8859-1, UTF-7, and UTF-8. When an encoding is not specified,
a downstream component may choose a different encoding, either by
assuming a default encoding or automatically inferring which encoding is
being used, which can be erroneous. When the encodings are inconsistent,
the downstream component might treat some character or byte sequences as
special, even if they are not special in the original encoding.
Attackers might then be able to exploit this discrepancy and conduct
injection attacks; they even might be able to bypass protection
mechanisms that assume the original encoding is also being used by the
downstream component.
The problem of inconsistent output encodings often arises in web
pages. If an encoding is not specified in an HTTP header, web browsers
often guess about which encoding is being used. This can open up the
browser to subtle XSS attacks.
Phase: Implementation
With Struts, write all data from form beans with the bean's filter
attribute set to true.
Phase: Implementation
Strategy: Identify and Reduce Attack Surface
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 more recent versions of Internet Explorer and Firefox),
this attribute can prevent the user's session cookie from being
accessible to malicious client-side scripts that use document.cookie.
This is not a complete solution, since HttpOnly is not supported by all
browsers. More importantly, XMLHTTPRequest and other powerful browser
technologies provide read access to HTTP headers, including the
Set-Cookie header in which the HttpOnly flag is set.
Effectiveness: Defense in Depth
Phase: Implementation
Strategy: Input Validation
Assume all input is malicious. Use an "accept known good" input
validation strategy, i.e., use a whitelist of acceptable inputs that
strictly conform to specifications. Reject any input that does not
strictly conform to specifications, or transform it into something that
does.
When performing input validation, consider all potentially relevant
properties, including length, type of input, the full range of
acceptable values, missing or extra inputs, syntax, consistency across
related fields, and conformance to business rules. As an example of
business rule logic, "boat" may be syntactically valid because it only
contains alphanumeric characters, but it is not valid if the input is
only expected to contain colors such as "red" or "blue."
Do not rely exclusively on looking for malicious or malformed inputs
(i.e., do not rely on a blacklist). A blacklist is likely to miss at
least one undesirable input, especially if the code's environment
changes. This can give attackers enough room to bypass the intended
validation. However, blacklists can be useful for detecting potential
attacks or determining which inputs are so malformed that they should be
rejected outright.
When dynamically constructing web pages, use stringent whitelists that
limit the character set based on the expected value of the parameter in
the request. All input should be validated and cleansed, 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. It is common to see 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.
Note that proper output encoding, escaping, and quoting is the most
effective solution for preventing XSS, although input validation may
provide some defense-in-depth. This is because it effectively limits
what will appear in output. Input validation will not always prevent
XSS, especially if you are required to support free-form text fields
that could contain arbitrary characters. For example, in a chat
application, the heart emoticon ("<3") would likely pass the
validation step, since it is commonly used. However, it cannot be
directly inserted into the web page because it contains the "<"
character, which would need to be escaped or otherwise handled. In this
case, stripping the "<" might reduce the risk of XSS, but it
would produce incorrect behavior because the emoticon would not be
recorded. This might seem to be a minor inconvenience, but it would be
more important in a mathematical forum that wants to represent
inequalities.
Even if you make a mistake in your validation (such as forgetting one
out of 100 input fields), appropriate encoding is still likely to
protect you from injection-based attacks. As long as it is not done in
isolation, input validation is still a useful technique, since it may
significantly reduce your attack surface, allow you to detect some
attacks, and provide other security benefits that proper encoding does
not address.
Ensure that you perform input validation at well-defined interfaces
within the application. This will help protect the application even if a
component is reused or moved elsewhere.
Phase: Architecture and Design
Strategy: Enforcement by Conversion
When the set of acceptable objects, such as filenames or URLs, is
limited or known, create a mapping from a set of fixed input values
(such as numeric IDs) to the actual filenames or URLs, and reject all
other inputs.
Phase: Operation
Strategy: Firewall
Use an application firewall that can detect attacks against this
weakness. It can be beneficial in cases in which the code cannot be
fixed (because it is controlled by a third party), as an emergency
prevention measure while more comprehensive software assurance measures
are applied, or to provide defense in depth.
Effectiveness: Moderate
An application firewall might not cover all possible input vectors. In
addition, attack techniques might be available to bypass the protection
mechanism, such as using malformed inputs that can still be processed by
the component that receives those inputs. Depending on functionality, an
application firewall might inadvertently reject or modify legitimate
requests. Finally, some manual effort may be required for
customization.
Phases: Operation; Implementation
Strategy: Environment Hardening
When using PHP, configure the application so that it does not use register_globals. During implementation, develop the application so that it does not rely on this feature, but be wary of implementing a register_globals emulation that is subject to weaknesses such as CWE-95, CWE-621, and similar issues.
Background Details
Same Origin Policy
The same origin policy states that browsers should limit the resources
accessible to scripts running on a given web site, or "origin", to the
resources associated with that web site on the client-side, and not the
client-side resources of any other sites or "origins". The goal is to
prevent one site from being able to modify or read the contents of an
unrelated site. Since the World Wide Web involves interactions between many
sites, this policy is important for browsers to enforce.
Domain
The Domain of a website when referring to XSS is roughly equivalent to the
resources associated with that website on the client-side of the connection.
That is, the domain can be thought of as all resources the browser is
storing for the user's interactions with this particular site.
Weakness Ordinalities
Ordinality
Description
Resultant
(where
the weakness is typically related to the presence of some other
weaknesses)
[R.79.1] [REF-15] Jeremiah Grossman, Robert "RSnake" Hansen, Petko "pdp" D. Petkov, Anton Rager
and Seth Fogie. "XSS Attacks". Syngress. 2007.
[R.79.2] [REF-17] Michael Howard, David LeBlanc
and John Viega. "24 Deadly Sins of Software Security". "Sin 2: Web-Server Related Vulnerabilities (XSS, XSRF, and
Response Splitting)." Page 31. McGraw-Hill. 2010.
[R.79.3] [REF-17] Michael Howard, David LeBlanc
and John Viega. "24 Deadly Sins of Software Security". "Sin 3: Web-Client Related Vulnerabilities (XSS)." Page
63. McGraw-Hill. 2010.
[R.79.19] [REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 17, "Cross Site Scripting", Page
1071.. 1st Edition. Addison Wesley. 2006.
Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
Definition in a New Window
Weakness ID: 78 (Weakness Base)
Status: Draft
Description
Description Summary
The software constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component.
Extended Description
This could allow attackers to execute unexpected, dangerous commands directly on the operating system. This weakness can lead to a vulnerability in environments in which the attacker does not have direct access to the operating system, such as in web applications. Alternately, if the weakness occurs in a privileged program, it could allow the attacker to specify commands that normally would not be accessible, or to call alternate commands with privileges that the attacker does not have. The problem is exacerbated if the compromised process does not follow the principle of least privilege, because the attacker-controlled commands may run with special system privileges that increases the amount of damage.
There are at least two subtypes of OS command injection:
The application intends to execute a single, fixed program that is under its own control. It intends to use externally-supplied inputs as arguments to that program. For example, the program might use system("nslookup [HOSTNAME]") to run nslookup and allow the user to supply a HOSTNAME, which is used as an argument. Attackers cannot prevent nslookup from executing. However, if the program does not remove command separators from the HOSTNAME argument, attackers could place the separators into the arguments, which allows them to execute their own program after nslookup has finished executing.
The application accepts an input that it uses to fully select which program to run, as well as which commands to use. The application simply redirects this entire command to the operating system. For example, the program might use "exec([COMMAND])" to execute the [COMMAND] that was supplied by the user. If the COMMAND is under attacker control, then the attacker can execute arbitrary commands or programs. If the command is being executed using functions like exec() and CreateProcess(), the attacker might not be able to combine multiple commands together in the same line.
From a weakness standpoint, these variants represent distinct programmer errors. In the first variant, the programmer clearly intends that input from untrusted parties will be part of the arguments in the command to be executed. In the second variant, the programmer does not intend for the command to be accessible to any untrusted party, but the programmer probably has not accounted for alternate ways in which malicious attackers can provide input.
Alternate Terms
Shell injection
Shell metacharacters
Terminology Notes
The "OS command injection" phrase carries different meanings to different people. For some, it refers to any type of attack that can allow the attacker to execute OS commands of his or her choosing. This usage could include untrusted search path weaknesses (CWE-426) that cause the application to find and execute an attacker-controlled program. For others, it only refers to the first variant, in which the attacker injects command separators into arguments for an application-controlled program that is being invoked. Further complicating the issue is the case when argument injection (CWE-88) allows alternate command-line switches or options to be inserted into the command line, such as an "-exec" switch whose purpose may be to execute the subsequent argument as a command (this -exec switch exists in the UNIX "find" command, for example). In this latter case, however, CWE-88 could be regarded as the primary weakness in a chain with CWE-78.
Time of Introduction
Architecture and Design
Implementation
Applicable Platforms
Languages
All
Common Consequences
Scope
Effect
Confidentiality
Integrity
Availability
Non-Repudiation
Technical Impact: Execute unauthorized code or
commands; DoS: crash / exit /
restart; Read files or
directories; Modify files or
directories; Read application
data; Modify application
data; Hide activities
Attackers could execute unauthorized commands, which could then be
used to disable the software, or read and modify data for which the
attacker does not have permissions to access directly. Since the
targeted application is directly executing the commands instead of the
attacker, any malicious activities may appear to come from the
application or the application's owner.
Likelihood of Exploit
High
Detection Methods
Automated Static Analysis
This weakness can often be detected using automated static analysis
tools. Many modern tools use data flow analysis or constraint-based
techniques to minimize the number of false positives.
Automated static analysis might not be able to recognize when proper
input validation is being performed, leading to false positives - i.e.,
warnings that do not have any security consequences or require any code
changes.
Automated static analysis might not be able to detect the usage of
custom API functions or third-party libraries that indirectly invoke OS
commands, leading to false negatives - especially if the API/library
code is not available for analysis.
This is not a perfect solution, since 100% accuracy and coverage are
not feasible.
Automated Dynamic Analysis
This weakness can be detected using dynamic tools and techniques that
interact with the software using large test suites with many diverse
inputs, such as fuzz testing (fuzzing), robustness testing, and fault
injection. The software's operation may slow down, but it should not
become unstable, crash, or generate incorrect results.
Effectiveness: Moderate
Manual Static Analysis
Since this weakness does not typically appear frequently within a
single software package, manual white box techniques may be able to
provide sufficient code coverage and reduction of false positives if all
potentially-vulnerable operations can be assessed within limited time
constraints.
Effectiveness: High
Demonstrative Examples
Example 1
This example code intends to take the name of a user and list the
contents of that user's home directory. It is subject to the first variant
of OS command injection.
(Bad Code)
Example
Language: PHP
$userName = $_POST["user"];
$command = 'ls -l /home/' . $userName;
system($command);
The $userName variable is not checked for malicious input. An attacker
could set the $userName variable to an arbitrary OS command such as:
(Attack)
;rm -rf /
Which would result in $command being:
(Result)
ls -l /home/;rm -rf /
Since the semi-colon is a command separator in Unix, the OS would
first execute the ls command, then the rm command, deleting the entire
file system.
Also note that this example code is vulnerable to Path Traversal (CWE-22) and Untrusted Search Path (CWE-426) attacks.
Example 2
This example is a web application that intends to perform a DNS
lookup of a user-supplied domain name. It is subject to the first variant of
OS command injection.
(Bad Code)
Example
Language: Perl
use CGI qw(:standard);
$name = param('name');
$nslookup = "/path/to/nslookup";
print header;
if (open($fh, "$nslookup $name|")) {
while (<$fh>) {
print escapeHTML($_);
print "<br>\n";
}
close($fh);
}
Suppose an attacker provides a domain name like this:
(Attack)
cwe.mitre.org%20%3B%20/bin/ls%20-l
The "%3B" sequence decodes to the ";" character, and the %20 decodes
to a space. The open() statement would then process a string like
this:
(Result)
/path/to/nslookup cwe.mitre.org ; /bin/ls -l
As a result, the attacker executes the "/bin/ls -l" command and gets a
list of all the files in the program's working directory. The input
could be replaced with much more dangerous commands, such as installing
a malicious program on the server.
Example 3
The example below reads the name of a shell script to execute from
the system properties. It is subject to the second variant of OS command
injection.
(Bad Code)
Example
Language: Java
String script = System.getProperty("SCRIPTNAME");
if (script != null)
System.exec(script);
If an attacker has control over this property, then he or she could
modify the property to point to a dangerous program.
Example 4
The following code is from a web application that allows users
access to an interface through which they can update their password on the
system. Part of the process for updating passwords in certain network
environments is to run a make command in the /var/yp directory, the code for
which is shown below.
(Bad Code)
Example
Language: Java
...
System.Runtime.getRuntime().exec("make");
...
The problem here is that the program does not specify an absolute path
for make and does not clean its environment prior to executing the call
to Runtime.exec(). If an attacker can modify the $PATH variable to point
to a malicious binary called make and cause the program to be executed
in their environment, then the malicious binary will be loaded instead
of the one intended. Because of the nature of the application, it runs
with the privileges necessary to perform system operations, which means
the attacker's make will now be run with these privileges, possibly
giving the attacker complete control of the system.
Example 5
In the example below, a method is used to transform geographic
coordinates from latitude and longitude format to UTM format. The method
gets the input coordinates from a user through a HTTP request and executes a
program local to the application server that performs the transformation.
The method passes the latitude and longitude coordinates as a command-line
option to the external program and will perform some processing to retrieve
the results of the transformation and return the resulting UTM coordinates.
(Bad Code)
Example
Language: Java
public String coordinateTransformLatLonToUTM(String
coordinates)
{
String utmCoords = null;
try {
String latlonCoords = coordinates;
Runtime rt = Runtime.getRuntime();
Process exec = rt.exec("cmd.exe /C latlon2utm.exe -" +
latlonCoords);
// process results of coordinate transform
// ...
}
catch(Exception e) {...}
return utmCoords;
}
However, the method does not verify that the contents of the
coordinates input parameter includes only correctly-formatted latitude
and longitude coordinates. If the input coordinates were not validated
prior to the call to this method, a malicious user could execute another
program local to the application server by appending '&'
followed by the command for another program to the end of the coordinate
string. The '&' instructs the Windows operating system to
execute another program.
Example 6
The following code is from an administrative web application
designed to allow users to kick off a backup of an Oracle database using a
batch-file wrapper around the rman utility and then run a cleanup.bat script
to delete some temporary files. The script rmanDB.bat accepts a single
command line parameter, which specifies what type of backup to perform.
Because access to the database is restricted, the application runs the
backup as a privileged user.
The problem here is that the program does not do any validation on the
backuptype parameter read from the user. Typically the Runtime.exec()
function will not execute multiple commands, but in this case the
program first runs the cmd.exe shell in order to run multiple commands
with a single call to Runtime.exec(). Once the shell is invoked, it will
happily execute multiple commands separated by two ampersands. If an
attacker passes a string of the form "& del c:\\dbms\\*.*", then
the application will execute this command along with the others
specified by the program. Because of the nature of the application, it
runs with the privileges necessary to interact with the database, which
means whatever command the attacker injects will run with those
privileges as well.
Language interpreter's mail function accepts another argument that is concatenated to a string used in a dangerous popen() call. Since there is no neutralization of this argument, both OS Command Injection (CWE-78) and Argument Injection (CWE-88) are possible.
Product allows remote users to execute arbitrary
commands by creating a file whose pathname contains shell
metacharacters.
Potential Mitigations
Phase: Architecture and Design
If at all possible, use library calls rather than external processes
to recreate the desired functionality.
Phases: Architecture and Design; Operation
Strategy: Sandbox or Jail
Run the code in a "jail" or similar sandbox environment that enforces
strict boundaries between the process and the operating system. This may
effectively restrict which files can be accessed in a particular
directory or which commands can be executed by the software.
OS-level examples include the Unix chroot jail, AppArmor, and SELinux.
In general, managed code may provide some protection. For example,
java.io.FilePermission in the Java SecurityManager allows the software
to specify restrictions on file operations.
This may not be a feasible solution, and it only limits the impact to
the operating system; the rest of the application may still be subject
to compromise.
Be careful to avoid CWE-243 and other weaknesses related to jails.
Effectiveness: Limited
The effectiveness of this mitigation depends on the prevention
capabilities of the specific sandbox or jail being used and might only
help to reduce the scope of an attack, such as restricting the attacker
to certain system calls or limiting the portion of the file system that
can be accessed.
Phase: Architecture and Design
Strategy: Identify and Reduce Attack Surface
For any data that will be used to generate a command to be executed,
keep as much of that data out of external control as possible. For
example, in web applications, this may require storing the data locally
in the session's state instead of sending it out to the client in a
hidden form field.
Phase: Architecture and Design
For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.
Phase: Architecture and Design
Strategy: Libraries or Frameworks
Use a vetted library or framework that does not allow this weakness to
occur or provides constructs that make this weakness easier to
avoid.
For example, consider using the ESAPI Encoding control [R.78.8] or a similar tool, library, or framework. These will help the programmer encode outputs in a manner less prone to error.
Phase: Implementation
Strategy: Output Encoding
While it is risky to use dynamically-generated query strings, code, or commands that mix control and data together, sometimes it may be unavoidable. Properly quote arguments and escape any special characters within those arguments. The most conservative approach is to escape or filter all characters that do not pass an extremely strict whitelist (such as everything that is not alphanumeric or white space). If some special characters are still needed, such as white space, wrap each argument in quotes after the escaping/filtering step. Be careful of argument injection (CWE-88).
Phase: Implementation
If the program to be executed allows arguments to be specified within
an input file or from standard input, then consider using that mode to
pass arguments instead of the command line.
Phase: Architecture and Design
Strategy: Parameterization
If available, use structured mechanisms that automatically enforce the
separation between data and code. These mechanisms may be able to
provide the relevant quoting, encoding, and validation automatically,
instead of relying on the developer to provide this capability at every
point where output is generated.
Some languages offer multiple functions that can be used to invoke
commands. Where possible, identify any function that invokes a command
shell using a single string, and replace it with a function that
requires individual arguments. These functions typically perform
appropriate quoting and filtering of arguments. For example, in C, the
system() function accepts a string that contains the entire command to
be executed, whereas execl(), execve(), and others require an array of
strings, one for each argument. In Windows, CreateProcess() only accepts
one command at a time. In Perl, if system() is provided with an array of
arguments, then it will quote each of the arguments.
Phase: Implementation
Strategy: Input Validation
Assume all input is malicious. Use an "accept known good" input
validation strategy, i.e., use a whitelist of acceptable inputs that
strictly conform to specifications. Reject any input that does not
strictly conform to specifications, or transform it into something that
does.
When performing input validation, consider all potentially relevant
properties, including length, type of input, the full range of
acceptable values, missing or extra inputs, syntax, consistency across
related fields, and conformance to business rules. As an example of
business rule logic, "boat" may be syntactically valid because it only
contains alphanumeric characters, but it is not valid if the input is
only expected to contain colors such as "red" or "blue."
Do not rely exclusively on looking for malicious or malformed inputs
(i.e., do not rely on a blacklist). A blacklist is likely to miss at
least one undesirable input, especially if the code's environment
changes. This can give attackers enough room to bypass the intended
validation. However, blacklists can be useful for detecting potential
attacks or determining which inputs are so malformed that they should be
rejected outright.
When constructing OS command strings, use stringent whitelists that
limit the character set based on the expected value of the parameter in
the request. This will indirectly limit the scope of an attack, but this
technique is less important than proper output encoding and
escaping.
Note that proper output encoding, escaping, and quoting is the most
effective solution for preventing OS command injection, although input
validation may provide some defense-in-depth. This is because it
effectively limits what will appear in output. Input validation will not
always prevent OS command injection, especially if you are required to
support free-form text fields that could contain arbitrary characters.
For example, when invoking a mail program, you might need to allow the
subject field to contain otherwise-dangerous inputs like ";" and
">" characters, which would need to be escaped or otherwise
handled. In this case, stripping the character might reduce the risk of
OS command injection, but it would produce incorrect behavior because
the subject field would not be recorded as the user intended. This might
seem to be a minor inconvenience, but it could be more important when
the program relies on well-structured subject lines in order to pass
messages to other components.
Even if you make a mistake in your validation (such as forgetting one
out of 100 input fields), appropriate encoding is still likely to
protect you from injection-based attacks. As long as it is not done in
isolation, input validation is still a useful technique, since it may
significantly reduce your attack surface, allow you to detect some
attacks, and provide other security benefits that proper encoding does
not address.
Phase: Architecture and Design
Strategy: Enforcement by Conversion
When the set of acceptable objects, such as filenames or URLs, is
limited or known, create a mapping from a set of fixed input values
(such as numeric IDs) to the actual filenames or URLs, and reject all
other inputs.
Phase: Operation
Strategies: Compilation or Build Hardening; Environment Hardening
Run the code in an environment that performs automatic taint propagation and prevents any command execution that uses tainted variables, such as Perl's "-T" switch. This will force the program to perform validation steps that remove the taint, although you must be careful to correctly validate your inputs so that you do not accidentally mark dangerous inputs as untainted (see CWE-183 and CWE-184).
Phase: Implementation
Ensure that error messages only contain minimal details that are
useful to the intended audience, and nobody else. The messages need to
strike the balance between being too cryptic and not being cryptic
enough. They should not necessarily reveal the methods that were used to
determine the error. Such detailed information can be used to refine the
original attack to increase the chances of success.
If errors must be tracked in some detail, capture them in log messages
- but consider what could occur if the log messages can be viewed by
attackers. Avoid recording highly sensitive information such as
passwords in any form. Avoid inconsistent messaging that might
accidentally tip off an attacker about internal state, such as whether a
username is valid or not.
In the context of OS Command Injection, error information passed back
to the user might reveal whether an OS command is being executed and
possibly which command is being used.
Phase: Operation
Strategy: Sandbox or Jail
Use runtime policy enforcement to create a whitelist of allowable
commands, then prevent use of any command that does not appear in the
whitelist. Technologies such as AppArmor are available to do
this.
Phase: Operation
Strategy: Firewall
Use an application firewall that can detect attacks against this
weakness. It can be beneficial in cases in which the code cannot be
fixed (because it is controlled by a third party), as an emergency
prevention measure while more comprehensive software assurance measures
are applied, or to provide defense in depth.
Effectiveness: Moderate
An application firewall might not cover all possible input vectors. In
addition, attack techniques might be available to bypass the protection
mechanism, such as using malformed inputs that can still be processed by
the component that receives those inputs. Depending on functionality, an
application firewall might inadvertently reject or modify legitimate
requests. Finally, some manual effort may be required for
customization.
Phases: Architecture and Design; Operation
Strategy: Environment Hardening
Run your code using the lowest privileges that are required to accomplish the necessary tasks [R.78.9]. If possible, create isolated accounts with limited privileges that are only used for a single task. That way, a successful attack will not immediately give the attacker access to the rest of the software or its environment. For example, database applications rarely need to run as the database administrator, especially in day-to-day operations.
Phases: Operation; Implementation
Strategy: Environment Hardening
When using PHP, configure the application so that it does not use register_globals. During implementation, develop the application so that it does not rely on this feature, but be wary of implementing a register_globals emulation that is subject to weaknesses such as CWE-95, CWE-621, and similar issues.
More investigation is needed into the distinction between the OS command injection variants, including the role with argument injection (CWE-88). Equivalent distinctions may exist in other injection-related problems such as SQL injection.
Affected Resources
System Process
Functional Areas
Program invocation
Taxonomy Mappings
Mapped Taxonomy Name
Node ID
Fit
Mapped Node Name
PLOVER
OS Command Injection
OWASP Top Ten 2007
A3
CWE_More_Specific
Malicious File Execution
OWASP Top Ten 2004
A6
CWE_More_Specific
Injection Flaws
CERT C Secure Coding
ENV03-C
Sanitize the environment when invoking external
programs
CERT C Secure Coding
ENV04-C
Do not call system() if you do not need a command
processor
CERT C Secure Coding
STR02-C
Sanitize data passed to complex subsystems
WASC
31
OS Commanding
CERT Java Secure Coding
IDS07-J
Do not pass untrusted, unsanitized data to the Runtime.exec()
method
CERT C++ Secure Coding
STR02-CPP
Sanitize data passed to complex subsystems
CERT C++ Secure Coding
ENV03-CPP
Sanitize the environment when invoking external
programs
CERT C++ Secure Coding
ENV04-CPP
Do not call system() if you do not need a command
processor
[R.78.6] [REF-17] Michael Howard, David LeBlanc
and John Viega. "24 Deadly Sins of Software Security". "Sin 10: Command Injection." Page 171. McGraw-Hill. 2010.
[R.78.10] [REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 8, "Shell Metacharacters", Page
425.. 1st Edition. Addison Wesley. 2006.
Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
Definition in a New Window
Weakness ID: 89 (Weakness Base)
Status: Draft
Description
Description Summary
The software constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.
Extended Description
Without sufficient removal or quoting of SQL syntax in user-controllable inputs, the generated SQL query can cause those inputs to be interpreted as SQL instead of ordinary user data. This can be used to alter query logic to bypass security checks, or to insert additional statements that modify the back-end database, possibly including execution of system commands.
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. This flaw depends on the fact that SQL makes no real distinction between the control and data planes.
Time of Introduction
Architecture and Design
Implementation
Operation
Applicable Platforms
Languages
All
Technology Classes
Database-Server
Modes of Introduction
This weakness typically appears in data-rich applications that save user
inputs in a database.
Common Consequences
Scope
Effect
Confidentiality
Technical Impact: Read application
data
Since SQL databases generally hold sensitive data, loss of
confidentiality is a frequent problem with SQL injection
vulnerabilities.
Access Control
Technical Impact: Bypass protection
mechanism
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.
Access Control
Technical Impact: Bypass protection
mechanism
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
Technical Impact: Modify application
data
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.
Likelihood of Exploit
Very High
Enabling Factors for Exploitation
The application dynamically generates queries that contain user
input.
Detection Methods
Automated Static Analysis
This weakness can often be detected using automated static analysis
tools. Many modern tools use data flow analysis or constraint-based
techniques to minimize the number of false positives.
Automated static analysis might not be able to recognize when proper
input validation is being performed, leading to false positives - i.e.,
warnings that do not have any security consequences or do not require
any code changes.
Automated static analysis might not be able to detect the usage of
custom API functions or third-party libraries that indirectly invoke SQL
commands, leading to false negatives - especially if the API/library
code is not available for analysis.
This is not a perfect solution, since 100% accuracy and coverage are
not feasible.
Automated Dynamic Analysis
This weakness can be detected using dynamic tools and techniques that
interact with the software using large test suites with many diverse
inputs, such as fuzz testing (fuzzing), robustness testing, and fault
injection. The software's operation may slow down, but it should not
become unstable, crash, or generate incorrect results.
Effectiveness: Moderate
Manual Analysis
Manual analysis can be useful for finding this weakness, but it might
not achieve desired code coverage within limited time constraints. This
becomes difficult for weaknesses that must be considered for all inputs,
since the attack surface can be too large.
Demonstrative Examples
Example 1
In 2008, a large number of web servers were compromised using the
same SQL injection attack string. This single string worked against many
different programs. The SQL injection was then used to modify the web sites
to serve malicious code. [1]
Example 2
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.
(Bad Code)
Example
Language: C#
...
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:
(Attack)
name' OR 'a'='a
for itemName, then the query becomes the following:
(Attack)
SELECT * FROM items WHERE owner = 'wiley' AND itemname = 'name' OR
'a'='a';
The addition of the:
(Attack)
OR 'a'='a'
condition causes the WHERE clause to always evaluate to true, so the
query becomes logically equivalent to the much simpler query:
(Attack)
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.
Example 3
This example examines the effects of a different malicious value
passed to the query constructed and executed in the previous
example.
If an attacker with the user name wiley enters the string:
(Attack)
name'; DELETE FROM items; --
for itemName, then the query becomes the following two queries:
(Attack)
Example
Language: SQL
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. 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 the previous example.
If an attacker enters the string
(Attack)
name'; DELETE FROM items; SELECT * FROM items WHERE 'a'='a
Then the following three valid statements will be created:
(Attack)
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 do not protect against many
others. For example, the following PL/SQL procedure is vulnerable to the
same SQL injection attack shown in the first example.
(Bad Code)
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.
Example 4
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:
(Bad Code)
SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='$user_input'
ORDER BY PRICE
Where $user_input is taken from an untrusted source.
If the user provides the string:
(Attack)
'; exec master..xp_cmdshell 'dir' --
The query will take the following form:
(Attack)
SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=''; exec
master..xp_cmdshell 'dir' --' ORDER BY PRICE
Now, this query can be broken down into:
a first SQL query: SELECT ITEM,PRICE FROM PRODUCT WHERE
ITEM_CATEGORY='';
a second SQL query, which executes the dir command in the shell:
exec master..xp_cmdshell 'dir'
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.
Example 5
This code intends to print a message summary given the message
ID.
(Bad Code)
Example
Language: PHP
$id = $_COOKIE["mid"];
mysql_query("SELECT MessageID, Subject FROM messages WHERE
MessageID = '$id'");
The programmer may have skipped any input validation on $id under the
assumption that attackers cannot modify the cookie. However, this is
easy to do with custom client code or even in the web browser.
While $id is wrapped in single quotes in the call to mysql_query(), an
attacker could simply change the incoming mid cookie to:
(Attack)
1432' or '1' = '1
This would produce the resulting query:
(Result)
SELECT MessageID, Subject FROM messages WHERE MessageID = '1432'
or '1' = '1'
Not only will this retrieve message number 1432, it will retrieve all
other messages.
In this case, the programmer could apply a simple modification to the
code to eliminate the SQL injection:
(Good Code)
Example
Language: PHP
$id = intval($_COOKIE["mid"]);
mysql_query("SELECT MessageID, Subject FROM messages WHERE
MessageID = '$id'");
However, if this code is intended to support multiple users with different message boxes, the code might also need an access control check (CWE-285) to ensure that the application user has the permission to see that message.
Example 6
This example attempts to take a last name provided by a user and
enter it into a database.
(Bad Code)
Example
Language: Perl
$userKey = getUserID();
$name = getUserInput();
# ensure only letters, hyphens and apostrophe are
allowed
$name = whiteList($name, "^a-zA-z'-$");
$query = "INSERT INTO last_names VALUES('$userKey',
'$name')";
While the programmer applies a whitelist to the user input, it has
shortcomings. First of all, the user is still allowed to provide hyphens
which are used as comment structures in SQL. If a user specifies -- then
the remainder of the statement will be treated as a comment, which may
bypass security logic. Furthermore, the whitelist permits the apostrophe
which is also a data / command separator in SQL. If a user supplies a
name with an apostrophe, they may be able to alter the structure of the
whole statement and even change control flow of the program, possibly
accessing or modifying confidential information. In this situation, both
the hyphen and apostrophe are legitimate characters for a last name and
permitting them is required. Instead, a programmer may want to use a
prepared statement or apply an encoding routine to the input to prevent
any data / directive misinterpretations.
Use a vetted library or framework that does not allow this weakness to
occur or provides constructs that make this weakness easier to
avoid.
For example, consider using persistence layers such as Hibernate or
Enterprise Java Beans, which can provide significant protection against
SQL injection if used properly.
Phase: Architecture and Design
Strategy: Parameterization
If available, use structured mechanisms that automatically enforce the
separation between data and code. These mechanisms may be able to
provide the relevant quoting, encoding, and validation automatically,
instead of relying on the developer to provide this capability at every
point where output is generated.
Process SQL queries using prepared statements, parameterized queries, or stored procedures. These features should accept parameters or variables and support strong typing. Do not dynamically construct and execute query strings within these features using "exec" or similar functionality, since this may re-introduce the possibility of SQL injection. [R.89.3]
Phases: Architecture and Design; Operation
Strategy: Environment Hardening
Run your code using the lowest privileges that are required to accomplish the necessary tasks [R.89.12]. If possible, create isolated accounts with limited privileges that are only used for a single task. That way, a successful attack will not immediately give the attacker access to the rest of the software or its environment. For example, database applications rarely need to run as the database administrator, especially in day-to-day operations.
Specifically, follow the principle of least privilege when creating
user accounts to a SQL database. The 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. Use
the strictest permissions possible on all database objects, such as
execute-only for stored procedures.
Phase: Architecture and Design
For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.
Phase: Implementation
Strategy: Output Encoding
While it is risky to use dynamically-generated query strings, code, or commands that mix control and data together, sometimes it may be unavoidable. Properly quote arguments and escape any special characters within those arguments. The most conservative approach is to escape or filter all characters that do not pass an extremely strict whitelist (such as everything that is not alphanumeric or white space). If some special characters are still needed, such as white space, wrap each argument in quotes after the escaping/filtering step. Be careful of argument injection (CWE-88).
Instead of building a new implementation, such features may be
available in the database or programming language. For example, the
Oracle DBMS_ASSERT package can check or enforce that parameters have
certain properties that make them less vulnerable to SQL injection. For
MySQL, the mysql_real_escape_string() API function is available in both
C and PHP.
Phase: Implementation
Strategy: Input Validation
Assume all input is malicious. Use an "accept known good" input
validation strategy, i.e., use a whitelist of acceptable inputs that
strictly conform to specifications. Reject any input that does not
strictly conform to specifications, or transform it into something that
does.
When performing input validation, consider all potentially relevant
properties, including length, type of input, the full range of
acceptable values, missing or extra inputs, syntax, consistency across
related fields, and conformance to business rules. As an example of
business rule logic, "boat" may be syntactically valid because it only
contains alphanumeric characters, but it is not valid if the input is
only expected to contain colors such as "red" or "blue."
Do not rely exclusively on looking for malicious or malformed inputs
(i.e., do not rely on a blacklist). A blacklist is likely to miss at
least one undesirable input, especially if the code's environment
changes. This can give attackers enough room to bypass the intended
validation. However, blacklists can be useful for detecting potential
attacks or determining which inputs are so malformed that they should be
rejected outright.
When constructing SQL query strings, use stringent whitelists that
limit the character set based on the expected value of the parameter in
the request. This will indirectly limit the scope of an attack, but this
technique is less important than proper output encoding and
escaping.
Note that proper output encoding, escaping, and quoting is the most
effective solution for preventing SQL injection, although input
validation may provide some defense-in-depth. This is because it
effectively limits what will appear in output. Input validation will not
always prevent SQL injection, especially if you are required to support
free-form text fields that could contain arbitrary characters. For
example, the name "O'Reilly" would likely pass the validation step,
since it is a common last name in the English language. However, it
cannot be directly inserted into the database because it contains the
"'" apostrophe character, which would need to be escaped or otherwise
handled. In this case, stripping the apostrophe might reduce the risk of
SQL injection, but it would produce incorrect behavior because the wrong
name would be recorded.
When feasible, it may be safest to disallow meta-characters entirely,
instead of escaping them. This will provide some defense in depth. After
the data is entered into the database, later processes may neglect to
escape meta-characters before use, and you may not have control over
those processes.
Phase: Architecture and Design
Strategy: Enforcement by Conversion
When the set of acceptable objects, such as filenames or URLs, is
limited or known, create a mapping from a set of fixed input values
(such as numeric IDs) to the actual filenames or URLs, and reject all
other inputs.
Phase: Implementation
Ensure that error messages only contain minimal details that are
useful to the intended audience, and nobody else. The messages need to
strike the balance between being too cryptic and not being cryptic
enough. They should not necessarily reveal the methods that were used to
determine the error. Such detailed information can be used to refine the
original attack to increase the chances of success.
If errors must be tracked in some detail, capture them in log messages
- but consider what could occur if the log messages can be viewed by
attackers. Avoid recording highly sensitive information such as
passwords in any form. Avoid inconsistent messaging that might
accidentally tip off an attacker about internal state, such as whether a
username is valid or not.
In the context of SQL Injection, error messages revealing the
structure of a SQL query can help attackers tailor successful attack
strings.
Phase: Operation
Strategy: Firewall
Use an application firewall that can detect attacks against this
weakness. It can be beneficial in cases in which the code cannot be
fixed (because it is controlled by a third party), as an emergency
prevention measure while more comprehensive software assurance measures
are applied, or to provide defense in depth.
Effectiveness: Moderate
An application firewall might not cover all possible input vectors. In
addition, attack techniques might be available to bypass the protection
mechanism, such as using malformed inputs that can still be processed by
the component that receives those inputs. Depending on functionality, an
application firewall might inadvertently reject or modify legitimate
requests. Finally, some manual effort may be required for
customization.
Phases: Operation; Implementation
Strategy: Environment Hardening
When using PHP, configure the application so that it does not use register_globals. During implementation, develop the application so that it does not rely on this feature, but be wary of implementing a register_globals emulation that is subject to weaknesses such as CWE-95, CWE-621, and similar issues.
SQL injection can be resultant from special character mismanagement, MAID,
or blacklist/whitelist problems. It can be primary to authentication
errors.
2. end statement that performs an SQL command where
a. the input is part of the SQL command and
b. input contains SQL syntax (esp. query separator)
References
[R.89.1] [REF-17] Michael Howard, David LeBlanc
and John Viega. "24 Deadly Sins of Software Security". "Sin 1: SQL Injection." Page 3. McGraw-Hill. 2010.
[R.89.2] [REF-11] M. Howard and
D. LeBlanc. "Writing Secure Code". Chapter 12, "Database Input Issues" Page
397. 2nd Edition. Microsoft. 2002.
[R.89.6] David Litchfield, Chris Anley, John Heasman
and Bill Grindlay. "The Database Hacker's Handbook: Defending Database
Servers". Wiley. 2005-07-14.
[R.89.7] David Litchfield. "The Oracle Hacker's Handbook: Hacking and Defending
Oracle". Wiley. 2007-01-30.
[R.89.13] [REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 8, "SQL Queries", Page 431.. 1st Edition. Addison Wesley. 2006.
[REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 17, "SQL Injection", Page 1061.. 1st Edition. Addison Wesley. 2006.
Improper Restriction of Excessive Authentication Attempts
Definition in a New Window
Weakness ID: 307 (Weakness Base)
Status: Draft
Description
Description Summary
The software does not implement sufficient measures to prevent multiple failed authentication attempts within in a short time frame, making it more susceptible to brute force attacks.
Time of Introduction
Architecture and Design
Applicable Platforms
Languages
Language-independent
Common Consequences
Scope
Effect
Access Control
Technical Impact: Bypass protection
mechanism
An attacker could perform an arbitrary number of authentication
attempts using different passwords, and eventually gain access to the
targeted account.
Demonstrative Examples
Example 1
In January 2009, an attacker was able to gain administrator access
to a Twitter server because the server did not restrict the number of login
attempts. The attacker targeted a member of Twitter's support team and was
able to successfully guess the member's password using a brute force attack
by guessing a large number of common words. Once the attacker gained access
as the member of the support staff, he used the administrator panel to gain
access to 33 accounts that belonged to celebrities and politicians.
Ultimately, fake Twitter messages were sent that appeared to come from the
compromised accounts.
However, there is no limit on parallel connections, so this does not
increase the amount of time an attacker needs to complete an
attack.
Example 4
In the following C/C++ example the validateUser method opens a
socket connection, reads a username and password from the socket and
attempts to authenticate the username and password.
(Bad Code)
Example Languages: C and C++
int validateUser(char *host, int port)
{
int socket = openSocketConnection(host, port);
if (socket < 0) {
printf("Unable to open socket connection");
return(FAIL);
}
int isValidUser = 0;
char username[USERNAME_SIZE];
char password[PASSWORD_SIZE];
while (isValidUser == 0) {
if (getNextMessage(socket, username, USERNAME_SIZE)
> 0) {
if (getNextMessage(socket, password, PASSWORD_SIZE)
> 0) {
The validateUser method will continuously check for a valid username
and password without any restriction on the number of authentication
attempts made. The method should limit the number of authentication
attempts made to prevent brute force attacks as in the following example
code.
(Good Code)
Example Languages: C and C++
int validateUser(char *host, int port)
{
...
int count = 0;
while ((isValidUser == 0) && (count <
MAX_ATTEMPTS)) {
if (getNextMessage(socket, username, USERNAME_SIZE)
> 0) {
if (getNextMessage(socket, password, PASSWORD_SIZE)
> 0) {
The product uses untrusted input when calculating or using an array index, but the product does not validate or incorrectly validates the index to ensure the index references a valid position within the array.
Alternate Terms
out-of-bounds array index
index-out-of-range
array index underflow
Time of Introduction
Implementation
Applicable Platforms
Languages
C: (Often)
C++: (Often)
Language-independent
Common Consequences
Scope
Effect
Integrity
Availability
Technical Impact: DoS: crash / exit /
restart
Use of an index that is outside the bounds of an array will very
likely result in the corruption of relevant memory and perhaps
instructions, leading to a crash, if the values are outside of the valid
memory area.
Integrity
Technical Impact: Modify memory
If the memory corrupted is data, rather than instructions, the system
will continue to function with improper values.
Confidentiality
Integrity
Technical Impact: Modify memory; Read memory
Use of an index that is outside the bounds of an array can also
trigger out-of-bounds read or write operations, or operations on the
wrong objects; i.e., "buffer overflows" are not always the result. This
may result in the exposure or modification of sensitive data.
Integrity
Confidentiality
Availability
Technical Impact: Execute unauthorized code or
commands
If the memory accessible by the attacker can be effectively
controlled, it may be possible to execute arbitrary code, as with a
standard buffer overflow and possibly without the use of large inputs if
a precise index can be controlled.
A single fault could allow either an overflow (CWE-788) or underflow (CWE-786) of the array index. What happens next will depend on the type of operation being performed out of bounds, but can expose sensitive information, cause a system crash, or possibly lead to arbitrary code execution.
Likelihood of Exploit
High
Detection Methods
Automated Static Analysis
This weakness can often be detected using automated static analysis
tools. Many modern tools use data flow analysis or constraint-based
techniques to minimize the number of false positives.
Automated static analysis generally does not account for environmental
considerations when reporting out-of-bounds memory operations. This can
make it difficult for users to determine which warnings should be
investigated first. For example, an analysis tool might report array
index errors that originate from command line arguments in a program
that is not expected to run with setuid or other special
privileges.
Effectiveness: High
This is not a perfect solution, since 100% accuracy and coverage are
not feasible.
Automated Dynamic Analysis
This weakness can be detected using dynamic tools and techniques that
interact with the software using large test suites with many diverse
inputs, such as fuzz testing (fuzzing), robustness testing, and fault
injection. The software's operation may slow down, but it should not
become unstable, crash, or generate incorrect results.
Black Box
Black box methods might not get the needed code coverage within
limited time constraints, and a dynamic test might not produce any
noticeable side effects even if it is successful.
Demonstrative Examples
Example 1
In the code snippet below, an untrusted integer value is used to
reference an object in an array.
(Bad Code)
Example
Language: Java
public String getValue(int index) {
return array[index];
}
If index is outside of the range of the array, this may result in an
ArrayIndexOutOfBounds Exception being raised.
Example 2
The following example takes a user-supplied value to allocate an
array of objects and then operates on the array.
(Bad Code)
Example
Language: Java
private void buildList ( int untrustedListSize ){
if ( 0 > untrustedListSize ){
die("Negative value supplied for list size, die evil
hacker!");
}
Widget[] list = new Widget [ untrustedListSize ];
list[0] = new Widget();
}
This example attempts to build a list from a user-specified value, and
even checks to ensure a non-negative value is supplied. If, however, a 0
value is provided, the code will build an array of size 0 and then try
to store a new Widget in the first location, causing an exception to be
thrown.
Example 3
In the following code, the method retrieves a value from an array at
a specific array index location that is given as an input parameter to the
method
(Bad Code)
Example
Language: C
int getValueFromArray(int *array, int len, int index) {
int value;
// check that the array index is less than the
maximum
// length of the array
if (index < len) {
// get the value at the specified index of the
array
value = array[index];
}
// if array index is invalid then output error
message
// and return value indicating error
else {
printf("Value is: %d\n", array[index]);
value = -1;
}
return value;
}
However, this method only verifies that the given array index is less than the maximum length of the array but does not check for the minimum value (CWE-839). This will allow a negative value to be accepted as the input array index, which will result in a out of bounds read (CWE-125) and may allow access to sensitive memory. The input array index should be checked to verify that is within the maximum and minimum range required for the array (CWE-129). In this example the if statement should be modified to include a minimum range check, as shown below.
(Good Code)
Example
Language: C
...
// check that the array index is within the correct
// range of values for the array
if (index <= 0 && index < len)
{
...
Example 4
The following example retrieves the sizes of messages for a pop3
mail server. The message sizes are retrieved from a socket that returns in a
buffer the message number and the message size, the message number (num) and
size (size) are extracted from the buffer and the message size is placed
into an array using the message number for the array index.
(Bad Code)
Example
Language: C
/* capture the sizes of all messages */
int getsizes(int sock, int count, int *sizes) {
...
char buf[BUFFER_SIZE];
int ok;
int num, size;
// read values from socket and added to sizes
array
while ((ok = gen_recv(sock, buf, sizeof(buf))) == 0)
{
// continue read from socket until buf only contains
'.'
if (DOTLINE(buf))
break;
else if (sscanf(buf, "%d %d", &num, &size)
== 2)
sizes[num - 1] = size;
}
...
}
In this example the message number retrieved from the buffer could be
a value that is outside the allowable range of indices for the array and
could possibly be a negative number. Without proper validation of the
value to be used for the array index an array overflow could occur and
could potentially lead to unauthorized access to memory addresses and
system crashes. The value of the array index should be validated to
ensure that it is within the allowable range of indices for the array as
in the following code.
(Good Code)
Example
Language: C
/* capture the sizes of all messages */
int getsizes(int sock, int count, int *sizes) {
...
char buf[BUFFER_SIZE];
int ok;
int num, size;
// read values from socket and added to sizes
array
while ((ok = gen_recv(sock, buf, sizeof(buf))) == 0)
{
// continue read from socket until buf only contains
'.'
if (DOTLINE(buf))
break;
else if (sscanf(buf, "%d %d", &num, &size)
== 2) {
if (num > 0 && num <=
(unsigned)count)
sizes[num - 1] = size;
else
/* warn about possible attempt to induce buffer
overflow */
report(stderr, "Warning: ignoring bogus data for
message sizes returned by server.\n");
}
}
...
}
Example 5
In the following example the method displayProductSummary is called
from a Web service servlet to retrieve product summary information for
display to the user. The servlet obtains the integer value of the product
number from the user and passes it to the displayProductSummary method. The
displayProductSummary method passes the integer value of the product number
to the getProductSummary method which obtains the product summary from the
array object containing the project summaries using the integer value of the
product number as the array index.
(Bad Code)
Example
Language: Java
// Method called from servlet to obtain product
information
public String displayProductSummary(int index) {
String productSummary = new String("");
try {
String productSummary = getProductSummary(index);
} catch (Exception ex) {...}
return productSummary;
}
public String getProductSummary(int index) {
return products[index];
}
In this example the integer value used as the array index that is
provided by the user may be outside the allowable range of indices for
the array which may provide unexpected results or cause the application
to fail. The integer value used for the array index should be validated
to ensure that it is within the allowable range of indices for the array
as in the following code.
(Good Code)
Example
Language: Java
// Method called from servlet to obtain product
information
public String displayProductSummary(int index) {
String productSummary = new String("");
try {
String productSummary = getProductSummary(index);
} catch (Exception ex) {...}
return productSummary;
}
public String getProductSummary(int index) {
String productSummary = "";
if ((index >= 0) && (index <
MAX_PRODUCTS)) {
productSummary = products[index];
}
else {
System.err.println("index is out of bounds");
throw new IndexOutOfBoundsException();
}
return productSummary;
}
An alternative in Java would be to use one of the collection objects
such as ArrayList that will automatically generate an exception if an
attempt is made to access an array index that is out of bounds.
(Good Code)
Example
Language: Java
ArrayList productArray = new ArrayList(MAX_PRODUCTS);
The programmer allows the user to specify which element in the list to select, however an attacker can provide an out-of-bounds offset, resulting in a buffer over-read (CWE-126).
Chain: array index error (CWE-129) leads to deadlock (CWE-833)
Potential Mitigations
Phase: Architecture and Design
Strategies: Input Validation; Libraries or Frameworks
Use an input validation framework such as Struts or the OWASP ESAPI Validation API. If you use Struts, be mindful of weaknesses covered by the CWE-101 category.
Phase: Architecture and Design
For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.
Even though client-side checks provide minimal benefits with respect
to server-side security, they are still useful. First, they can support
intrusion detection. If the server receives input that should have been
rejected by the client, then it may be an indication of an attack.
Second, client-side error-checking can provide helpful feedback to the
user about the expectations for valid input. Third, there may be a
reduction in server-side processing time for accidental input errors,
although this is typically a small savings.
Phase: Requirements
Strategy: Language Selection
Use a language that does not allow this weakness to occur or provides
constructs that make this weakness easier to avoid.
For example, Ada allows the programmer to constrain the values of a
variable and languages such as Java and Ruby will allow the programmer
to handle exceptions when an out-of-bounds index is accessed.
Phase: Operation
Strategy: Environment Hardening
Use a feature like Address Space Layout Randomization (ASLR) [R.129.3] [R.129.4].
Effectiveness: Defense in Depth
This is not a complete solution. However, it forces the attacker to
guess an unknown value that changes every program execution. In
addition, an attack could still cause a denial of service, since the
typical response is to exit the application.
Phase: Operation
Strategy: Environment Hardening
Use a CPU and operating system that offers Data Execution Protection (NX) or its equivalent [R.129.4] [R.129.5].
Effectiveness: Defense in Depth
This is not a complete solution, since buffer overflows could be used
to overwrite nearby variables to modify the software's state in
dangerous ways. In addition, it cannot be used in cases in which
self-modifying code is required. Finally, an attack could still cause a
denial of service, since the typical response is to exit the
application.
Phase: Implementation
Strategy: Input Validation
Assume all input is malicious. Use an "accept known good" input
validation strategy, i.e., use a whitelist of acceptable inputs that
strictly conform to specifications. Reject any input that does not
strictly conform to specifications, or transform it into something that
does.
When performing input validation, consider all potentially relevant
properties, including length, type of input, the full range of
acceptable values, missing or extra inputs, syntax, consistency across
related fields, and conformance to business rules. As an example of
business rule logic, "boat" may be syntactically valid because it only
contains alphanumeric characters, but it is not valid if the input is
only expected to contain colors such as "red" or "blue."
Do not rely exclusively on looking for malicious or malformed inputs
(i.e., do not rely on a blacklist). A blacklist is likely to miss at
least one undesirable input, especially if the code's environment
changes. This can give attackers enough room to bypass the intended
validation. However, blacklists can be useful for detecting potential
attacks or determining which inputs are so malformed that they should be
rejected outright.
When accessing a user-controlled array index, use a stringent range of
values that are within the target array. Make sure that you do not allow
negative values to be used. That is, verify the minimum as well as the
maximum of the range of acceptable values.
Phase: Implementation
Be especially careful to validate all input when invoking code that
crosses language boundaries, such as from an interpreted language to
native code. This could create an unexpected interaction between the
language boundaries. Ensure that you are not violating any of the
expectations of the language with which you are interfacing. For
example, even though Java may not be susceptible to buffer overflows,
providing a large argument in a call to native code might trigger an
overflow.
Phases: Architecture and Design; Operation
Strategy: Environment Hardening
Run your code using the lowest privileges that are required to accomplish the necessary tasks [R.129.6]. If possible, create isolated accounts with limited privileges that are only used for a single task. That way, a successful attack will not immediately give the attacker access to the rest of the software or its environment. For example, database applications rarely need to run as the database administrator, especially in day-to-day operations.
Phases: Architecture and Design; Operation
Strategy: Sandbox or Jail
Run the code in a "jail" or similar sandbox environment that enforces
strict boundaries between the process and the operating system. This may
effectively restrict which files can be accessed in a particular
directory or which commands can be executed by the software.
OS-level examples include the Unix chroot jail, AppArmor, and SELinux.
In general, managed code may provide some protection. For example,
java.io.FilePermission in the Java SecurityManager allows the software
to specify restrictions on file operations.
This may not be a feasible solution, and it only limits the impact to
the operating system; the rest of the application may still be subject
to compromise.
Be careful to avoid CWE-243 and other weaknesses related to jails.
Effectiveness: Limited
The effectiveness of this mitigation depends on the prevention
capabilities of the specific sandbox or jail being used and might only
help to reduce the scope of an attack, such as restricting the attacker
to certain system calls or limiting the portion of the file system that
can be accessed.
Weakness Ordinalities
Ordinality
Description
Resultant
The most common condition situation leading to an out-of-bounds array
index is the use of loop index variables as buffer indexes. If the end
condition for the loop is subject to a flaw, the index can grow or
shrink unbounded, therefore causing a buffer overflow or underflow.
Another common situation leading to this condition is the use of a
function's return value, or the resulting value of a calculation
directly as an index in to a buffer.
This weakness can precede uncontrolled memory allocation (CWE-789) in languages that automatically expand an array when an index is used that is larger than the size of the array, such as JavaScript.
Theoretical Notes
An improperly validated array index might lead directly to the
always-incorrect behavior of "access of array using out-of-bounds index."
Affected Resources
Memory
Causal Nature
Explicit
Taxonomy Mappings
Mapped Taxonomy Name
Node ID
Fit
Mapped Node Name
CLASP
Unchecked array indexing
PLOVER
INDEX - Array index overflow
CERT C Secure Coding
ARR00-C
Understand how arrays work
CERT C Secure Coding
ARR30-C
Guarantee that array indices are within the valid
range
CERT C Secure Coding
ARR38-C
Do not add or subtract an integer to a pointer if the
resulting value does not refer to a valid array element
CERT C Secure Coding
INT32-C
Ensure that operations on signed integers do not result in
overflow
CERT C++ Secure Coding
INT10-CPP
Do not assume a positive remainder when using the %
operator
CERT C++ Secure Coding
INT32-CPP
Ensure that operations on signed integers do not result in
overflow
CERT C++ Secure Coding
ARR00-CPP
Understand when to prefer vectors over
arrays
CERT C++ Secure Coding
ARR30-CPP
Guarantee that array and vector indices are within the valid
range
CERT C++ Secure Coding
ARR38-CPP
Do not add or subtract an integer to a pointer or iterator if
the resulting value does not refer to a valid element in the array or
container
[R.129.7] [REF-17] Michael Howard, David LeBlanc
and John Viega. "24 Deadly Sins of Software Security". "Sin 5: Buffer Overruns." Page 89. McGraw-Hill. 2010.
If the incorrect calculation is used in the context of memory allocation, then the software may create a buffer that is smaller or larger than expected. If the allocated buffer is smaller than expected, this could lead to an out-of-bounds read or write (CWE-119), possibly causing a crash, allowing arbitrary code execution, or exposing sensitive data.
Likelihood of Exploit
High to Very High
Detection Methods
Automated Static Analysis
This weakness can often be detected using automated static analysis
tools. Many modern tools use data flow analysis or constraint-based
techniques to minimize the number of false positives.
Automated static analysis generally does not account for environmental
considerations when reporting potential errors in buffer calculations.
This can make it difficult for users to determine which warnings should
be investigated first. For example, an analysis tool might report buffer
overflows that originate from command line arguments in a program that
is not expected to run with setuid or other special privileges.
Effectiveness: High
Detection techniques for buffer-related errors are more mature than
for most other weakness types.
Automated Dynamic Analysis
This weakness can be detected using dynamic tools and techniques that
interact with the software using large test suites with many diverse
inputs, such as fuzz testing (fuzzing), robustness testing, and fault
injection. The software's operation may slow down, but it should not
become unstable, crash, or generate incorrect results.
Effectiveness: Moderate
Without visibility into the code, black box methods may not be able to
sufficiently distinguish this weakness from others, requiring follow-up
manual methods to diagnose the underlying problem.
Manual Analysis
Manual analysis can be useful for finding this weakness, but it might
not achieve desired code coverage within limited time constraints. This
becomes difficult for weaknesses that must be considered for all inputs,
since the attack surface can be too large.
Manual Analysis
This weakness can be detected using tools and techniques that require
manual (human) analysis, such as penetration testing, threat modeling,
and interactive tools that allow the tester to record and modify an
active session.
Specifically, manual static analysis is useful for evaluating the correctness of allocation calculations. This can be useful for detecting overflow conditions (CWE-190) or similar weaknesses that might have serious security impacts on the program.
Effectiveness: High
These may be more effective than strictly automated techniques. This
is especially the case with weaknesses that are related to design and
business rules.