Weaknesses in the 2011 CWE/SANS Top 25 Most Dangerous Software Errors
Definition in a New Window
View ID: 900 (View: Graph)
Status: Incomplete
View Data
View Objective
CWE entries in this view (graph) are listed in the 2011 CWE/SANS Top 25 Most Dangerous Software Errors.
View Metrics
CWEs in this view
Total CWEs
Total
45
out of
909
Views
0
out of
29
Categories
4
out of
178
Weaknesses
40
out of
693
Compound_Elements
1
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. Do not rely exclusively on looking for malicious or malformed
inputs (i.e., do not rely on a blacklist). However, blacklists can be
useful for detecting potential attacks or determining which inputs are
so malformed that they should be rejected outright.
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 you are
expecting colors such as "red" or "blue."
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.
Phase: Implementation
For system resources when using C, consider using the getrlimit()
function included in the sys/resources library in order to determine how
many files are currently allowed to be opened for the process.
Phase: Operation
Use resource-limiting settings provided by the operating system or
environment. For example, setrlimit() can be used to set limits for
certain types of resources. However, this is not available on all
operating systems.
Ensure that your 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 your 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 your 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 your 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 you 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 your 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 your 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. Do not rely exclusively on looking for malicious or malformed
inputs (i.e., do not rely on a blacklist). However, blacklists can be
useful for detecting potential attacks or determining which inputs are
so malformed that they should be rejected outright.
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 you are
expecting colors such as "red" or "blue."
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 your 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 your 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 you 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 your 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 your 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.
If you are providing the code that is to be downloaded, such as for automatic updates of your software, then use cryptographic signatures for your code and modify your download clients to verify the signatures. Ensure that your 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 your 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 your 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 you 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 your 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 performs an operation at a privilege level that is higher than the minimum level required, which creates new weaknesses or amplifies the consequences of other weaknesses.
Extended Description
New weaknesses can be exposed because running with extra privileges, such as root or Administrator, can disable the normal security checks being performed by the operating system or surrounding environment. Other pre-existing weaknesses can turn into security vulnerabilities if they occur while operating at raised privileges.
Privilege management functions can behave in some less-than-obvious ways, and they have different quirks on different platforms. These inconsistencies are particularly pronounced if you are transitioning from one non-root user to another. Signal handlers and spawned processes run at the privilege of the owning process, so if a process is running as root when a signal fires or a sub-process is executed, the signal handler or sub-process will operate with root privileges.
Time of Introduction
Installation
Architecture and Design
Operation
Applicable Platforms
Languages
All
Modes of Introduction
If an application has this design problem, then it can be easier for the developer to make implementation-related errors such as CWE-271 (Privilege Dropping / Lowering Errors). In addition, the consequences of Privilege Chaining (CWE-268) can become more severe.
An attacker will be able to gain access to any resources that are
allowed by the extra privileges. Common results include executing code,
disabling services, and reading restricted data.
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.
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 perform a login. Look for
library functions and system calls that indicate when privileges are
being raised or dropped. Look for accesses of resources that are
restricted to normal users.
Note that this technique is only useful for privilege issues related
to system resources. It is not likely to detect application-level
business rules that are related to privileges, such as if a blog system
allows a user to delete a blog entry without first checking that the
user has administrator privileges.
Demonstrative Examples
Example 1
This code temporarily raises the program's privileges to allow
creation of a new user folder.
print('Unable to create new user directory for user:' +
username)
return False
return True
While the program only raises its privilege level to create the folder
and immediately lowers it again, if the call to os.mkdir() throws an
exception, the call to lowerPrivileges() will not occur. As a result,
the program is indefinitely operating in a raised privilege state,
possibly allowing further exploitation to occur.
Example 2
The following code calls chroot() to restrict the application to a
subset of the filesystem below APP_HOME in order to prevent an attacker from
using the program to gain unauthorized access to files located elsewhere.
The code then opens a file specified by the user and processes the contents
of the file.
(Bad Code)
Example
Language: C
chroot(APP_HOME);
chdir("/");
FILE* data = fopen(argv[1], "r+");
...
Constraining the process inside the application's home directory
before opening any files is a valuable security measure. However, the
absence of a call to setuid() with some non-zero value means the
application is continuing to operate with unnecessary root privileges.
Any successful exploit carried out by an attacker against the
application can now result in a privilege escalation attack because any
malicious operations will be performed with the privileges of the
superuser. If the application drops to the privilege level of a non-root
user, the potential for damage is substantially reduced.
FTP client program on a certain OS runs with
setuid privileges and has a buffer overflow. Most clients do not need extra
privileges, so an overflow is not a vulnerability for those clients.
Composite: application running with high
privileges allows user to specify a restricted file to process, which
generates a parsing error that leaks the contents of the file.
Installation script installs some programs as
setuid when they shouldn't be.
Potential Mitigations
Phases: Architecture and Design; Operation
Strategy: Environment Hardening
Run your code using the lowest privileges that are required to accomplish the necessary tasks [R.250.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: Architecture and Design
Strategy: Separation of Privilege
Identify the functionality that requires additional privileges, such as access to privileged operating system resources. Wrap and centralize this functionality if possible, and isolate the privileged code as much as possible from other code [R.250.2]. Raise your privileges as late as possible, and drop them as soon as possible to avoid CWE-271. Avoid weaknesses such as CWE-288 and CWE-420 by protecting all possible communication channels that could interact with your privileged code, such as a secondary socket that you only intend to be accessed by administrators.
Phase: Implementation
Perform extensive input validation for any privileged code that must
be exposed to the user and reject anything that does not fit your strict
requirements.
Phase: Implementation
When you drop privileges, ensure that you have dropped them successfully to avoid CWE-273. As protection mechanisms in the environment get stronger, privilege-dropping calls may fail even if it seems like they would always succeed.
Phase: Implementation
If circumstances force you to run with extra privileges, then determine the minimum access level necessary. First identify the different permissions that the software and its users will need to perform their actions, such as file read and write permissions, network socket permissions, and so forth. Then explicitly allow those actions while denying all else [R.250.2]. Perform extensive input validation and canonicalization to minimize the chances of introducing a separate vulnerability. This mitigation is much more prone to error than dropping the privileges in the first place.
Phases: Operation; System Configuration
Strategy: Environment Hardening
Ensure that your software runs properly under the Federal Desktop Core Configuration (FDCC) [R.250.4] or an equivalent hardening configuration guide, which many organizations use to limit the attack surface and potential risk of deployed software.
There is a close association with CWE-653 (Insufficient Separation of Privileges). CWE-653 is about providing separate components for each privilege; CWE-250 is about ensuring that each component has the least amount of privileges possible.
Taxonomy Mappings
Mapped Taxonomy Name
Node ID
Fit
Mapped Node Name
7 Pernicious Kingdoms
Often Misused: Privilege Management
CERT Java Secure Coding
SER09-J
Minimize privileges before deserializing from a privilege
context
[R.250.5] [REF-17] Michael Howard, David LeBlanc
and John Viega. "24 Deadly Sins of Software Security". "Sin 16: Executing Code With Too Much Privilege." Page
243. McGraw-Hill. 2010.
[R.250.6] [REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 9, "Privilege Vulnerabilities", Page
477.. 1st Edition. Addison Wesley. 2006.
Maintenance Notes
CWE-271, CWE-272, and CWE-250 are all closely related and possibly overlapping. CWE-271 is probably better suited as a category. Both CWE-272 and CWE-250 are in active use by the community. The "least privilege" phrase has multiple interpretations.
The program dereferences a pointer that contains a location for memory that was previously valid, but is no longer valid.
Extended Description
When a program releases memory, but it maintains a pointer to that memory, then the memory might be re-allocated at a later time. If the original pointer is accessed to read or write data, then this could cause the program to read or modify data that is in use by a different function or process. Depending on how the newly-allocated memory is used, this could lead to a denial of service, information exposure, or code execution.
Terminology Notes
Many weaknesses related to pointer dereferences fall under the general
term of "memory corruption" or "memory safety." As of September 2010, there
is no commonly-used terminology that covers the lower-level variants.
Common Consequences
Scope
Effect
Confidentiality
Technical Impact: Read memory
If the expired pointer is used in a read operation, an attacker might
be able to control data read in by the application.
Availability
Technical Impact: DoS: crash / exit /
restart
If the expired pointer references a memory location that is not
accessible to the program, or points to a location that is "malformed"
(such as NULL) or larger than expected by a read or write operation,
then a crash may occur.
Integrity
Confidentiality
Availability
Technical Impact: Execute unauthorized code or
commands
If the expired pointer is used in a function call, or points to
unexpected data in a write operation, then code execution may be
possible.
Demonstrative Examples
Example 1
The following code shows a simple example of a use after free
error:
(Bad Code)
Example
Language: C
char* ptr = (char*)malloc (SIZE);
if (err) {
abrt = 1;
free(ptr);
}
...
if (abrt) {
logError("operation aborted before commit", ptr);
}
When an error occurs, the pointer is immediately freed. However, this
pointer is later incorrectly used in the logError function.
Example 2
The following code shows a simple example of a double free
error:
(Bad Code)
Example
Language: C
char* ptr = (char*)malloc (SIZE);
...
if (abrt) {
free(ptr);
}
...
free(ptr);
Double free vulnerabilities have two common (and sometimes
overlapping) causes:
Error conditions and other exceptional circumstances
Confusion over which part of the program is responsible for
freeing the memory
Although some double free vulnerabilities are not much more
complicated than the previous example, most are spread out across
hundreds of lines of code or even different files. Programmers seem
particularly susceptible to freeing global variables more than
once.
read of value at an offset into a structure after
the offset is no longer valid
Potential Mitigations
Phase: Architecture and Design
Choose a language that provides automatic memory management.
Phase: Implementation
When freeing pointers, be sure to set them to NULL once they are
freed. However, the utilization of multiple or complex data structures
may lower the usefulness of this strategy.
Under-studied and probably under-reported as of September 2010. This
weakness has been reported in high-visibility software, but applied
vulnerability researchers have only been investigating it since
approximately 2008, and there are only a few public reports. Few reports
identify weaknesses at such a low level, which makes it more difficult to
find and study real-world code examples.
Maintenance Notes
There are close relationships between incorrect pointer dereferences and
other weaknesses related to buffer operations. There may not be sufficient
community agreement regarding these relationships. Further study is needed
to determine when these relationships are chains, composites,
perspective/layering, or other types of relationships. As of September 2010,
most of the relationships are being captured as chains.
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. Do not rely exclusively on looking for malicious or malformed
inputs (i.e., do not rely on a blacklist). However, blacklists can be
useful for detecting potential attacks or determining which inputs are
so malformed that they should be rejected outright.
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 you are
expecting colors such as "red" or "blue."
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.
Probing an Application Through Targeting its Error Reporting
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.
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
Compartmentalize your 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.
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).
The software supports a session in which more than one behavior must be performed by an actor, but it does not properly ensure that the actor performs the behaviors in the required sequence.
Extended Description
By performing actions in an unexpected order, or by omitting steps, an attacker could manipulate the business logic of the software or cause it to enter an invalid state. In some cases, this can also expose resultant weaknesses.
For example, a file-sharing protocol might require that an actor perform separate steps to provide a username, then a password, before being able to transfer files. If the file-sharing server accepts a password command followed by a transfer command, without any username being provided, the software might still perform the transfer.
Note that this is different than CWE-696, which focuses on when the software performs actions in the wrong sequence; this entry is closely related, but it is focused on ensuring that the actor performs actions in the correct sequence.
Workflow-related behaviors include:
Steps are performed in the expected order.
Required steps are not omitted.
Steps are not interrupted.
Steps are performed in a timely fashion.
Common Consequences
Scope
Effect
Other
Technical Impact: Alter execution
logic
An attacker could cause the software to skip critical steps or perform
them in the wrong order, bypassing its intended business logic. This can
sometimes have security implications.
Demonstrative Examples
Example 1
This code is part of an FTP server and deals with various commands
that could be sent by a user. It is intended that a user must successfully
login before performing any other action such as retrieving or listing
files.
(Bad Code)
Example
Language: Python
def dispatchCommand(command, user, args):
if command == 'Login':
loginUser(args)
return
# user has requested a file
if command == 'Retrieve_file':
if authenticated(user) and ownsFile(user,args):
sendFile(args)
return
if command == 'List_files':
listFiles(args)
return
...
The server correctly does not send files to a user that isn't logged
in and doesnt own the file. However, the server will incorrectly list
the files in any directory without confirming the command came from an
authenticated user, and that the user is authorized to see the
directory's contents.
Here is a fixed version of the above example:
(Good Code)
Example
Language: Python
def dispatchCommand(command, user, args):
...
if command == 'List_files':
if authenticated(user) and
ownsDirectory(user,args):
FTP server allows remote attackers to bypass
authentication by sending (1) LIST, (2) RETR, (3) STOR, or other commands
without performing the required login steps first.
This weakness is typically associated with business logic flaws, except
when it produces resultant weaknesses.
The classification of business logic flaws has been under-studied,
although exploitation of business flaws frequently happens in real-world
systems, and many applied vulnerability researchers investigate them. The
greatest focus is in web applications. There is debate within the community
about whether these problems represent particularly new concepts, or if they
are variations of well-known principles.
Many business logic flaws appear to be oriented toward business processes,
application flows, and sequences of behaviors, which are not as
well-represented in CWE as weaknesses related to input validation, memory
management, etc.
Viktoria Felmetsger, Ludovico Cavedon, Christopher Kruegel
and Giovanni Vigna. "Toward Automated Detection of Logic Vulnerabilities in Web
Applications". USENIX Security Symposium 2010. August 2010. <http://www.usenix.org/events/sec10/tech/full_papers/Felmetsger.pdf>.
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: external control of values for user's
desired language and theme enables 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 provide this capability.[R.22.3]
Phases: Architecture and Design; Operation
Strategy: Sandbox or Jail
Run your 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 your 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 you 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 your 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 your 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
If you are using PHP, configure your application so that it does not use register_globals. During implementation, develop your 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 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
For every web page that is generated, use and specify a character encoding such as ISO-8859-1 or UTF-8. When an encoding is not specified, the web browser may choose a different encoding by guessing which encoding is actually being used by the web page. This can cause the web browser to treat certain sequences as special, opening up the client to subtle XSS attacks. See CWE-116 for more mitigations related to encoding/escaping.
Phase: Implementation
With Struts, you should 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. Do not rely exclusively on looking for malicious or malformed
inputs (i.e., do not rely on a blacklist). However, blacklists can be
useful for detecting potential attacks or determining which inputs are
so malformed that they should be rejected outright.
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 you are
expecting colors such as "red" or "blue."
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
If you are using PHP, configure your application so that it does not use register_globals. During implementation, develop your 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.
Chain: incomplete blacklist for OS command
injection
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 your 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 your 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 you 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 your 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
If you need to use dynamically-generated query strings or commands in spite of the risk, 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. Do not rely exclusively on looking for malicious or malformed
inputs (i.e., do not rely on a blacklist). However, blacklists can be
useful for detecting potential attacks or determining which inputs are
so malformed that they should be rejected outright.
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 you are
expecting colors such as "red" or "blue."
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
Strategy: Compilation or Build 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 you 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
If you are using PHP, configure your application so that it does not use register_globals. During implementation, develop your 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
If you need to use dynamically-generated query strings or commands in spite of the risk, 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 your own 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. Do not rely exclusively on looking for malicious or malformed
inputs (i.e., do not rely on a blacklist). However, blacklists can be
useful for detecting potential attacks or determining which inputs are
so malformed that they should be rejected outright.
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 you are
expecting colors such as "red" or "blue."
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
If you are using PHP, configure your application so that it does not use register_globals. During implementation, develop your 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. Do not rely exclusively on looking for malicious or malformed
inputs (i.e., do not rely on a blacklist). However, blacklists can be
useful for detecting potential attacks or determining which inputs are
so malformed that they should be rejected outright.
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 you are
expecting colors such as "red" or "blue."
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 your input when you invoke 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 your 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 your 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 you 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 your 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.
The software uses or specifies an encoding when generating output to a downstream component, but the specified encoding is not the same as the encoding that is expected by the downstream component.
Extended Description
This weakness can cause the downstream component to use a decoding method that produces different data than what the software intended to send. When the wrong encoding is used - even if closely related - the downstream component could decode the data incorrectly. This can have security consequences when the provided boundaries between control and data are inadvertently broken, because the resulting data could introduce control characters or special elements that were not sent by the software. The resulting data could then be used to bypass protection mechanisms such as input validation, and enable injection attacks.
While using output encoding is essential for ensuring that communications between components are accurate, the use of the wrong encoding - even if closely related - could cause the downstream component to misinterpret the output.
For example, HTML entity encoding is used for elements in the HTML body of a web page. However, a programmer might use entity encoding when generating output for that is used within an attribute of an HTML tag, which could contain functional Javascript that is not affected by the HTML encoding.
While web applications have received the most attention for this problem, this weakness could potentially apply to any type of software that uses a communications stream that could support multiple encodings.
Applicable Platforms
Languages
Language-independent
Common Consequences
Scope
Effect
Integrity
Confidentiality
Availability
Technical Impact: Modify application
data; Execute unauthorized code or
commands
An attacker could modify the structure of the message or data being
sent to the downstream component, possibly injecting commands.
Demonstrative Examples
Example 1
This code dynamically builds an HTML page using POST data:
The programmer attempts to avoid XSS exploits (CWE-79) by encoding the POST values so they will not be interpreted as valid HTML. However, the htmlentities() encoding is not appropriate when the data are used as HTML attributes, allowing more attributes to be injected.
Server does not properly handle requests that do
not contain UTF-8 data; browser assumes UTF-8, allowing
XSS.
Potential Mitigations
Phase: Implementation
Strategy: Output Encoding
Use context-aware encoding. That is, understand which encoding is
being used by the downstream component, and ensure that this encoding is
used. If an encoding can be specified, do so, instead of assuming that
the default encoding is the same as the default being assumed by the
downstream component.
Phase: Architecture and Design
Strategy: Output Encoding
Where possible, use communications protocols or data formats that
provide strict boundaries between control and data. If this is not
feasible, ensure that the protocols or formats allow the communicating
components to explicitly state which encoding/decoding method is being
used. Some template frameworks provide built-in support.
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.838.7] or a similar tool, library, or framework. These will help the programmer encode outputs in a manner less prone to error.
Note that some template mechanisms provide built-in support for the
appropriate encoding.
Inclusion of Functionality from Untrusted Control Sphere
Definition in a New Window
Weakness ID: 829 (Weakness Class)
Status: Incomplete
Description
Description Summary
The software imports, requires, or includes executable functionality (such as a library) from a source that is outside of the intended control sphere.
Extended Description
When including third-party functionality, such as a web widget, library, or other source of functionality, the software must effectively trust that functionality. Without sufficient protection mechanisms, the functionality could be malicious in nature (either by coming from an untrusted source, being spoofed, or being modified in transit from a trusted source). The functionality might also contain its own weaknesses, or grant access to additional functionality and state information that should be kept private to the base system, such as system state information, sensitive application data, or the DOM of a web application.
This might lead to many different consequences depending on the included functionality, but some examples include injection of malware, information exposure by granting excessive privileges or permissions to the untrusted functionality, DOM-based XSS vulnerabilities, stealing user's cookies, or open redirect to malware (CWE-601).
Common Consequences
Scope
Effect
Confidentiality
Integrity
Availability
Technical Impact: Execute unauthorized code or
commands
An attacker could insert malicious functionality into the program by
causing the program to download code that the attacker has placed into
the untrusted control sphere, such as a malicious web site.
Demonstrative Examples
Example 1
This login webpage includes a weather widget from an external
website:
(Bad Code)
Example
Language: HTML
<div class="header"> Welcome!
<div id="loginBox">Please Login:
<form id ="loginForm" name="loginForm"
action="login.php" method="post">
This webpage is now only as secure as the external domain it is including functionality from. If an attacker compromised the external domain and could add malicious scripts to the weatherwidget.js file, the attacker would have complete control, as seen in any XSS weakness (CWE-79).
For example, user login information could easily be stolen with a
single line added to weatherwidget.js:
This line of javascript changes the login form's original action
target from the original website to an attack site. As a result, if a
user attempts to login their username and password will be sent directly
to the attack site.
Product does not properly reject DTDs in SOAP
messages, which allows remote attackers to read arbitrary files, send HTTP
requests to intranet servers, or cause a denial of service.
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.
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 provide this capability [R.829.1].
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 your 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 your 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 you 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 your 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.829.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. Do not rely exclusively on looking for malicious or malformed
inputs (i.e., do not rely on a blacklist). However, blacklists can be
useful for detecting potential attacks or determining which inputs are
so malformed that they should be rejected outright.
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 you are
expecting colors such as "red" or "blue."
For 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.
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 your 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.
The software performs an authorizationcheck when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.
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 is incorrectly applied, 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 correctly 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 correctly restricted, or by
accessing insufficiently-protected, privileged functionality to write
the data.
Access Control
Technical Impact: Gain privileges / assume
identity; Bypass protection
mechanism
An attacker could gain privileges by modifying or reading critical
data directly, or by accessing 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. Even if they can be customized to
recognize these schemes, they might not be able to tell whether the
scheme correctly performs the authorization in a way that cannot be
bypassed or subverted by an attacker.
Effectiveness: Limited
Automated Dynamic Analysis
Automated dynamic analysis may not be able to find interfaces that are
protected by authorization checks, even if those checks contain
weaknesses.
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
The following code could be for a medical records application. It
displays a record to already authenticated users, confirming the user's
authorization using a value stored in a cookie.
(Bad Code)
Example
Language: PHP
$role = $_COOKIES['role'];
if (!$role) {
$role = getRole('user');
if ($role) {
// save the cookie to send out in future responses
setcookie("role", $role, time()+60*60*2);
}
else{
ShowLoginScreen();
die("\n");
}
}
if ($role == 'Reader') {
DisplayMedicalHistory($_POST['patient_ID']);
}
else{
die("You are not Authorized to view this record\n");
}
The programmer expects that the cookie will only be set when
getRole() succeeds. The programmer even diligently specifies a 2-hour
expiration for the cookie. However, the attacker can easily set the
"role" cookie to the value "Reader". As a result, the $role variable is
"Reader", and getRole() is never invoked. The attacker has bypassed the
authorization system.
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 your application 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) [R.863.1] 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.863.4] and the OWASP ESAPI Access Control feature [R.863.5].
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.863.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.
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.
Demonstrative Examples
Example 1
The following code allocates memory for a maximum number of widgets.
It then gets a user-specified number of widgets, making sure that the user
does not request too many. It then initializes the elements of the array
using InitializeWidget(). Because the number of widgets can vary for each
request, the code inserts a NULL pointer to signify the location of the last
widget.
(Bad Code)
Example
Language: C
int i;
unsigned int numWidgets;
Widget **WidgetList;
numWidgets = GetUntrustedSizeValue();
if ((numWidgets == 0) || (numWidgets > MAX_NUM_WIDGETS))
{
ExitError("Incorrect number of widgets requested!");
However, this code contains an off-by-one calculation error. It allocates exactly enough space to contain the specified number of widgets, but it does not include the space for the NULL pointer. As a result, the allocated buffer is smaller than it is supposed to be. So if the user ever requests MAX_NUM_WIDGETS, there is an off-by-one buffer overflow (CWE-193) when the NULL is assigned. Depending on the environment and compilation settings, this could cause memory corruption.
Example 2
The following image processing code allocates a table for
images.
This code intends to allocate a table of size num_imgs, however as num_imgs grows large, the calculation determining the size of the list will eventually overflow (CWE-190). This will result in a very small list to be allocated instead. If the subsequent code operates on the list as if it were num_imgs long, it may result in many types of out-of-bounds problems (CWE-119).
Example 3
This example applies an encoding procedure to an input string and
stores it into a buffer.
The programmer attempts to encode the ampersand character in the
user-controlled string, however the length of the string is validated
before the encoding procedure is applied. Furthermore, the programmer
assumes encoding expansion will only expand a given character by a
factor of 4, while the encoding of the ampersand expands by 5. As a
result, when the encoding procedure expands the string it is possible to
overflow the destination buffer if the attacker provides a string of
many ampersands.
Example 4
The following code is intended to read an incoming packet from a
socket and extract one or more headers.
The code performs a check to make sure that the packet does not contain too many headers. However, numHeaders is defined as a signed int, so it could be negative. If the incoming packet specifies a value such as -3, then the malloc calculation will generate a negative number (say, -300 if each header can be a maximum of 100 bytes). When this result is provided to malloc(), it is first converted to a size_t type. This conversion then produces a large value such as 4294966996, which may cause malloc() to fail or to allocate an extremely large amount of memory (CWE-195). With the appropriate negative numbers, an attacker could trick malloc() into using a very small positive number, which then allocates a buffer that is much smaller than expected, potentially leading to a buffer overflow.
Example 5
The following code attempts to save three different identification
numbers into an array. The array is allocated from memory using a call to
malloc().
(Bad Code)
Example
Language: C
int *id_sequence;
/* Allocate space for an array of three ids. */
id_sequence = (int*) malloc(3);
if (id_sequence == NULL) exit(1);
/* Populate the id array. */
id_sequence[0] = 13579;
id_sequence[1] = 24680;
id_sequence[2] = 97531;
The problem with the code above is the value of the size parameter
used during the malloc() call. It uses a value of '3' which by
definition results in a buffer of three bytes to be created. However the
intention was to create a buffer that holds three ints, and in C, each
int requires 4 bytes worth of memory, so an array of 12 bytes is needed,
4 bytes for each int. Executing the above code could result in a buffer
overflow as 12 bytes of data is being saved into 3 bytes worth of
allocated space. The overflow would occur during the assignment of
id_sequence[0] and would continue with the assignment of id_sequence[1]
and id_sequence[2].
The malloc() call could have used '3*sizeof(int)' as the value for the
size parameter in order to allocate the correct amount of space required
to store the three ints.
Chain: Language interpreter calculates wrong buffer size (CWE-131) by using "size = ptr ? X : Y" instead of "size = (ptr ? X : Y)" expression.
Potential Mitigations
Phase: Implementation
If you allocate a buffer for the purpose of transforming, converting,
or encoding an input, make sure that you allocate enough memory to
handle the largest possible encoding. For example, in a routine that
converts "&" characters to "&" for HTML entity encoding, you
will need an output buffer that is at least 5 times as large as the
input buffer.
Phase: Implementation
Understand your programming language's underlying representation and how it interacts with numeric calculation (CWE-681). Pay close attention to byte size discrepancies, precision, signed/unsigned distinctions, truncation, conversion and casting between types, "not-a-number" calculations, and how your language handles numbers that are too large or too small for its underlying representation. [R.131.7]
Also be careful to account for 32-bit, 64-bit, and other potential
differences that may affect the numeric representation.
Phase: Implementation
Strategy: Input Validation
Perform input validation on any numeric input by ensuring that it is
within the expected range. Enforce that the input meets both the minimum
and maximum requirements for the expected range.
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
When processing structured incoming data containing a size field followed by raw data, ensure that you identify and resolve any inconsistencies between the size field and the actual size of the data (CWE-130).
Phase: Implementation
When allocating memory that uses sentinels to mark the end of a data
structure - such as NUL bytes in strings - make sure you also include
the sentinel in your calculation of the total amount of memory that must
be allocated.
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).
Additionally, this only addresses potential overflow issues. Resource
consumption / exhaustion issues are still possible.
Phase: Implementation
Use sizeof() on the appropriate data type to avoid CWE-467.
Phase: Implementation
Use the appropriate type for the desired action. For example, in
C/C++, only use unsigned types for values that could never be negative,
such as height, width, or other numbers related to quantity. This will
simplify your sanity checks and will reduce surprises related to
unexpected casting.
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.
Use libraries or frameworks that make it easier to handle numbers
without unexpected consequences, or buffer allocation routines that
automatically track buffer size.
Examples include safe integer handling packages such as SafeInt (C++) or IntegerLib (C or C++). [R.131.1]
Phase: Build and Compilation
Strategy: Compilation or Build Hardening
Run or compile your 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: Operation
Strategy: Environment Hardening
Use a feature like Address Space Layout Randomization (ASLR). [R.131.3][R.131.5]
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.131.4][R.131.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: Compilation or Build Hardening
Examine compiler warnings closely and eliminate problems with
potential security implications, such as signed / unsigned mismatch in
memory operations, or use of uninitialized variables. Even if the
weakness is rarely exploitable, a single failure may lead to the
compromise of the entire system.
Phases: Architecture and Design; Operation
Strategy: Environment Hardening
Run your code using the lowest privileges that are required to accomplish the necessary tasks [R.131.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 your 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 your 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 you 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 your 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.
[R.131.7] [REF-11] M. Howard and
D. LeBlanc. "Writing Secure Code". Chapter 20, "Integer Overflows" Page 620. 2nd Edition. Microsoft. 2002.
[R.131.8] [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.131.9] [REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 8, "Incrementing Pointers Incorrectly", Page
401.. 1st Edition. Addison Wesley. 2006.
Maintenance Notes
This is a broad category. Some examples include:
simple math errors,
incorrectly updating parallel counters,
not accounting for size differences when "transforming" one input to
another format (e.g. URL canonicalization or other transformation that
can generate a result that's larger than the original input, i.e.
"expansion").
This level of detail is rarely available in public reports, so it is
difficult to find good examples.
This weakness may be a composite or a chain. It also may contain layering
or perspective differences.
This issue may be associated with many different types of incorrect calculations (CWE-682), although the integer overflow (CWE-190) is probably the most prevalent. This can be primary to resource consumption problems (CWE-400), including uncontrolled memory allocation (CWE-789). However, its relationship with out-of-bounds buffer access (CWE-119) must also be considered.
When converting from one data type to another, such as long to integer, data can be omitted or translated in a way that produces unexpected values. If the resulting values are used in a sensitive context, then dangerous behaviors may occur.
The program could wind up using the wrong number and generate
incorrect results. If the number is used to allocate resources or make a
security decision, then this could introduce a vulnerability.
Likelihood of Exploit
Medium to High
Demonstrative Examples
Example 1
In the following Java example, a float literal is cast to an
integer, thus causing a loss of precision.
(Bad Code)
Example
Language: Java
int i = (int) 33457.8f;
Example 2
This code adds a float and an integer together, casting the result
to an integer.
(Bad Code)
Example
Language: PHP
$floatVal = 1.8345;
$intVal = 3;
$result = (int)$floatVal + $intVal;
Normally, PHP will preserve the precision of this operation, making
$result = 4.8345. After the cast to int, it is reasonable to expect PHP
to follow rounding convention and set $result = 5. However, the explicit
cast to int always rounds DOWN, so the final value of $result is 4. This
behavior may have unintended consequences.
Example 3
In this example the variable amount can hold a negative value when
it is returned. Because the function is declared to return an unsigned int,
amount will be implicitly converted to unsigned.
(Bad Code)
Example
Language: C
unsigned int readdata () {
int amount = 0;
...
if (result == ERROR)
amount = -1;
...
return amount;
}
If the error condition in the code above is met, then the return value
of readdata() will be 4,294,967,295 on a system that uses 32-bit
integers.
Example 4
In this example, depending on the return value of
accecssmainframe(), the variable amount can hold a negative value when it is
returned. Because the function is declared to return an unsigned value,
amount will be implicitly cast to an unsigned number.
(Bad Code)
Example
Language: C
unsigned int readdata () {
int amount = 0;
...
amount = accessmainframe();
...
return amount;
}
If the return value of accessmainframe() is -1, then the return value
of readdata() will be 4,294,967,295 on a system that uses 32-bit
integers.
Chain: signed short width value in image processor
is sign extended during conversion to unsigned int, which leads to integer
overflow and heap-based buffer overflow.
Convert integers to floating point for floating point
operations
CERT C Secure Coding
FLP34-C
Ensure that floating point conversions are within range of the
new type
CERT C Secure Coding
INT15-C
Use intmax_t or uintmax_t for formatted IO on
programmer-defined integer types
CERT C Secure Coding
INT31-C
Ensure that integer conversions do not result in lost or
misinterpreted data
CERT C Secure Coding
INT35-C
Evaluate integer expressions in a larger size before comparing
or assigning to that size
CERT Java Secure Coding
NUM12-J
Ensure conversions of numeric types to narrower types do not
result in lost or misinterpreted data
CERT C++ Secure Coding
INT15-CPP
Use intmax_t or uintmax_t for formatted IO on
programmer-defined integer types
CERT C++ Secure Coding
INT31-CPP
Ensure that integer conversions do not result in lost or
misinterpreted data
CERT C++ Secure Coding
INT35-CPP
Evaluate integer expressions in a larger size before comparing
or assigning to that size
CERT C++ Secure Coding
FLP33-CPP
Convert integers to floating point for floating point
operations
CERT C++ Secure Coding
FLP34-CPP
Ensure that floating point conversions are within range of the
new type
References
[REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 6, "Type Conversions", Page 223.. 1st Edition. Addison Wesley. 2006.
Incorrect Permission Assignment for Critical Resource
Definition in a New Window
Weakness ID: 732 (Weakness Class)
Status: Draft
Description
Description Summary
The software specifies permissions for a security-critical resource in a way that allows that resource to be read or modified by unintended actors.
Extended Description
When a resource is given a permissions setting that provides access to a wider range of actors than required, it could lead to the exposure of sensitive information, or the modification of that resource by unintended parties. This is especially dangerous when the resource is related to program configuration, execution or sensitive user data.
Time of Introduction
Architecture and Design
Implementation
Installation
Operation
Applicable Platforms
Languages
Language-independent
Modes of Introduction
The developer may set loose permissions in order to minimize problems when
the user first runs the program, then create documentation stating that
permissions should be tightened. Since system administrators and users do
not always read the documentation, this can result in insecure permissions
being left unchanged.
The developer might make certain assumptions about the environment in
which the software runs - e.g., that the software is running on a
single-user system, or the software is only accessible to trusted
administrators. When the software is running in a different environment, the
permissions become a problem.
Common Consequences
Scope
Effect
Confidentiality
Technical Impact: Read application
data; Read files or
directories
An attacker may be able to read sensitive information from the
associated resource, such as credentials or configuration information
stored in a file.
Access Control
Technical Impact: Gain privileges / assume
identity
An attacker may be able to modify critical properties of the
associated resource to gain privileges, such as replacing a
world-writable executable with a Trojan horse.
Integrity
Other
Technical Impact: Modify application
data; Other
An attacker may be able to destroy or corrupt critical data in the
associated resource, such as deletion of records from a database.
Likelihood of Exploit
Medium to High
Detection Methods
Automated Static Analysis
Automated static analysis may be effective in detecting permission
problems for system resources such as files, directories, shared memory,
device interfaces, etc. Automated techniques may be able to detect the
use of library functions that modify permissions, then analyze function
calls for arguments that contain potentially insecure values.
However, since the software's intended security policy might allow
loose permissions for certain operations (such as publishing a file on a
web server), automated static analysis may produce some false positives
- i.e., warnings that do not have any security consequences or require
any code changes.
When custom permissions models are used - such as defining who can
read messages in a particular forum in a bulletin board system - these
can be difficult to detect using automated static analysis. It may be
possible to define custom signatures that identify any custom functions
that implement the permission checks and assignments.
Automated Dynamic Analysis
Automated dynamic analysis may be effective in detecting permission
problems for system resources such as files, directories, shared memory,
device interfaces, etc.
However, since the software's intended security policy might allow
loose permissions for certain operations (such as publishing a file on a
web server), automated dynamic analysis may produce some false positives
- i.e., warnings that do not have any security consequences or require
any code changes.
When custom permissions models are used - such as defining who can
read messages in a particular forum in a bulletin board system - these
can be difficult to detect using automated dynamic analysis. It may be
possible to define custom signatures that identify any custom functions
that implement the permission checks and assignments.
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.
These may be more effective than strictly automated techniques. This
is especially the case with weaknesses that are related to design and
business rules.
Manual Static Analysis
Manual static analysis may be effective in detecting the use of custom
permissions models and functions. The code could then be examined to
identifying usage of the related functions. Then the human analyst could
evaluate permission assignments in the context of the intended security
model of the software.
Manual Dynamic Analysis
Manual dynamic analysis may be effective in detecting the use of
custom permissions models and functions. The program could then be
executed with a focus on exercising code paths that are related to the
custom permissions. Then the human analyst could evaluate permission
assignments in the context of the intended security model of the
software.
Fuzzing
Fuzzing is not effective in detecting this weakness.
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 watch for library functions or
system calls on OS resources such as files, directories, and shared
memory. Examine the arguments to these calls to infer which permissions
are being used.
Note that this technique is only useful for permissions issues related
to system resources. It is not likely to detect application-level
business rules that are related to permissions, such as if a user of a
blog system marks a post as "private," but the blog system inadvertently
marks it as "public."
Demonstrative Examples
Example 1
The following code sets the umask of the process to 0 before
creating a file and writing "Hello world" into the file.
(Bad Code)
Example
Language: C
#define OUTFILE "hello.out"
umask(0);
FILE *out;
/* Ignore CWE-59 (link following) for brevity */
out = fopen(OUTFILE, "w");
if (out) {
fprintf(out, "hello world!\n");
fclose(out);
}
After running this program on a UNIX system, running the "ls -l"
command might return the following output:
(Result)
-rw-rw-rw- 1 username 13 Nov 24 17:58 hello.out
The "rw-rw-rw-" string indicates that the owner, group, and world (all
users) can read the file and write to it.
Example 2
This code creates a home directory for a new user, and makes that
user the owner of the directory. If the new directory cannot be owned by the
user, the directory is deleted.
(Bad Code)
Example
Language: PHP
function createUserDir($username){
$path = '/home/'.$username;
if(!mkdir($path)){
return false;
}
if(!chown($path,$username)){
rmdir($path);
return false;
}
return true;
}
Because the optional "mode" argument is omitted from the call to
mkdir(), the directory is created with the default permissions 0777.
Simply setting the new user as the owner of the directory does not
explicitly change the permissions of the directory, leaving it with the
default. This default allows any user to read and write to the
directory, allowing an attack on the user's files. The code also fails
to change the owner group of the directory, which may result in access
by unexpected groups.
This code may also be vulnerable to Path Traversal (CWE-22) attacks if an attacker supplies a non alphanumeric username.
Example 3
The following code snippet might be used as a monitor to
periodically record whether a web site is alive. To ensure that the file can
always be modified, the code uses chmod() to make the file
world-writable.
The first time the program runs, it might create a new file that
inherits the permissions from its environment. A file listing might look
like:
(Result)
-rw-r--r-- 1 username 13 Nov 24 17:58 secretFile.out
This listing might occur when the user has a default umask of 022,
which is a common setting. Depending on the nature of the file, the user
might not have intended to make it readable by everyone on the
system.
The next time the program runs, however - and all subsequent
executions - the chmod will set the file's permissions so that the
owner, group, and world (all users) can read the file and write to
it:
(Result)
-rw-rw-rw- 1 username 13 Nov 24 17:58 secretFile.out
Perhaps the programmer tried to do this because a different process
uses different permissions that might prevent the file from being
updated.
Example 4
The following command recursively sets world-readable permissions
for a directory and all of its children:
(Bad Code)
Example
Language: Shell
chmod -R ugo+r DIRNAME
If this command is run from a program, the person calling the program
might not expect that all the files under the directory will be
world-readable. If the directory is expected to contain private data,
this could become a security problem.
Anti-virus product sets insecure "Everyone: Full
Control" permissions for files under the "Program Files" folder, allowing
attackers to replace executables with Trojan
horses.
Library function copies a file to a new target and
uses the source file's permissions for the target, which is incorrect when
the source file is a symbolic link, which typically has 0777 permissions.
Product uses "Everyone: Full Control" permissions
for memory-mapped files (shared memory) in inter-process communication,
allowing attackers to tamper with a session.
Chain: database product contains buffer overflow
that is only reachable through a .ini configuration file - which has
"Everyone: Full Control" permissions.
Potential Mitigations
Phase: Implementation
When using a critical resource such as a configuration file, check to see if the resource has insecure permissions (such as being modifiable by any regular user) [R.732.1], and generate an error or even exit the software if there is a possibility that the resource could have been modified by an unauthorized party.
Phase: Architecture and Design
Divide your application into anonymous, normal, privileged, and administrative areas. Reduce the attack surface by carefully defining distinct user groups, privileges, and/or roles. Map these against data, functionality, and the related resources. Then set the permissions accordingly. This will allow you to maintain more fine-grained control over your resources. [R.732.2]
Effectiveness: Moderate
This can be an effective strategy. However, in practice, it may be
difficult or time consuming to define these areas when there are many
different resources or user types, or if the applications features
change rapidly.
Phases: Architecture and Design; Operation
Strategy: Sandbox or Jail
Run your 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 your 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 you 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 your application may still be subject
to compromise.
Be careful to avoid CWE-243 and other weaknesses related to jails.
Effectiveness: Moderate
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: Implementation; Installation
During program startup, explicitly set the default permissions or
umask to the most restrictive setting possible. Also set the appropriate
permissions during program installation. This will prevent you from
inheriting insecure permissions from any user who installs or runs the
program.
Effectiveness: High
Phase: System Configuration
For all configuration files, executables, and libraries, make sure
that they are only readable and writable by the software's
administrator.
Effectiveness: High
Phase: Documentation
Do not suggest insecure configuration changes in your documentation,
especially if those configurations can extend to resources and other
software that are outside the scope of your own software.
Phase: Installation
Do not assume that the system administrator will manually change the
configuration to the settings that you recommend in the manual.
Phases: Operation; System Configuration
Strategy: Environment Hardening
Ensure that your software runs properly under the Federal Desktop Core Configuration (FDCC) [R.732.4] or an equivalent hardening configuration guide, which many organizations use to limit the attack surface and potential risk of deployed software.
[R.732.1] [REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 9, "File Permissions." Page 495.. 1st Edition. Addison Wesley. 2006.
[R.732.2] [REF-9] John Viega and
Gary McGraw. "Building Secure Software: How to Avoid Security Problems the
Right Way". Chapter 8, "Access Control." Page 194.. 1st Edition. Addison-Wesley. 2002.
The relationships between privileges, permissions, and actors (e.g. users and groups) need further refinement within the Research view. One complication is that these concepts apply to two different pillars, related to control of resources (CWE-664) and protection mechanism failures (CWE-396).
The software generates an error message that includes sensitive information about its environment, users, or associated data.
Extended Description
The sensitive information may be valuable information on its own (such as a password), or it may be useful for launching other, more deadly attacks. If an attack fails, an attacker may use error information provided by the server to launch another more focused attack. For example, an attempt to exploit a path traversal weakness (CWE-22) might yield the full pathname of the installed application. In turn, this could be used to select the proper number of ".." sequences to navigate to the targeted file. An attack using SQL injection (CWE-89) might not initially succeed, but an error message could reveal the malformed query, which would expose query logic and possibly even passwords or other sensitive information used within the query.
Time of Introduction
Architecture and Design
Implementation
System Configuration
Operation
Applicable Platforms
Languages
PHP: (Often)
All
Common Consequences
Scope
Effect
Confidentiality
Technical Impact: Read application
data
Often this will either reveal sensitive information which may be used
for a later attack or private information stored in the server.
Likelihood of Exploit
High
Detection Methods
Manual Analysis
This weakness generally requires domain-specific interpretation using
manual analysis. However, the number of potential error conditions may
be too large to cover completely within limited time constraints.
Effectiveness: High
Automated Analysis
Automated methods may be able to detect certain idioms automatically,
such as exposed stack traces or pathnames, but violation of business
rules or privacy requirements is not typically feasible.
Effectiveness: Moderate
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.
Error conditions may be triggered 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.
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
In the following example, sensitive information might be printed
depending on the exception that occurs.
(Bad Code)
Example
Language: Java
try {
/.../
}
catch (Exception e) {
System.out.println(e);
}
If an exception related to SQL is handled by the catch, then the
output might contain sensitive information such as SQL query structure
or private information. If this output is redirected to a web user, this
may represent a security problem.
Example 2
This code tries to open a database connection, and prints any
exceptions that occur.
(Bad Code)
Example
Language: PHP
try {
openDbConnection();
}
//print exception message that includes exception message and
configuration file location
echo 'Check credentials in config file at: ',
$Mysql_config_location, '\n';
}
If an exception occurs, the printed message exposes the location of
the configuration file the script is using. An attacker can use this
information to target the configuration file (perhaps exploiting a Path
Traversal weakness). If the file can be read, the attacker could gain
credentials for accessing the database. The attacker may also be able to
replace the file with a malicious one, causing the application to use an
arbitrary database.
Example 3
The following code generates an error message that leaks the full
pathname of the configuration file.
(Bad Code)
Example
Language: Perl
$ConfigDir = "/home/myprog/config";
$uname = GetUserInput("username");
# avoid CWE-22, CWE-78, others.
ExitError("Bad hacker!") if ($uname !~ /^\w+$/);
$file = "$ConfigDir/$uname.txt";
if (! (-e $file)) {
ExitError("Error: $file does not exist");
}
...
If this code is running on a server, such as a web application, then
the person making the request should not know what the full pathname of
the configuration directory is. By submitting a username that does not
produce a $file that exists, an attacker could get this pathname. It
could then be used to exploit path traversal or symbolic link following
problems that may exist elsewhere in the application.
Example 4
In the example below, the method getUserBankAccount retrieves a bank
account object from a database using the supplied username and account
number to query the database. If an SQLException is raised when querying the
database, an error message is created and output to a log file.
(Bad Code)
Example
Language: Java
public BankAccount getUserBankAccount(String username, String
accountNumber) {
BankAccount userAccount = null;
String query = null;
try {
if (isAuthorizedUser(username)) {
query = "SELECT * FROM accounts WHERE owner = "
+ username + " AND accountID = " +
accountNumber;
DatabaseManager dbManager = new
DatabaseManager();
The error message that is created includes information about the database query that may contain sensitive information about the database or query logic. In this case, the error message will expose the table name and column names used in the database. This data could be used to simplify other attacks, such as SQL injection (CWE-89) to directly access the database.
Composite: application running with high
privileges allows user to specify a restricted file to process, which
generates a parsing error that leaks the contents of the
file.
Malformed regexp syntax leads to information
exposure in error message.
Potential Mitigations
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.
Phase: Implementation
Handle exceptions internally and do not display errors containing
potentially sensitive information to a user.
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.
Phases: Implementation; Build and Compilation
Strategies: Compilation or Build Hardening; Environment Hardening
Debugging information should not make its way into a production
release.
Phase: System Configuration
Where available, configure the environment to use less verbose error
messages. For example, in PHP, disable the display_errors setting during
configuration, or at runtime using the error_reporting()
function.
Phase: System Configuration
Create default error pages or messages that do not leak any
information.
Brian Chess and
Jacob West. "Secure Programming with Static Analysis". Section 9.2, page 326.. Addison-Wesley. 2007.
[REF-8] M. Howard and
D. LeBlanc. "Writing Secure Code". Chapter 16, "General Good Practices." Page
415. 1st Edition. Microsoft. 2002.
[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.
[REF-17] Michael Howard, David LeBlanc
and John Viega. "24 Deadly Sins of Software Security". "Sin 12: Information Leakage." Page 191. McGraw-Hill. 2010.
[REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 3, "Overly Verbose Error Messages", Page
75.. 1st Edition. Addison Wesley. 2006.
The software performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control.
Extended Description
An integer overflow or wraparound occurs when an integer value is incremented to a value that is too large to store in the associated representation. When this occurs, the value may wrap to become a very small or negative number. While this may be intended behavior in circumstances that rely on wrapping, it can have security consequences if the wrap is unexpected. This is especially the case if the integer overflow can be triggered using user-supplied inputs. This becomes security-critical when the result is used to control looping, make a security decision, or determine the offset or size in behaviors such as memory allocation, copying, concatenation, etc.
Terminology Notes
"Integer overflow" is sometimes used to cover several types of errors,
including signedness errors, or buffer overflows that involve manipulation
of integer data types instead of characters. Part of the confusion results
from the fact that 0xffffffff is -1 in a signed context. Other confusion
also arises because of the role that integer overflows have in
chains.
This weakness will generally lead to undefined behavior and therefore
crashes. In the case of overflows involving loop index variables, the
likelihood of infinite loops is also high.
Integrity
Technical Impact: Modify memory
If the value in question is important to data (as opposed to flow),
simple data corruption has occurred. Also, if the wrap around results in
other conditions such as buffer overflows, further memory corruption may
occur.
Confidentiality
Availability
Access Control
Technical Impact: Execute unauthorized code or
commands; Bypass protection
mechanism
This weakness can sometimes trigger buffer overflows which can be used
to execute arbitrary code. This is usually outside the scope of a
program's implicit security policy.
Likelihood of Exploit
Medium
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.
Effectiveness: High
Black Box
Sometimes, evidence of 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
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.
Demonstrative Examples
Example 1
The following image processing code allocates a table for
images.
This code intends to allocate a table of size num_imgs, however as num_imgs grows large, the calculation determining the size of the list will eventually overflow (CWE-190). This will result in a very small list to be allocated instead. If the subsequent code operates on the list as if it were num_imgs long, it may result in many types of out-of-bounds problems (CWE-119).
Example 2
The following code excerpt from OpenSSH 3.3 demonstrates a classic
case of integer overflow:
(Bad Code)
Example
Language: C
nresp = packet_get_int();
if (nresp > 0) {
response = xmalloc(nresp*sizeof(char*));
for (i = 0; i > nresp; i++) response[i] =
packet_get_string(NULL);
}
If nresp has the value 1073741824 and sizeof(char*) has its typical
value of 4, then the result of the operation nresp*sizeof(char*)
overflows, and the argument to xmalloc() will be 0. Most malloc()
implementations will happily allocate a 0-byte buffer, causing the
subsequent loop iterations to overflow the heap buffer response.
Example 3
Integer overflows can be complicated and difficult to detect. The
following example is an attempt to show how an integer overflow may lead to
undefined looping behavior:
(Bad Code)
Example
Language: C
short int bytesRec = 0;
char buf[SOMEBIGNUM];
while(bytesRec < MAXGET) {
bytesRec += getFromInput(buf+bytesRec);
}
In the above case, it is entirely possible that bytesRec may overflow,
continuously creating a lower number than MAXGET and also overwriting
the first MAXGET-1 bytes of buf.
Example 4
In this example the method determineFirstQuarterRevenue is used to
determine the first quarter revenue for an accounting/business application.
The method retrieves the monthly sales totals for the first three months of
the year, calculates the first quarter sales totals from the monthly sales
totals, calculates the first quarter revenue based on the first quarter
sales, and finally saves the first quarter revenue results to the
database.
However, in this example the primitive type short int is used for
both the monthly and the quarterly sales variables. In C the short int
primitive type has a maximum value of 32768. This creates a potential
integer overflow if the value for the three monthly sales adds up to
more than the maximum value for the short int primitive type. An integer
overflow can lead to data corruption, unexpected behavior, infinite
loops and system crashes. To correct the situation the appropriate
primitive type should be used, as in the example below, and/or provide
some validation mechanism to ensure that the maximum value for the
primitive type is not exceeded.
Note that an integer overflow could also occur if the quarterSold
variable has a primitive type long but the method
calculateRevenueForQuarter has a parameter of type short.
Length value of -1 leads to allocation of 0 bytes
and resultant heap overflow.
Potential Mitigations
Phase: Requirements
Ensure that all protocols are strictly defined, such that all
out-of-bounds behavior can be identified simply, and require strict
conformance to the protocol.
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.
If possible, choose a language or compiler that performs automatic
bounds checking.
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.
Use libraries or frameworks that make it easier to handle numbers
without unexpected consequences.
Examples include safe integer handling packages such as SafeInt (C++) or IntegerLib (C or C++). [R.190.5]
Phase: Implementation
Strategy: Input Validation
Perform input validation on any numeric input by ensuring that it is
within the expected range. Enforce that the input meets both the minimum
and maximum requirements for the expected range.
Use unsigned integers where possible. This makes it easier to perform
sanity checks for integer overflows. If you must use signed integers,
make sure that your range check includes minimum values as well as
maximum values.
Phase: Implementation
Understand your programming language's underlying representation and how it interacts with numeric calculation (CWE-681). Pay close attention to byte size discrepancies, precision, signed/unsigned distinctions, truncation, conversion and casting between types, "not-a-number" calculations, and how your language handles numbers that are too large or too small for its underlying representation. [R.190.3]
Also be careful to account for 32-bit, 64-bit, and other potential
differences that may affect the numeric representation.
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: Compilation or Build Hardening
Examine compiler warnings closely and eliminate problems with
potential security implications, such as signed / unsigned mismatch in
memory operations, or use of uninitialized variables. Even if the
weakness is rarely exploitable, a single failure may lead to the
compromise of the entire system.
[R.190.1] Yves Younan. "An overview of common programming security vulnerabilities and
possible solutions". Student thesis section 5.4.3. August 2003. <http://fort-knox.org/thesis.pdf>.
[R.190.3] [REF-11] M. Howard and
D. LeBlanc. "Writing Secure Code". Chapter 20, "Integer Overflows" Page 620. 2nd Edition. Microsoft. 2002.
[R.190.4] [REF-17] Michael Howard, David LeBlanc
and John Viega. "24 Deadly Sins of Software Security". "Sin 7: Integer Overflows." Page 119. McGraw-Hill. 2010.
[REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 6, "Signed Integer Boundaries", Page
220.. 1st Edition. Addison Wesley. 2006.
The software does not perform any authentication for functionality that requires a provable user identity or consumes a significant amount of resources.
Time of Introduction
Architecture and Design
Applicable Platforms
Languages
Language-independent
Common Consequences
Scope
Effect
Access Control
Other
Technical Impact: Gain privileges / assume
identity; Other
Exposing critical functionality essentially provides an attacker with
the privilege level of that functionality. The consequences will depend
on the associated functionality, but they can range from reading or
modifying sensitive data, access to administrative or other privileged
functionality, or possibly even execution of arbitrary code.
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 static analysis is useful for evaluating the
correctness of custom authentication mechanisms.
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
Automated static analysis is useful for detecting commonly-used idioms
for authentication. A tool may be able to analyze related configuration
files, such as .htaccess in Apache web servers, or detect the usage of
commonly-used authentication libraries.
Generally, automated static analysis tools have difficulty detecting
custom authentication schemes. In addition, the software's design may
include some functionality that is accessible to any user and does not
require an established identity; an automated technique that detects the
absence of authentication may report false positives.
Effectiveness: Limited
Demonstrative Examples
Example 1
In the following Java example the method createBankAccount is used
to create a BankAccount object for a bank management
application.
(Bad Code)
Example
Language: Java
public BankAccount createBankAccount(String accountNumber, String
accountType,
However, there is no authentication mechanism to ensure that the user
creating this bank account object has the authority to create new bank
accounts. Some authentication mechanisms should be used to verify that
the user has the authority to create bank account objects.
The following Java code includes a boolean variable and method for
authenticating a user. If the user has not been authenticated then the
createBankAccount will not create the bank account object.
(Good Code)
Example
Language: Java
private boolean isUserAuthentic = false;
// authenticate user,
// if user is authenticated then set variable to true
// otherwise set variable to false
public boolean authenticateUser(String username, String password)
{
...
}
public BankAccount createNewBankAccount(String accountNumber,
String accountType,
Product enforces restrictions through a GUI but
not through privileged APIs.
Potential Mitigations
Phase: Architecture and Design
Divide your software into anonymous, normal, privileged, and
administrative areas. Identify which of these areas require a proven
user identity, and use a centralized authentication capability.
Identify all potential communication channels, or other means of
interaction with the software, to ensure that all channels are
appropriately protected. Developers sometimes perform authentication at
the primary channel, but open up a secondary channel that is assumed to
be private. For example, a login mechanism may be listening on one
network port, but after successful authentication, it may open up a
second port where it waits for the connection, but avoids authentication
because it assumes that only the authenticated party will connect to the
port.
In general, if the software or protocol allows a single session or
user state to persist across multiple connections or channels,
authentication and appropriate credential management need to be used
throughout.
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
Where possible, avoid implementing custom authentication routines and
consider using authentication capabilities as provided by the
surrounding framework, operating system, or environment. These may make
it easier to provide a clear separation between authentication tasks and
authorization tasks.
In environments such as the World Wide Web, the line between
authentication and authorization is sometimes blurred. If custom
authentication routines are required instead of those provided by the
server, then these routines must be applied to every single page, since
these pages could be requested directly.
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 libraries with authentication capabilities such as OpenSSL or the ESAPI Authenticator [R.306.3].
[R.306.1] [REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 2, "Common Vulnerabilities of Authentication," Page
36. 1st Edition. Addison Wesley. 2006.
The software does not perform 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, 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 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 restricted, or by accessing
insufficiently-protected, privileged functionality to write the
data.
Access Control
Technical Impact: Gain privileges / assume
identity; Bypass protection
mechanism
An attacker could gain privileges by modifying or reading critical
data directly, or by accessing 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 your application 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) [R.862.1] 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 [R.862.2].
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.862.5] and the OWASP ESAPI Access Control feature [R.862.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.862.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.
The software does not encrypt sensitive or critical information before storage or transmission.
Extended Description
The lack of proper data encryption passes up the guarantees of confidentiality, integrity, and accountability that properly implemented encryption conveys.
Time of Introduction
Architecture and Design
Operation
Applicable Platforms
Languages
Language-independent
Common Consequences
Scope
Effect
Confidentiality
Technical Impact: Read application
data
If the application does not use a secure channel, such as SSL, to
exchange sensitive information, it is possible for an attacker with
access to the network traffic to sniff packets from the connection and
uncover the data. This attack is not technically difficult, but does
require physical access to some portion of the network over which the
sensitive data travels. This access is usually somewhere near where the
user is connected to the network (such as a colleague on the company
network) but can be anywhere along the path from the user to the end
server.
Confidentiality
Integrity
Technical Impact: Modify application
data
Omitting the use of encryption in any program which transfers data
over a network of any kind should be considered on par with delivering
the data sent to each user on the local networks of both the sender and
receiver. Worse, this omission allows for the injection of data into a
stream of communication between two parties -- with no means for the
victims to separate valid data from invalid. In this day of widespread
network attacks and password collection sniffers, it is an unnecessary
risk to omit encryption from the design of any system which might
benefit from it.
Likelihood of Exploit
High to Very High
Detection Methods
Manual Analysis
The characterizaton of sensitive data often requires domain-specific
understanding, so manual methods are useful. However, manual efforts
might not achieve desired code coverage within limited time constraints.
Black box methods may produce artifacts (e.g. stored data or unencrypted
network transfer) that require manual evaluation.
Effectiveness: High
Automated Analysis
Automated measurement of the entropy of an input/output source may
indicate the use or lack of encryption, but human analysis is still
required to distinguish intentionally-unencrypted data (e.g. metadata)
from sensitive data.
Demonstrative Examples
Example 1
This code writes a user's login information to a cookie so the user
does not have to login again later.
The code stores the user's username and password in plaintext in a cookie on the user's machine. This exposes the user's login information if their computer is compromised by an attacker. Even if the user's machine is not compromised, this weakness combined with cross-site scripting (CWE-79) could allow an attacker to remotely copy the cookie.
Also note this example code also exhibits Plaintext Storage in a Cookie (CWE-315).
Example 2
The following code attempts to establish a connection, read in a
password, then store it to a buffer.
(Bad Code)
Example
Language: C
server.sin_family = AF_INET; hp = gethostbyname(argv[1]);
if (connect(sock, (struct sockaddr *)&server, sizeof server)
< 0) error("Connecting");
...
while ((n=read(sock,buffer,BUFSIZE-1))!=-1) {
write(dfd,password_buffer,n);
...
While successful, the program does not encrypt the data before writing
it to a buffer, possibly exposing it to unauthorized actors.
Example 3
The following code attempts to establish a connection to a site to
communicate sensitive information.
(Bad Code)
Example
Language: Java
try {
URL u = new URL("http://www.secret.example.org/");
HttpURLConnection hu = (HttpURLConnection)
u.openConnection();
hu.setRequestMethod("PUT");
hu.connect();
OutputStream os = hu.getOutputStream();
hu.disconnect();
}
catch (IOException e) {
//...
}
Though a connection is successfully made, the connection is
unencrypted and it is possible that all sensitive data sent to or
received from the server will be read by unintended actors.
Product sends file with cleartext passwords in
e-mail message intended for diagnostic purposes.
Potential Mitigations
Phase: Requirements
Clearly specify which data or resources are valuable enough that they
should be protected by encryption. Require that any transmission or
storage of this data/resource should use well-vetted encryption
algorithms.
Phase: Architecture and Design
Strategy: Threat Modeling
Using threat modeling or other techniques, assume that your data can be compromised through a separate vulnerability or weakness, and determine where encryption will be most effective. Ensure that data you believe should be private is not being inadvertently exposed using weaknesses such as insecure permissions (CWE-732). [R.311.1]
Phase: Architecture and Design
Ensure that encryption is properly integrated into the system design,
including but not necessarily limited to:
Encryption that is needed to store or transmit private data of the
users of the system
Encryption that is needed to protect the system itself from
unauthorized disclosure or tampering
Identify the separate needs and contexts for encryption:
One-way (i.e., only the user or recipient needs to have the key).
This can be achieved using public key cryptography, or other
techniques in which the encrypting party (i.e., the software) does
not need to have access to a private key.
Two-way (i.e., the encryption can be automatically performed on
behalf of a user, but the key must be available so that the
plaintext can be automatically recoverable by that user). This
requires storage of the private key in a format that is recoverable
only by the user (or perhaps by the operating system) in a way that
cannot be recovered by others.
Phase: Architecture and Design
Strategy: Libraries or Frameworks
Select a well-vetted algorithm that is currently considered to be
strong by experts in the field, and select well-tested implementations.
As with all cryptographic mechanisms, the source code should be
available for analysis.
For example, US government systems require FIPS 140-2
certification.
Do not develop your own cryptographic algorithms. They will likely be
exposed to attacks that are well-understood by cryptographers. Reverse
engineering techniques are mature. If your algorithm can be compromised
if attackers find out how it works, then it is especially weak.
Periodically ensure that you aren't using obsolete cryptography. Some
older algorithms, once thought to require a billion years of computing
time, can now be broken in days or hours. This includes MD4, MD5, SHA1,
DES, and other algorithms that were once regarded as strong.
Phase: Architecture and Design
Compartmentalize your 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.
Phases: Implementation; Architecture and Design
When you use industry-approved techniques, you need to use them correctly. Don't cut corners by skipping resource-intensive steps (CWE-325). These steps are often essential for preventing common attacks.
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.
Passively Sniff and Capture Application Code Bound for Authorized Client
References
[R.311.1] [REF-11] M. Howard and
D. LeBlanc. "Writing Secure Code". Chapter 9, "Protecting Secret Data" Page
299. 2nd Edition. Microsoft. 2002.
[R.311.2] [REF-17] Michael Howard, David LeBlanc
and John Viega. "24 Deadly Sins of Software Security". "Sin 17: Failure to Protect Stored Data." Page
253. McGraw-Hill. 2010.
[R.311.4] [REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 2, "Common Vulnerabilities of Encryption", Page
43.. 1st Edition. Addison Wesley. 2006.
The software does not initialize critical variables, which causes the execution environment to use unexpected values.
Time of Introduction
Implementation
Applicable Platforms
Languages
Language-independent
Common Consequences
Scope
Effect
Integrity
Other
Technical Impact: Unexpected state; Quality degradation; Varies by context
The uninitialized data may be invalid, causing logic errors within the
program. In some cases, this could result in a security problem.
Demonstrative Examples
Example 1
Here, an uninitialized field in a Java class is used in a
seldom-called method, which would cause a NullPointerException to be
thrown.
(Bad Code)
Example
Language: Java
private User user;
public void someMethod() {
// Do something interesting.
...
// Throws NPE if user hasn't been properly
initialized.
String username = user.getName();
}
Example 2
This code first authenticates a user, then allows a delete command
if the user is an administrator.
(Bad Code)
Example
Language: PHP
if (authenticate($username,$password) &&
setAdmin($username)){
$isAdmin = true;
}
/.../
if ($isAdmin){
deleteUser($userToDelete);
}
The $isAdmin variable is set to true if the user is an admin, but is
uninitialized otherwise. If PHP's register_globals feature is enabled,
an attacker can set uninitialized variables like $isAdmin to arbitrary
values, in this case gaining administrator privileges by setting
$isAdmin to true.
Example 3
In the following Java code the BankManager class uses the user
variable of the class User to allow authorized users to perform bank manager
tasks. The user variable is initialized within the method setUser that
retrieves the User from the User database. The user is then authenticated as
unauthorized user through the method authenticateUser.
(Bad Code)
Example
Language: Java
public class BankManager {
// user allowed to perform bank manager tasks
private User user = null;
private boolean isUserAuthentic = false;
// constructor for BankManager class
public BankManager() {
...
}
// retrieve user from database of users
public User getUserFromUserDatabase(String username){
...
}
// set user variable using username
public void setUser(String username) {
this.user = getUserFromUserDatabase(username);
}
// authenticate user
public boolean authenticateUser(String username, String
password) {
if (username.equals(user.getUsername()) &&
password.equals(user.getPassword())) {
isUserAuthentic = true;
}
return isUserAuthentic;
}
// methods for performing bank manager tasks
...
}
However, if the method setUser is not called before authenticateUser
then the user variable will not have been initialized and will result in
a NullPointerException. The code should verify that the user variable
has been initialized before it is used, as in the following code.
(Good Code)
Example
Language: Java
public class BankManager {
// user allowed to perform bank manager tasks
private User user = null;
private boolean isUserAuthentic = false;
// constructor for BankManager class
public BankManager(String username) {
user = getUserFromUserDatabase(username);
}
// retrieve user from database of users
public User getUserFromUserDatabase(String username)
{...}
// authenticate user
public boolean authenticateUser(String username, String
password) {
if (user == null) {
System.out.println("Cannot find user " +
username);
This weakness is a major factor in a number of resultant weaknesses,
especially in web applications that allow global variable initialization
(such as PHP) with libraries that can be directly requested.
Research Gaps
It is highly likely that a large number of resultant weaknesses have
missing initialization as a primary factor, but researcher reports generally
do not provide this level of detail.
Taxonomy Mappings
Mapped Taxonomy Name
Node ID
Fit
Mapped Node Name
PLOVER
Missing Initialization
References
[REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 7, "Variable Initialization", Page
312.. 1st Edition. Addison Wesley. 2006.
When allocating resources without limits, an attacker could prevent
all other processes from accessing the same type of resource.
Likelihood of Exploit
Medium to High
Demonstrative Examples
Example 1
The following code attempts to process a file by reading it in line
by line until the end has been reached.
(Bad Code)
Example
Language: Java
private void processFile(string fName)
{
BufferReader in = new BufferReader(new
FileReader(fName));
String line;
while ((line = in.ReadLine()) != null)
{
processLine(line);
}
}
The problem with the above code is that it never closes the file
handle it opens. The Finalize() method for BufferReader eventually calls
Close(), but there is no guarantee as to how long it will take before
the Finalize() method is invoked. In fact, there is no guarantee that
Finalize() will ever be invoked. In a busy environment, this can result
in the VM using up all of its available file handles.
Example 2
The following code attempts to open a new connection to a database,
process the results returned by the database, and close the allocated
SqlConnection object.
(Bad Code)
Example
Language: C#
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand(queryString);
cmd.Connection = conn;
conn.Open();
SqlDataReader rdr = cmd.ExecuteReader();
HarvestResults(rdr);
conn.Connection.Close();
The problem with the above code is that if an exception occurs while
executing the SQL or processing the results, the SqlConnection object is
not closed. If this happens often enough, the database will run out of
available cursors and not be able to execute any more SQL queries.
Example 3
The following method never closes the file handle it opens. The
Finalize() method for StreamReader eventually calls Close(), but there is no
guarantee as to how long it will take before the Finalize() method is
invoked. In fact, there is no guarantee that Finalize() will ever be
invoked. In a busy environment, this can result in the VM using up all of
its available file handles.
(Bad Code)
Example
Language: Java
private void processFile(string fName) {
StreamWriter sw = new
StreamWriter(fName);
string line;
while ((line = sr.ReadLine()) != null)
processLine(line);
}
Example 4
If an exception occurs after establishing the database connection
and before the same connection closes, the pool of database connections may
become exhausted. If the number of available connections is exceeded, other
users cannot access this resource, effectively denying access to the
application. Using the following database connection pattern will ensure
that all opened connections are closed. The con.close() call should be the
first executable statement in the finally block.
(Bad Code)
Example
Language: Java
try {
Connection con =
DriverManager.getConnection(some_connection_string)
}
catch ( Exception e ) {
log( e )
}
finally {
con.close()
}
Example 5
Under normal conditions the following C# code executes a database
query, processes the results returned by the database, and closes the
allocated SqlConnection object. But if an exception occurs while executing
the SQL or processing the results, the SqlConnection object is not closed.
If this happens often enough, the database will run out of available cursors
and not be able to execute any more SQL queries.
(Bad Code)
Example
Language: C#
...
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand(queryString);
cmd.Connection = conn;
conn.Open();
SqlDataReader rdr = cmd.ExecuteReader();
HarvestResults(rdr);
conn.Connection.Close();
...
Example 6
The following C function does not close the file handle it opens if
an error occurs. If the process is long-lived, the process can run out of
file handles.
(Bad Code)
Example
Language: C
int decodeFile(char* fName) {
char buf[BUF_SZ];
FILE* f = fopen(fName, "r");
if (!f) {
printf("cannot open %s\n", fName);
return DECODE_FAIL;
}
else {
while (fgets(buf, BUF_SZ, f)) {
if (!checkChecksum(buf)) {
return DECODE_FAIL;
}
else {
decodeBlock(buf);
}
}
}
fclose(f);
return DECODE_SUCCESS;
}
Example 7
In this example, the program does not use matching functions such as
malloc/free, new/delete, and new[]/delete[] to allocate/deallocate the
resource.
(Bad Code)
Example
Language: C++
class A {
void foo();
};
void A::foo(){
int *ptr;
ptr = (int*)malloc(sizeof(int));
delete ptr;
}
Example 8
In this example, the program calls the delete[] function on non-heap
memory.
Chain: anti-virus product encounters a malformed file but returns from a function without closing a file descriptor (CWE-775) leading to file descriptor consumption (CWE-400) and failed scans.
Return values of file/socket operations not
checked, allowing resultant consumption of file
descriptors.
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, languages such as Java, Ruby, and Lisp perform automatic
garbage collection that releases memory for objects that have been
deallocated.
Phase: Implementation
It is good practice to be responsible for freeing all resources you
allocate and to be consistent with how and where you free resources in a
function. If you allocate resources that you intend to free upon
completion of the function, you must be sure to free the resources at
all exit points for that function including error conditions.
Phase: Implementation
For system resources, consider using the getrlimit() function included
in the sys/resources library in order to determine how many resources
are currently allowed to be opened for the process.
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.
Phase: Operation
Use resource-limiting settings provided by the operating system or
environment. For example, setrlimit() can be used to set limits for
certain types of resources. However, this is not available on all
operating systems.
Ensure that your 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.
"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.
A NULL pointer dereference occurs when the application dereferences a pointer that it expects to be valid, but is NULL, typically causing a crash or exit.
Extended Description
NULL pointer dereference issues can occur through a number of flaws, including race conditions, and simple programming omissions.
Time of Introduction
Implementation
Applicable Platforms
Languages
C
C++
Java
.NET
Common Consequences
Scope
Effect
Availability
Technical Impact: DoS: crash / exit /
restart
NULL pointer dereferences usually result in the failure of the process
unless exception handling (on some platforms) is available and
implemented. Even when exception handling is being used, it can still be
very difficult to return the software to a safe state of
operation.
Integrity
Confidentiality
Availability
Technical Impact: Execute unauthorized code or
commands
In very rare circumstances and environments, code execution is
possible.
Likelihood of Exploit
Medium
Detection Methods
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 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
While there are no complete fixes aside from conscientious
programming, the following steps will go a long way to ensure that NULL
pointer dereferences do not occur.
(Mitigation Code)
if (pointer1 != NULL) {
/* make use of pointer1 */
/* ... */
}
If you are working with a multithreaded or otherwise asynchronous
environment, ensure that proper locking APIs are used to lock before the
if statement; and unlock when it has finished.
Example 2
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. Since the code does not check the return value from gethostbyaddr (CWE-252), a NULL pointer dereference would then occur in the call to strcpy().
Note that this example is also vulnerable to a buffer overflow (see CWE-119).
Example 3
In the following code, the programmer assumes that the system always
has a property named "cmd" defined. If an attacker can control the program's
environment so that "cmd" is not defined, the program throws a NULL pointer
exception when it attempts to call the trim() method.
race condition causes a table to be corrupted if a
timer activates while it is being modified, leading to resultant NULL
dereference; also involves locking.
Chat client allows remote attackers to cause a
denial of service (crash) via a passive DCC request with an invalid ID
number, which causes a null dereference.
OS allows remote attackers to cause a denial of
service (crash from null dereference) or execute arbitrary code via a
crafted request during authentication protocol
selection.
Network monitor allows remote attackers to cause a
denial of service (crash) or execute arbitrary code via malformed packets
that cause a NULL pointer dereference.
Potential Mitigations
Phase: Implementation
If all pointers that could have been modified are sanity-checked
previous to use, nearly all NULL pointer dereferences can be
prevented.
Phase: Requirements
The choice could be made to use a language that is not susceptible to
these issues.
Phase: Implementation
Check the results of all functions that return a value and verify that
the value is non-null before acting upon it.
Effectiveness: Moderate
Checking the return value of the function will typically be sufficient, however beware of race conditions (CWE-362) in a concurrent environment.
This solution does not handle the use of improperly initialized variables (CWE-665).
Phase: Architecture and Design
Identify all variables and data stores that receive information from
external sources, and apply input validation to make sure that they are
only initialized to expected values.
Phase: Implementation
Explicitly initialize all your variables and other data stores, either
during declaration or just before the first usage.
Phase: Testing
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.
Weakness Ordinalities
Ordinality
Description
Resultant
NULL pointer dereferences are frequently resultant from rarely
encountered error conditions, since these are most likely to escape
detection during the testing phases.
Reliance on Untrusted Inputs in a Security Decision
Definition in a New Window
Weakness ID: 807 (Weakness Base)
Status: Incomplete
Description
Description Summary
The application uses a protection mechanism that relies on the existence or values of an input, but the input can be modified by an untrusted actor in a way that bypasses the protection mechanism.
Extended Description
Developers may assume that inputs such as cookies, environment variables, and hidden form fields cannot be modified. However, an attacker could change these inputs using customized clients or other attacks. This change might not be detected. When security decisions such as authentication and authorization are made based on the values of these inputs, attackers can bypass the security of the software.
Without sufficient encryption, integrity checking, or other mechanism, any input that originates from an outsider cannot be trusted.
Time of Introduction
Architecture and Design
Implementation
Applicable Platforms
Languages
Language-independent
Common Consequences
Scope
Effect
Confidentiality
Access Control
Availability
Other
Technical Impact: Bypass protection
mechanism; Gain privileges / assume
identity; Varies by context
Attackers can bypass the security decision to access whatever is being
protected. The consequences will depend on the associated functionality,
but they can range from granting additional privileges to untrusted
users to bypassing important security checks. Ultimately, this weakness
may lead to exposure or modification of sensitive data, system crash, or
execution of arbitrary code.
Likelihood of Exploit
Medium to High
Detection Methods
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
The effectiveness and speed of manual analysis will be reduced if the
there is not a centralized security mechanism, and the security logic is
widely distributed throughout the software.
Demonstrative Examples
Example 1
The following code excerpt reads a value from a browser cookie to
determine the role of the user.
(Bad Code)
Example
Language: Java
Cookie[] cookies = request.getCookies();
for (int i =0; i< cookies.length; i++) {
Cookie c = cookies[i];
if (c.getName().equals("role")) {
userRole = c.getValue();
}
}
Example 2
The following code could be for a medical records application. It
performs authentication by checking if a cookie has been set.
(Bad Code)
Example
Language: PHP
$auth = $_COOKIES['authenticated'];
if (! $auth) {
if (AuthenticateUser($_POST['user'], $_POST['password']) ==
"success") {
// save the cookie to send out in future responses
setcookie("authenticated", "1", time()+60*60*2);
}
else {
ShowLoginScreen();
die("\n");
}
}
DisplayMedicalHistory($_POST['patient_ID']);
The programmer expects that the AuthenticateUser() check will always
be applied, and the "authenticated" cookie will only be set when
authentication succeeds. The programmer even diligently specifies a
2-hour expiration for the cookie.
However, the attacker can set the "authenticated" cookie to a non-zero
value such as 1. As a result, the $auth variable is 1, and the
AuthenticateUser() check is not even performed. The attacker has
bypassed the authentication.
Example 3
In the following example, an authentication flag is read from a
browser cookie, thus allowing for external control of user state
data.
(Bad Code)
Example
Language: Java
Cookie[] cookies = request.getCookies();
for (int i =0; i< cookies.length; i++) {
Cookie c = cookies[i];
if (c.getName().equals("authenticated") &&
Boolean.TRUE.equals(c.getValue())) {
authenticated = true;
}
}
Example 4
The following code samples use a DNS lookup in order to decide
whether or not an inbound request is from a trusted host. If an attacker can
poison the DNS cache, they can gain trusted status.
(Bad Code)
Example
Language: C
struct hostent *hp;struct in_addr myaddr;
char* tHost = "trustme.example.com";
myaddr.s_addr=inet_addr(ip_addr_string);
hp = gethostbyaddr((char *) &myaddr, sizeof(struct in_addr),
AF_INET);
if (hp && !strncmp(hp->h_name, tHost, sizeof(tHost)))
{
trusted = true;
} else {
trusted = false;
}
(Bad Code)
Example
Language: Java
String ip = request.getRemoteAddr();
InetAddress addr = InetAddress.getByName(ip);
if (addr.getCanonicalHostName().endsWith("trustme.com")) {
IP addresses are more reliable than DNS names, but they can also be
spoofed. Attackers can easily forge the source IP address of the packets
they send, but response packets will return to the forged IP address. To
see the response packets, the attacker has to sniff the traffic between
the victim machine and the forged IP address. In order to accomplish the
required sniffing, attackers typically attempt to locate themselves on
the same subnet as the victim machine. Attackers may be able to
circumvent this requirement by using source routing, but source routing
is disabled across much of the Internet today. In summary, IP address
verification can be a useful part of an authentication scheme, but it
should not be the single factor required for authentication.
Web-based email list manager allows attackers to
gain admin privileges by setting a login cookie to "admin."
Potential Mitigations
Phase: Architecture and Design
Strategy: Identify and Reduce Attack Surface
Store state information and sensitive data on the server side only.
Ensure that the system definitively and unambiguously keeps track of
its own state and user state and has rules defined for legitimate state
transitions. Do not allow any application user to affect state directly
in any way other than through legitimate actions leading to state
transitions.
If information must be stored on the client, do not do so without encryption and integrity checking, or otherwise having a mechanism on the server side to catch tampering. Use a message authentication code (MAC) algorithm, such as Hash Message Authentication Code (HMAC) [R.807.2]. Apply this against the state or sensitive data that you have to expose, which can guarantee the integrity of the data - i.e., that the data has not been modified. Ensure that you use an algorithm with a strong hash function (CWE-328).
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.
With a stateless protocol such as HTTP, use a framework that maintains
the state for you.
Examples include ASP.NET View State [R.807.3] and the OWASP ESAPI [R.807.4] Session Management feature.
Be careful of language features that provide state support, since
these might be provided as a convenience to the programmer and may not
be considering security.
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: Operation; Implementation
Strategy: Environment Hardening
If you are using PHP, configure your application so that it does not use register_globals. During implementation, develop your 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.
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.
Identify all inputs that are used for security decisions and determine
if you can modify the design so that you do not have to rely on
submitted inputs at all. For example, you may be able to keep critical
information about the user's session on the server side instead of
recording it within external data.
The software uses externally-controlled format strings in printf-style functions, which can lead to buffer overflows or data representation problems.
Time of Introduction
Implementation
Applicable Platforms
Languages
C: (Often)
C++: (Often)
Perl: (Rarely)
Languages that support format strings
Modes of Introduction
The programmer rarely intends for a format string to be user-controlled at
all. This weakness is frequently introduced in code that constructs log
messages, where a constant format string is omitted.
In cases such as localization and internationalization, the
language-specific message repositories could be an avenue for exploitation,
but the format string issue would be resultant, since attacker control of
those repositories would also allow modification of message length, format,
and content.
Common Consequences
Scope
Effect
Confidentiality
Technical Impact: Read memory
Format string problems allow for information disclosure which can
severely simplify exploitation of the program.
Integrity
Confidentiality
Availability
Technical Impact: Execute unauthorized code or
commands
Format string problems can result in the execution of arbitrary
code.
Likelihood of Exploit
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.
Black Box
Since format strings often occur in rarely-occurring erroneous
conditions (e.g. for error message logging), they can be difficult to
detect using black box methods. It is highly likely that many latent
issues exist in executables that do not have associated source code (or
equivalent source.
Effectiveness: Limited
Demonstrative Examples
Example 1
The following example is exploitable, due to the printf() call in
the printWrapper() function. Note: The stack buffer was added to make
exploitation more simple.
(Bad Code)
Example
Language: C
#include <stdio.h>
void printWrapper(char *string) {
printf(string);
}
int main(int argc, char **argv) {
char buf[5012];
memcpy(buf, argv[1], 5012);
printWrapper(argv[1]);
return (0);
}
Example 2
The following code copies a command line argument into a buffer
using snprintf().
(Bad Code)
Example
Language: C
int main(int argc, char **argv){
char buf[128];
...
snprintf(buf,128,argv[1]);
}
This code allows an attacker to view the contents of the stack and
write to the stack using a command line argument containing a sequence
of formatting directives. The attacker can read from the stack by
providing more formatting directives, such as %x, than the function
takes as arguments to be formatted. (In this example, the function takes
no arguments to be formatted.) By using the %n formatting directive, the
attacker can write to the stack, causing snprintf() to write the number
of bytes output thus far to the specified argument (rather than reading
a value from the argument, which is the intended behavior). A
sophisticated version of this attack will use four staggered writes to
completely control the value of a pointer on the stack.
Example 3
Certain implementations make more advanced attacks even easier by
providing format directives that control the location in memory to read from
or write to. An example of these directives is shown in the following code,
written for glibc:
(Bad Code)
Example
Language: C
printf("%d %d %1$d %1$d\n", 5, 9);
This code produces the following output: 5 9 5 5 It is also possible
to use half-writes (%hn) to accurately control arbitrary DWORDS in
memory, which greatly reduces the complexity needed to execute an attack
that would otherwise require four staggered writes, such as the one
mentioned in the first example.
Chain: untrusted search path enabling resultant
format string by loading malicious internationalization
messages
Potential Mitigations
Phase: Requirements
Choose a language that is not subject to this flaw.
Phase: Implementation
Ensure that all format string functions are passed a static string which cannot be controlled by the user and that the proper number of arguments are always sent to that function as well. If at all possible, use functions that do not support the %n operator in format strings. [R.134.1] [R.134.2]
Phase: Build and Compilation
Heed the warnings of compilers and linkers, since they may alert you
to improper usage.
Other Notes
While Format String vulnerabilities typically fall under the Buffer
Overflow category, technically they are not overflowed buffers. The Format
String vulnerability is fairly new (circa 1999) and stems from the fact that
there is no realistic way for a function that takes a variable number of
arguments to determine just how many arguments were passed in. The most
common functions that take a variable number of arguments, including
C-runtime functions, are the printf() family of calls. The Format String
problem appears in a number of ways. A *printf() call without a format
specifier is dangerous and can be exploited. For example, printf(input); is
exploitable, while printf(y, input); is not exploitable in that context. The
result of the first call, used incorrectly, allows for an attacker to be
able to peek at stack memory since the input string will be used as the
format specifier. The attacker can stuff the input string with format
specifiers and begin reading stack values, since the remaining parameters
will be pulled from the stack. Worst case, this improper use may give away
enough control to allow an arbitrary value (or values in the case of an
exploit program) to be written into the memory of the running
program.
Frequently targeted entities are file names, process names,
identifiers.
Format string problems are a classic C/C++ issue that are now rare due to
the ease of discovery. One main reason format string vulnerabilities can be
exploited is due to the %n operator. The %n operator will write the number
of characters, which have been printed by the format string therefore far,
to the memory pointed to by its argument. Through skilled creation of a
format string, a malicious user may use values on the stack to create a
write-what-where condition. Once this is achieved, he can execute arbitrary
code. Other operators can be used as well; for example, a %9999s operator
could also trigger a buffer overflow, or when used in file-formatting
functions like fprintf, it can generate a much larger output than
intended.
Weakness Ordinalities
Ordinality
Description
Primary
(where
the weakness exists independent of other weaknesses)
Format string issues are under-studied for languages other than C. Memory
or disk consumption, control flow or variable alteration, and data
corruption may result from format string exploitation in applications
written in other languages such as Perl, PHP, Python, etc.
[R.134.4] [REF-11] M. Howard and
D. LeBlanc. "Writing Secure Code". Chapter 5, "Format String Bugs" Page 147. 2nd Edition. Microsoft. 2002.
[R.134.5] [REF-17] Michael Howard, David LeBlanc
and John Viega. "24 Deadly Sins of Software Security". "Sin 6: Format String Problems." Page 109. McGraw-Hill. 2010.
[R.134.5] [REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 8, "C Format Strings", Page 422.. 1st Edition. Addison Wesley. 2006.
The software allows the attacker to upload or transfer files of dangerous types that can be automatically processed within the product's environment.
Alternate Terms
Unrestricted File Upload:
The "unrestricted file upload" term is used in vulnerability databases
and elsewhere, but it is insufficiently precise. The phrase could be
interpreted as the lack of restrictions on the size or number of
uploaded files, which is a resource consumption issue.
Time of Introduction
Implementation
Architecture and Design
Applicable Platforms
Languages
ASP.NET: (Sometimes)
PHP: (Often)
Language-independent
Architectural Paradigms
Web-based
Technology Classes
Web-Server: (Sometimes)
Common Consequences
Scope
Effect
Integrity
Confidentiality
Availability
Technical Impact: Execute unauthorized code or
commands
Arbitrary code execution is possible if an uploaded file is
interpreted and executed as code by the recipient. This is especially
true for .asp and .php extensions uploaded to web servers because these
file types are often treated as automatically executable, even when file
system permissions do not specify execution. For example, in Unix
environments, programs typically cannot run unless the execute bit is
set, but PHP programs may be executed by the web server without directly
invoking them on the operating system.
Likelihood of Exploit
Medium to High
Demonstrative Examples
Example 1
The following code intends to allow a user to upload a picture to
the web server. The HTML code that drives the form on the user end has an
input field of type "file".
Once submitted, the form above sends the file to upload_picture.php on
the web server. PHP stores the file in a temporary location until it is
retrieved (or discarded) by the server side code. In this example, the
file is moved to a more permanent pictures/ directory.
(Bad Code)
Example
Language: PHP
// Define the target location where the picture being
echo "The picture has been successfully uploaded.";
}
else
{
echo "There was an error uploading the picture, please try
again.";
}
The problem with the above code is that there is no check regarding
type of file being uploaded. Assuming that pictures/ is available in the
web document root, an attacker could upload a file with the name:
(Attack)
malicious.php
Since this filename ends in ".php" it can be executed by the web
server. In the contents of this uploaded file, the attacker could use:
(Attack)
Example
Language: PHP
<?php
system($_GET['cmd']);
?>
Once this file has been installed, the attacker can enter arbitrary
commands to execute using a URL such as:
which runs the "ls -l" command - or any other type of command that the
attacker wants to specify.
Example 2
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
{...}
}
...
}
As with the previous example 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.
Additionally, the creation of the BufferedWriter object is subject to relative path traversal (CWE-22, CWE-23). 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.
Generate your own filename for an uploaded file instead of the user-supplied filename, so that no external input is used at all.[R.434.1] [R.434.2]
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: Architecture and Design
Consider storing the uploaded files outside of the web document root entirely. Then, use other mechanisms to deliver the files dynamically. [R.434.2]
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. Do not rely exclusively on looking for malicious or malformed
inputs (i.e., do not rely on a blacklist). However, blacklists can be
useful for detecting potential attacks or determining which inputs are
so malformed that they should be rejected outright.
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 you are
expecting colors such as "red" or "blue."
For example, limiting filenames to alphanumeric characters can help to
restrict the introduction of unintended file extensions.
Phase: Architecture and Design
Define a very limited set of allowable extensions and only generate filenames that end in these extensions. Consider the possibility of XSS (CWE-79) before you allow .html or .htm file types.
Phase: Implementation
Strategy: Input Validation
Ensure that only one extension is used in the filename. Some web servers, including some versions of Apache, may process files based on inner extensions so that "filename.php.gif" is fed to the PHP interpreter.[R.434.1] [R.434.2]
Phase: Implementation
When running on a web server that supports case-insensitive filenames,
ensure that you perform case-insensitive evaluations of the extensions
that are provided.
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
Do not rely exclusively on sanity checks of file contents to ensure
that the file is of the expected type and size. It may be possible for
an attacker to hide code in some file segments that will still be
executed by the server. For example, GIF images may contain a free-form
comments field.
Phase: Implementation
Do not rely exclusively on the MIME content type or filename attribute
when determining how to render a file. Validating the MIME content type
and ensuring that it matches the extension is only a partial
solution.
Phases: Architecture and Design; Operation
Strategy: Environment Hardening
Run your code using the lowest privileges that are required to accomplish the necessary tasks [R.434.4]. 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 your 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 your 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 you 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 your 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
Primary
This can be primary when there is no check at all.
Resultant
This is frequently resultant when use of double extensions (e.g.
".php.gif") bypasses a sanity check.
This can be resultant from client-side enforcement (CWE-602); some products will include web script in web clients to check the filename, without verifying on the server side.
This can have a chaining relationship with incomplete blacklist / permissive whitelist errors when the product tries, but fails, to properly limit which types of files are allowed (CWE-183, CWE-184).
This can also overlap multiple interpretation errors for intermediaries,
e.g. anti-virus products that do not remove or quarantine attachments with
certain file extensions that can be processed by client systems.
Research Gaps
PHP applications are most targeted, but this likely applies to other
languages that support file upload, as well as non-web technologies. ASP
applications have also demonstrated this problem.
[R.434.5] [REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 17, "File Uploading", Page 1068.. 1st Edition. Addison Wesley. 2006.
The program obtains a value from an untrusted source, converts this value to a pointer, and dereferences the resulting pointer.
Extended Description
An attacker can supply a pointer for memory locations that the program is not expecting. If the pointer is dereferenced for a write operation, the attack might allow modification of critical program state variables, cause a crash, or execute code. If the dereferencing operation is for a read, then the attack might allow reading of sensitive data, cause a crash, or set a program variable to an unexpected value (since the value will be read from an unexpected memory location).
There are several variants of this weakness, including but not necessarily limited to:
The untrusted value is directly invoked as a function call.
In OS kernels or drivers where there is a boundary between "userland" and privileged memory spaces, an untrusted pointer might enter through an API or system call (see CWE-781 for one such example).
Inadvertently accepting the value from an untrusted control sphere when it did not have to be accepted as input at all. This might occur when the code was originally developed to be run by a single user in a non-networked environment, and the code is then ported to or otherwise exposed to a networked environment.
Terminology Notes
Many weaknesses related to pointer dereferences fall under the general
term of "memory corruption" or "memory safety." As of September 2010, there
is no commonly-used terminology that covers the lower-level variants.
Common Consequences
Scope
Effect
Confidentiality
Technical Impact: Read memory
If the untrusted pointer is used in a read operation, an attacker
might be able to read sensitive portions of memory.
Availability
Technical Impact: DoS: crash / exit /
restart
If the untrusted pointer references a memory location that is not
accessible to the program, or points to a location that is "malformed"
or larger than expected by a read or write operation, the application
may terminate unexpectedly.
Integrity
Confidentiality
Availability
Technical Impact: Execute unauthorized code or
commands; Modify memory
If the untrusted pointer is used in a function call, or points to
unexpected data in a write operation, then code execution may be
possible.
labeled as a "type confusion" issue, also referred to as a "stale pointer." However, the bug ID says "contents are simply interpreted as a pointer... renderer ordinarily doesn't supply this pointer directly". The "handle" in the untrusted area is replaced in one function, but not another - thus also, effectively, exposure to wrong sphere (CWE-668).
Under-studied and probably under-reported as of September 2010. This
weakness has been reported in high-visibility software, but applied
vulnerability researchers have only been investigating it since
approximately 2008, and there are only a few public reports. Few reports
identify weaknesses at such a low level, which makes it more difficult to
find and study real-world code examples.
There are close relationships between incorrect pointer dereferences and
other weaknesses related to buffer operations. There may not be sufficient
community agreement regarding these relationships. Further study is needed
to determine when these relationships are chains, composites,
perspective/layering, or other types of relationships. As of September 2010,
most of the relationships are being captured as chains.
URL Redirection to Untrusted Site ('Open Redirect')
Definition in a New Window
Weakness ID: 601 (Weakness Variant)
Status: Draft
Description
Description Summary
A web application accepts a user-controlled input that specifies a link to an external site, and uses that link in a Redirect. This simplifies phishing attacks.
Extended Description
An http parameter may contain a URL value and could cause the web application to redirect the request to the specified URL. By modifying the URL value to a malicious site, an attacker may successfully launch a phishing scam and steal user credentials. Because the server name in the modified link is identical to the original site, phishing attempts have a more trustworthy appearance.
Alternate Terms
Open Redirect
Cross-site Redirect
Cross-domain Redirect
Time of Introduction
Architecture and Design
Implementation
Applicable Platforms
Languages
Language-independent
Architectural Paradigms
Web-based
Common Consequences
Scope
Effect
Access Control
Technical Impact: Bypass protection
mechanism; Gain privileges / assume
identity
The user may be redirected to an untrusted page that contains malware
which may then compromise the user's machine. This will expose the user
to extensive risk and the user's interaction with the web server may
also be compromised if the malware conducts keylogging or other attacks
that steal credentials, personally identifiable information (PII), or
other important data.
Access Control
Confidentiality
Other
Technical Impact: Bypass protection
mechanism; Gain privileges / assume
identity; Other
The user may be subjected to phishing attacks by being redirected to
an untrusted page. The phishing attack may point to an attacker
controlled web page that appears to be a trusted web site. The phishers
may then steal the user's credentials and then use these credentials to
access the legitimate web site.
Likelihood of Exploit
Low to Medium
Detection Methods
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
Automated Dynamic Analysis
Automated black box tools that supply URLs to every input may be able
to spot Location header modifications, but test case coverage is a
factor, and custom redirects may not be detected.
Automated Static Analysis
Automated static analysis tools may not be able to determine whether
input influences the beginning of a URL, which is important for reducing
false positives.
Other
Whether this issue poses a vulnerability will be subject to the
intended behavior of the application. For example, a search engine might
intentionally provide redirects to arbitrary URLs.
Demonstrative Examples
Example 1
The following code obtains a URL from the query string and then
redirects the user to that URL.
(Bad Code)
Example
Language: PHP
$redirect_url = $_GET['url'];
header("Location: " . $redirect_url);
The problem with the above code is that an attacker could use this
page as part of a phishing scam by redirecting users to a malicious
site. For example, assume the above code is in the file example.php. An
attacker could supply a user with the following link:
The user sees the link pointing to the original trusted site
(example.com) and does not realize the redirection that could take
place.
Example 2
The following code is a Java servlet that will receive a GET request
with a url parameter in the request to redirect the browser to the address
specified in the url parameter. The servlet will retrieve the url parameter
value from the request and send a response to redirect the browser to the
url address.
(Bad Code)
Example
Language: Java
public class RedirectServlet extends HttpServlet {
The problem with this Java servlet code is that an attacker could use
the RedirectServlet as part of a e-mail phishing scam to redirect users
to a malicious site. An attacker could send an HTML formatted e-mail
directing the user to log into their account by including in the e-mail
the following link:
(Attack)
Example
Language: HTML
<a
href="http://bank.example.com/redirect?url=http://attacker.example.net">Click
here to log in</a>
The user may assume that the link is safe since the URL starts with
their trusted bank, bank.example.com. However, the user will then be
redirected to the attacker's web site (attacker.example.net) which the
attacker may have made to appear very similar to bank.example.com. The
user may then unwittingly enter credentials into the attacker's web page
and compromise their bank account. A Java servlet should never redirect
a user to a URL without verifying that the redirect address is a trusted
site.
An open redirect vulnerability in the search
script in the software allows remote attackers to redirect users to
arbitrary web sites and conduct phishing attacks via a URL as a parameter to
the proper function.
Open redirect vulnerability in the software allows
remote attackers to redirect users to arbitrary web sites and conduct
phishing attacks via a URL in the proper
parameter.
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. Do not rely exclusively on looking for malicious or malformed
inputs (i.e., do not rely on a blacklist). However, blacklists can be
useful for detecting potential attacks or determining which inputs are
so malformed that they should be rejected outright.
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 you are
expecting colors such as "red" or "blue."
Use a whitelist of approved URLs or domains to be used for
redirection.
Phase: Architecture and Design
Use an intermediate disclaimer page that provides the user with a clear warning that they are leaving your site. Implement a long timeout before the redirect occurs, or force the user to click on the link. Be careful to avoid XSS problems (CWE-79) when generating the disclaimer page.
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 "/login.asp" and ID 2 could map to "http://www.example.com/". Features such as the ESAPI AccessReferenceMap provide this capability. [R.601.4]
Phase: Architecture and Design
Ensure that no externally-supplied requests are honored by requiring that all redirect requests include a unique nonce generated by the application [R.601.1]. Be sure that the nonce is not predictable (CWE-330).
Note that this can be bypassed using XSS (CWE-79).
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 open redirect problems occur because the programmer assumed that
certain inputs could not be modified, such as cookies and hidden form
fields.
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.
Background Details
Phishing is a general term for deceptive attempts to coerce private
information from users that will be used for identity theft.
The use of a broken or risky cryptographic algorithm is an unnecessary risk that may result in the exposure of sensitive information.
Extended Description
The use of a non-standard algorithm is dangerous because a determined attacker may be able to break the algorithm and compromise whatever data has been protected. Well-known techniques may exist to break the algorithm.
Time of Introduction
Architecture and Design
Applicable Platforms
Languages
Language-independent
Common Consequences
Scope
Effect
Confidentiality
Technical Impact: Read application
data
The confidentiality of sensitive data may be compromised by the use of
a broken or risky cryptographic algorithm.
Integrity
Technical Impact: Modify application
data
The integrity of sensitive data may be compromised by the use of a
broken or risky cryptographic algorithm.
Accountability
Non-Repudiation
Technical Impact: Hide activities
If the cryptographic algorithm is used to ensure the identity of the
source of the data (such as digital signatures), then a broken algorithm
will compromise this scheme and the source of the data cannot be
proven.
Likelihood of Exploit
Medium to High
Detection Methods
Automated Analysis
Automated methods may be useful for recognizing commonly-used
libraries or features that have become obsolete.
Effectiveness: Moderate
False negatives may occur if the tool is not aware of the
cryptographic libraries in use, or if custom cryptography is being
used.
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.
These may be more effective than strictly automated techniques. This
is especially the case with weaknesses that are related to design and
business rules.
Demonstrative Examples
Example 1
These code examples use the Data Encryption Standard (DES). Once
considered a strong algorithm, it is now regarded as insufficient for many
applications. It has been replaced by Advanced Encryption Standard
(AES).
Product uses the hash of a hash for
authentication, allowing attackers to gain privileges if they can obtain the
original hash.
Potential Mitigations
Phase: Architecture and Design
Strategy: Libraries or Frameworks
Select a well-vetted algorithm that is currently considered to be
strong by experts in the field, and select well-tested implementations.
As with all cryptographic mechanisms, the source code should be
available for analysis.
For example, US government systems require FIPS 140-2
certification.
Do not develop your own cryptographic algorithms. They will likely be
exposed to attacks that are well-understood by cryptographers. Reverse
engineering techniques are mature. If your algorithm can be compromised
if attackers find out how it works, then it is especially weak.
Periodically ensure that you aren't using obsolete cryptography. Some older algorithms, once thought to require a billion years of computing time, can now be broken in days or hours. This includes MD4, MD5, SHA1, DES, and other algorithms that were once regarded as strong. [R.327.4]
Phase: Architecture and Design
Design your software so that you can replace one cryptographic
algorithm with another. This will make it easier to upgrade to stronger
algorithms.
Phase: Architecture and Design
Carefully manage and protect cryptographic keys (see CWE-320). If the keys can be guessed or stolen, then the strength of the cryptography itself is irrelevant.
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.
Industry-standard implementations will save you development time and
may be more likely to avoid errors that can occur during implementation
of cryptographic algorithms. Consider the ESAPI Encryption
feature.
Phases: Implementation; Architecture and Design
When you use industry-approved techniques, you need to use them correctly. Don't cut corners by skipping resource-intensive steps (CWE-325). These steps are often essential for preventing common attacks.
Background Details
Cryptographic algorithms are the methods by which data is scrambled. There
are a small number of well-understood and heavily studied algorithms that
should be used by most applications. It is quite difficult to produce a
secure algorithm, and even high profile algorithms by accomplished
cryptographic experts have been broken.
Since the state of cryptography advances so rapidly, it is common for an
algorithm to be considered "unsafe" even if it was once thought to be
strong. This can happen when new attacks against the algorithm are
discovered, or if computing power increases so much that the cryptographic
algorithm no longer provides the amount of protection that was originally
thought.
[R.327.2] Alfred J. Menezes, Paul C. van Oorschot
and Scott A. Vanstone. "Handbook of Applied Cryptography". October 1996. <http://www.cacr.math.uwaterloo.ca/hac/>.
[R.327.6] [REF-11] M. Howard and
D. LeBlanc. "Writing Secure Code". Chapter 8, "Cryptographic Foibles" Page
259. 2nd Edition. Microsoft. 2002.
[R.327.7] [REF-17] Michael Howard, David LeBlanc
and John Viega. "24 Deadly Sins of Software Security". "Sin 21: Using the Wrong Cryptography." Page
315. McGraw-Hill. 2010.
[R.327.9] [REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 2, "Insufficient or Obsolete Encryption", Page
44.. 1st Edition. Addison Wesley. 2006.
Maintenance Notes
Relationships between CWE-310, CWE-326, and CWE-327 and all their children need to be reviewed and reorganized.
The software uses a one-way cryptographic hash against an input that should not be reversible, such as a password, but the software does not also use a salt as part of the input.
Extended Description
This makes it easier for attackers to pre-compute the hash value using dictionary attack techniques such as rainbow tables.
Common Consequences
Scope
Effect
Access Control
Technical Impact: Bypass protection
mechanism; Gain privileges / assume
identity
If an attacker can gain access to the hashes, then the lack of a salt
makes it easier to conduct brute force attacks using techniques such as
rainbow tables.
Demonstrative Examples
Example 1
In this example, a new user provides a new username and password to
create an account. The program hashes the new user's password then stores it
in a database.
(Bad Code)
Example
Language: Python
def storePassword(userName,Password):
hasher = hashlib.new('md5')
hasher.update(Password)
hashedPassword = hasher.digest()
# UpdateUserLogin returns True on success, False
otherwise
return updateUserLogin(userName,hashedPassword)
While it is good to avoid storing a cleartext password, the program
does not provide a salt to the hashing function, thus increasing the
chances of an attacker being able to reverse the hash and discover the
original password if the database is compromised.
Fixing this is as simple as providing a salt to the hashing function
on initialization:
(Good Code)
Example
Language: Python
def storePassword(userName,Password):
hasher = hashlib.new('md5',b'SaltGoesHere')
hasher.update(Password)
hashedPassword = hasher.digest()
# UpdateUserLogin returns True on success, False
otherwise
return updateUserLogin(userName,hashedPassword)
Note that regardless of the usage of a salt, the md5 hash is no longer considered secure, so this example still exhibits CWE-327.
Router does not use a salt with a hash, making it
easier to crack passwords.
Potential Mitigations
Phase: Architecture and Design
Generate a random salt each time you process a new password. Add the salt to the plaintext password before hashing it. When you store the hash, also store the salt. Do not use the same salt for every password that you process (CWE-760). [R.759.3]
Phase: Architecture and Design
Use one-way hashing techniques that allow you to configure a large
number of rounds, such as bcrypt. This may increase the expense when
processing incoming authentication requests, but if the hashed passwords
are ever stolen, it significantly increases the effort for conducting a
brute force attack, including rainbow tables. With the ability to
configure the number of rounds, you can increase the number of rounds
whenever CPU speeds or attack techniques become more efficient.
Phases: Implementation; Architecture and Design
When you use industry-approved techniques, you need to use them correctly. Don't cut corners by skipping resource-intensive steps (CWE-325). These steps are often essential for preventing common attacks.
Background Details
In cryptography, salt refers to some random addition of data to an input
before hashing to make dictionary attacks more difficult.
[R.759.6] [REF-11] M. Howard and
D. LeBlanc. "Writing Secure Code". Chapter 9, "Creating a Salted Hash" Page
302. 2nd Edition. Microsoft. 2002.
[R.759.7] [REF-7] Mark Dowd, John McDonald
and Justin Schuh. "The Art of Software Security Assessment". Chapter 2, "Salt Values", Page 46.. 1st Edition. Addison Wesley. 2006.
The software contains hard-coded credentials, such as a password or cryptographic key, which it uses for its own inbound authentication, outbound communication to external components, or encryption of internal data.
Extended Description
Hard-coded credentials typically create a significant hole that allows an attacker to bypass the authentication that has been configured by the software administrator. This hole might be difficult for the system administrator to detect. Even if detected, it can be difficult to fix, so the administrator may be forced into disabling the product entirely. There are two main variations:
Inbound: the software contains an authentication mechanism that checks the input credentials against a hard-coded set of credentials.
Outbound: the software connects to another system or component, and it contains hard-coded credentials for connecting to that component.
In the Inbound variant, a default administration account is created, and a simple password is hard-coded into the product and associated with that account. This hard-coded password is the same for each installation of the product, and it usually cannot be changed or disabled by system administrators without manually modifying the program, or otherwise patching the software. If the password is ever discovered or published (a common occurrence on the Internet), then anybody with knowledge of this password can access the product. Finally, since all installations of the software will have the same password, even across different organizations, this enables massive attacks such as worms to take place.
The Outbound variant applies to front-end systems that authenticate with a back-end service. The back-end service may require a fixed password which can be easily discovered. The programmer may simply hard-code those back-end credentials into the front-end software. Any user of that program may be able to extract the password. Client-side systems with hard-coded passwords pose even more of a threat, since the extraction of a password from a binary is usually very simple.
Time of Introduction
Architecture and Design
Applicable Platforms
Languages
Language-independent
Common Consequences
Scope
Effect
Access Control
Technical Impact: Bypass protection
mechanism
If hard-coded passwords are used, it is almost certain that malicious
users will gain access to the account in question.
Integrity
Confidentiality
Availability
Access Control
Other
Technical Impact: Read application
data; Gain privileges / assume
identity; Execute unauthorized code or
commands; Other
This weakness can lead to the exposure of resources or functionality
to unintended actors, possibly providing attackers with sensitive
information or even execute arbitrary code.
Likelihood of Exploit
Very High
Detection Methods
Black Box
Credential storage in configuration files is findable using black box
methods, but the use of hard-coded credentials for an incoming
authentication routine typically involves an account that is not visible
outside of the code.
Effectiveness: Moderate
Automated Static Analysis
Automated white box techniques have been published for detecting
hard-coded credentials for incoming authentication, but there is some
expert disagreement regarding their effectiveness and applicability to a
broad range of methods.
Manual Static Analysis
This weakness may be detectable using manual code analysis. Unless
authentication is decentralized and applied throughout the software,
there can be sufficient time for the analyst to find incoming
authentication routines and examine the program logic looking for usage
of hard-coded credentials. Configuration files could also be
analyzed.
These may be more effective than strictly automated techniques. This
is especially the case with weaknesses that are related to design and
business rules.
Manual Dynamic Analysis
For hard-coded credentials in incoming authentication: 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 perform a login. Using call
trees or similar artifacts from the output, examine the associated
behaviors and see if any of them appear to be comparing the input to a
fixed string or value.
Demonstrative Examples
Example 1
The following code uses a hard-coded password to connect to a
database:
This is an example of an external hard-coded password on the
client-side of a connection. This code will run successfully, but anyone
who has access to it will have access to the password. Once the program
has shipped, there is no going back from the database user "scott" with
a password of "tiger" unless the program is patched. A devious employee
with access to this information can use it to break into the system.
Even worse, if attackers have access to the bytecode for application,
they can use the javap -c command to access the disassembled code, which
will contain the values of the passwords used. The result of this
operation might look something like the following for the example
above:
(Attack)
javap -c ConnMngr.class
22: ldc #36; //String jdbc:mysql://ixne.com/rxsql
24: ldc #38; //String scott
26: ldc #17; //String tiger
Example 2
The following code is an example of an internal hard-coded password
in the back-end:
(Bad Code)
Example Languages: C and C++
int VerifyAdmin(char *password) {
if (strcmp(password, "Mew!")) {
printf("Incorrect Password!\n");
return(0)
}
printf("Entering Diagnostic Mode...\n");
return(1);
}
(Bad Code)
Example
Language: Java
int VerifyAdmin(String password) {
if (passwd.Equals("Mew!")) {
return(0)
}
//Diagnostic Mode
return(1);
}
Every instance of this program can be placed into diagnostic mode with
the same password. Even worse is the fact that if this program is
distributed as a binary-only distribution, it is very difficult to
change that password or disable this "functionality."
Example 3
The following code examples attempt to verify a password using a
hard-coded cryptographic key. The cryptographic key is within a hard-coded
string value that is compared to the password and a true or false value is
returned for verification that the password is equivalent to the hard-coded
cryptographic key.
(Bad Code)
Example Languages: C and C++
int VerifyAdmin(char *password) {
if (strcmp(password,"68af404b513073584c4b6f22b6c63e6b"))
{
printf("Incorrect Password!\n");
return(0);
}
printf("Entering Diagnostic Mode...\n");
return(1);
}
(Bad Code)
Example
Language: Java
public boolean VerifyAdmin(String password) {
if (password.equals("68af404b513073584c4b6f22b6c63e6b"))
{
VoIP product uses hard coded public and private
SNMP community strings that cannot be changed, which allows remote attackers
to obtain sensitive information
Backup product contains hard-coded credentials
that effectively serve as a back door, which allows remote attackers to
access the file system
Potential Mitigations
Phase: Architecture and Design
For outbound authentication: store passwords, keys, and other credentials outside of the code in a strongly-protected, encrypted configuration file or database that is protected from access by all outsiders, including other local users on the same system. Properly protect the key (CWE-320). If you cannot use encryption to protect the file, then make sure that the permissions are as restrictive as possible [R.798.1].
In Windows environments, the Encrypted File System (EFS) may provide
some protection.
Phase: Architecture and Design
For inbound authentication: Rather than hard-code a default username
and password, key, or other authentication credentials for first time
logins, utilize a "first login" mode that requires the user to enter a
unique strong password or key.
Phase: Architecture and Design
If the software must contain hard-coded credentials or they cannot be
removed, perform access control checks and limit which entities can
access the feature that requires the hard-coded credentials. For
example, a feature might only be enabled through the system console
instead of through a network connection.
Phase: Architecture and Design
For inbound authentication using passwords: apply strong one-way
hashes to your passwords and store those hashes in a configuration file
or database with appropriate access control. That way, theft of the
file/database still requires the attacker to try to crack the password.
When handling an incoming password during authentication, take the hash
of the password and compare it to the hash that you have saved.
Use randomly assigned salts for each separate hash that you generate.
This increases the amount of computation that an attacker needs to
conduct a brute-force attack, possibly limiting the effectiveness of the
rainbow table method.
Phase: Architecture and Design
For front-end to back-end connections: Three solutions are possible,
although none are complete.
The first suggestion involves the use of generated passwords or
keys that are changed automatically and must be entered at given
time intervals by a system administrator. These passwords will be
held in memory and only be valid for the time intervals.
Next, the passwords or keys should be limited at the back end to
only performing actions valid for the front end, as opposed to
having full access.
Finally, the messages sent should be tagged and checksummed with
time sensitive values so as to prevent replay-style attacks.
Weakness Ordinalities
Ordinality
Description
Primary
(where
the weakness exists independent of other weaknesses)
The software may use insufficiently random numbers or values in a security context that depends on unpredictable numbers.
Extended Description
When software generates predictable values in a context requiring unpredictability, it may be possible for an attacker to guess the next value that will be generated, and use this guess to impersonate another user or access sensitive information.
Time of Introduction
Architecture and Design
Implementation
Applicable Platforms
Languages
Language-independent
Common Consequences
Scope
Effect
Confidentiality
Other
Technical Impact: Other
When a protection mechanism relies on random values to restrict access
to a sensitive resource, such as a session ID or a seed for generating a
cryptographic key, then the resource being protected could be accessed
by guessing the ID or key.
Access Control
Other
Technical Impact: Bypass protection
mechanism; Other
If software relies on unique, unguessable IDs to identify a resource,
an attacker might be able to guess an ID for a resource that is owned by
another user. The attacker could then read the resource, or pre-create a
resource with the same ID to prevent the legitimate program from
properly sending the resource to the intended user. For example, a
product might maintain session information in a file whose name is based
on a username. An attacker could pre-create this file for a victim user,
then set the permissions so that the application cannot generate the
session for the victim, preventing the victim from using the
application.
Access Control
Technical Impact: Bypass protection
mechanism; Gain privileges / assume
identity
When an authorization or authentication mechanism relies on random
values to restrict access to restricted functionality, such as a session
ID or a seed for generating a cryptographic key, then an attacker may
access the restricted functionality by guessing the ID or key.
Likelihood of Exploit
Medium to High
Detection Methods
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 look for library functions that
indicate when randomness is being used. Run the process multiple times
to see if the seed changes. Look for accesses of devices or equivalent
resources that are commonly used for strong (or weak) randomness, such
as /dev/urandom on Linux. Look for library or system calls that access
predictable information such as process IDs and system time.
Demonstrative Examples
Example 1
This code generates a unique random identifier for a user's
session.
(Bad Code)
Example
Language: PHP
function generateSessionID($userID){
srand($userID);
return rand();
}
Because the seed for the PRNG is always the user's ID, the session ID
will always be the same. An attacker could thus predict any user's
session ID and potentially hijack the session.
This example also exhibits a Small Seed Space (CWE-339).
Example 2
The following code uses a statistical PRNG to create a URL for a
receipt that remains active for some period of time after a
purchase.
This code uses the Random.nextInt() function to generate "unique"
identifiers for the receipt pages it generates. Because Random.nextInt()
is a statistical PRNG, it is easy for an attacker to guess the strings
it generates. Although the underlying design of the receipt system is
also faulty, it would be more secure if it used a random number
generator that did not produce predictable receipt identifiers, such as
a cryptographic PRNG.
Application generates passwords that are based on
the time of day.
Potential Mitigations
Phase: Architecture and Design
Use a well-vetted algorithm that is currently considered to be strong
by experts in the field, and select well-tested implementations with
adequate length seeds.
In general, if a pseudo-random number generator is not advertised as
being cryptographically secure, then it is probably a statistical PRNG
and should not be used in security-sensitive contexts.
Pseudo-random number generators can produce predictable numbers if the
generator is known and the seed can be guessed. A 256-bit seed is a good
starting point for producing a "random enough" number.
Phase: Implementation
Consider a PRNG that re-seeds itself as needed from high quality
pseudo-random output sources, such as hardware devices.
Phase: Testing
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.
Phases: Architecture and Design; Requirements
Strategy: Libraries or Frameworks
Use products or modules that conform to FIPS 140-2 [R.330.1] to avoid obvious entropy problems. Consult FIPS 140-2 Annex C ("Approved Random Number Generators").
Phase: Testing
Use 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. These may be more
effective than strictly automated techniques. This is especially the
case with weaknesses that are related to design and business
rules.
Background Details
Computers are deterministic machines, and as such are unable to produce
true randomness. Pseudo-Random Number Generators (PRNGs) approximate
randomness algorithmically, starting with a seed from which subsequent
values are calculated. There are two types of PRNGs: statistical and
cryptographic. Statistical PRNGs provide useful statistical properties, but
their output is highly predictable and forms an easy to reproduce numeric
stream that is unsuitable for use in cases where security depends on
generated values being unpredictable. Cryptographic PRNGs address this
problem by generating output that is more difficult to predict. For a value
to be cryptographically secure, it must be impossible or highly improbable
for an attacker to distinguish between it and a truly random value.
Weakness Ordinalities
Ordinality
Description
Primary
(where
the weakness exists independent of other weaknesses)
[R.330.2] [REF-9] John Viega and
Gary McGraw. "Building Secure Software: How to Avoid Security Problems the
Right Way". 1st Edition. Addison-Wesley. 2002.
[R.330.3] [REF-11] M. Howard and
D. LeBlanc. "Writing Secure Code". Chapter 8, "Using Poor Random Numbers" Page
259. 2nd Edition. Microsoft. 2002.
[R.330.4] [REF-17] Michael Howard, David LeBlanc
and John Viega. "24 Deadly Sins of Software Security". "Sin 20: Weak Random Numbers." Page 299. McGraw-Hill. 2010.
The program invokes a potentially dangerous function that could introduce a vulnerability if it is used incorrectly, but the function can also be used safely.
Time of Introduction
Architecture and Design
Implementation
Applicable Platforms
Languages
C
C++
Common Consequences
Scope
Effect
Other
Technical Impact: Varies by context; Quality degradation; Unexpected state
If the function is used incorrectly, then it could result in security
problems.
Likelihood of Exploit
High
Demonstrative Examples
Example 1
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.
Identify a list of prohibited API functions and prohibit developers from using these functions, providing safer alternatives. In some cases, automatic code analysis tools or the compiler can be instructed to spot use of prohibited functions, such as the "banned.h" include file from Microsoft's SDL. [R.676.1] [R.676.2]
Weakness Ordinalities
Ordinality
Description
Primary
(where
the weakness exists independent of other weaknesses)
This weakness is different than CWE-242 (Use of Inherently Dangerous Function). CWE-242 covers functions with such significant security problems that they can never be guaranteed to be safe. Some functions, if used properly, do not directly pose a security risk, but can introduce a weakness if not called correctly. These are regarded as potentially dangerous. A well-known example is the strcpy() function. When provided with a destination buffer that is larger than its source, strcpy() will not overflow. However, it is so often misused that some developers prohibit strcpy() entirely.
Causal Nature
Explicit
Taxonomy Mappings
Mapped Taxonomy Name
Node ID
Fit
Mapped Node Name
7 Pernicious Kingdoms
Dangerous Functions
CERT C Secure Coding
ERR07-C
Prefer functions that support error checking over equivalent
functions that don't
CERT C Secure Coding
FIO01-C
Be careful using functions that use file names for
identification
CERT C Secure Coding
INT06-C
Use strtol() or a related function to convert a string token
to an integer
CERT C++ Secure Coding
INT06-CPP
Use strtol() or a related function to convert a string token
to an integer
CERT C++ Secure Coding
FIO01-CPP
Be careful using functions that use file names for
identification
[R.676.2] [REF-11] M. Howard and
D. LeBlanc. "Writing Secure Code". Chapter 5, "Safe String Handling" Page 156,
160. 2nd Edition. Microsoft. 2002.
[R.676.3] [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.