360
Run your code using the lowest privileges that are required to accomplish the necessary tasks
[REF-76]. 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
Phase: Operation
Strategy = Sandbox or Jail
Run the code in a "jail" or similar sandbox environment that enforces strict boundaries between
the process and the operating system. This may effectively restrict which files can be accessed
in a particular directory or which commands can be executed by the software. OS-level examples
include the Unix chroot jail, AppArmor, and SELinux. In general, managed code may provide
some protection. For example, java.io.FilePermission in the Java SecurityManager allows the
software to specify restrictions on file operations. This may not be a feasible solution, and it
only limits the impact to the operating system; the rest of the application may still be subject to
compromise. Be careful to avoid CWE-243 and other weaknesses related to jails.
Effectiveness = Limited
The effectiveness of this mitigation depends on the prevention capabilities of the specific
sandbox or jail being used and might only help to reduce the scope of an attack, such as
restricting the attacker to certain system calls or limiting the portion of the file system that can be
accessed.
Demonstrative Examples
Example 1:
The following code allocates memory for a maximum number of widgets. It then gets a userspecified
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.
Example Language: C (Bad)
int i;
unsigned int numWidgets;
Widget **WidgetList;
numWidgets = GetUntrustedSizeValue();
if ((numWidgets == 0) || (numWidgets > MAX_NUM_WIDGETS)) {
ExitError("Incorrect number of widgets requested!");
}
WidgetList = (Widget **)malloc(numWidgets * sizeof(Widget *));
printf("WidgetList ptr=%p\n", WidgetList);
for(i=0; i<numWidgets; i++) {
WidgetList[i] = InitializeWidget();
}
WidgetList[numWidgets] = NULL;
showWidgets(WidgetList);
However, this code contains an off-by-one calculation error (CWE-193). 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 (CWE-131). So if
the user ever requests MAX_NUM_WIDGETS, there is an out-of-bounds write (CWE-787) 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.
CWE Version 4.14
CWE-131: Incorrect Calculation of Buffer Size
CWE-131: Incorrect Calculation of Buffer Size