Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This recommendation is a defense in depth strategy that aims at isolating a user program or a daemon Creating a jail isolates a program from the rest of the file system. It is applicable to programs that do not need to continually maintain superuser status. The central idea is to create a jail sandbox, so that entities that the program does not need to access under normal operation are made invisibleinaccessible. This makes it much harder to abuse a potential flaw that could any vulnerability that can otherwise lead to unconstrained system compromise and consequently functions as a defense-in-depth strategy. A jail may consist of world-viewable programs that require fewer resources to execute than those that possibly exist on that system. Jails are useful only useful when there is no way to elevate privileges in the event of program failure.

Additionally, care must be taken to ensure that all the required resources (such as libraries, files, and so on) are replicated within the jail directory and that no reference is made to other parts of the filesystem file system from within this directory. It is also advisable to administer restrictive read/write permissions on the jail directories and resources based on the basis of the program's privilege requirements. Although , creating jails is an effective security measure when used correctly, it is not a surrogate for additional security best practices.

...

compliance with the other rules and recommendations in this standard.

Noncompliant Code Example

A security flaw exists in the this noncompliant code shown below example resulting from the absence of proper canonicalization measures on the file path. This allows an attacker to traverse the filesystem file system and possibly write to a file of his the attacker's choice , with the privileges of the vulnerable program. For example, it maybe may be possible to overwrite the password file (such as the /etc/passwd, common to many POSIX-based systems) or a device file, such as the mouse, which in turn can aid further exploitation or cause a denial of service to occur.

Code Block
bgColor#ffcccc
langc
enum { array_max = 100 };

/*
 * Program running with elevated privileges where argv[1] is
 * and argv[2] are supplied by the user
 */

char x[array_max];
FILE *fp = fopen(argv[1], "w");

strncpy(x, argv[2], array_max);
x[array_max - 1] = '\0';

/*
 * argv[2] is also specified by the user and may be "foo:*:100:200:8A-74(home):/home/foo:/usr/bin/sh";  */

char x[100];
strncpy(x,argv[2],100);
x[100] = '\0';

Write operation to an unintended file such as /etc/passwd
 * gets executed
 */
if (fwrite(x, sizeof(x[0]), sizeof(x)/sizeof(x[0]), fp); <
  /*  Write operation to an unintended file like /etc/passwd gets executed sizeof(x)/sizeof(x[0])) {
  /* Handle error */
}

...

An attacker can control the value of {{argv\[1\]}} and consequently access any resource on the filesystemfile system.

This non-compliant coding noncompliant code example also violates FIO02-AC. Canonicalize path names originating from untrusted tainted sources and FIO03-AC. Do not make assumptions about fopen() and file creation.

Compliant Solution (UNIX)

Some Unix UNIX-based systems (such as OpenBSD) encourage restricting filesystem can restrict file system access by recommending the creation of creating a chroot() jail. This The chroot() jail requires care to implement securely [Wheeler 2003]. It is achieved by passing a predefined directory name as an argument to chroot(). The call to chroot() requires superuser privileges and thus the program should be set-uid root. However, this call does not 'leave' the process inside the jail directory as one would expect. The might be expected. A subsequent chdir() call that follows does just this and is indispensable when access is to be restricted to within is required to restrict access to the jail boundaries.

Another essential step is to drop superuser privileges permanently after these calls so as to be in agreement with (see POS02-C. Follow the principle of least privilege). The chroot() system call is not secure against the superuser changing the current root directory (if privileges are not dropped) and may be ineffective if the current working directory is not set to the new root directory immediately following the call to chroot(). Successful jail creation prevents unintentional filesystem file system access even if an attacker gives malicious input, such as through command-line arguments.

Code Block
bgColor#ccccff
langc


/*
 * Make sure that the ~/chroot/jail directory exists within
 * the  current working directory 
 *. Also assign appropriate
 * permissions to the directory to restrict access. Close
 * Closeall allfile filesystemsystem descriptors to outside resources lest
 * they escape the jail.
 */

 if (setuid(0) == -1) {
   /* ReportHandle that setuid failed and note the errno value error */
 }

 if (chroot("/chroot/jail") == -1) { 
  /* OperationHandle failed, handle error */  
}

 if (chdir("/") == -1) {
   /* Operation failed, handle Handle error */   
}

 /* Drop privileges permanently to those of the file owner */ 

 */
if (setgid(getgid()) == -1) {
  /* Handle error */
}

if (setuid(getuid()) == -1)  {
   /* Operation failed, handleHandle error */   
}

 /* Perform unprivileged operations */
enum {array_max = 100};

FILE FILE* fp = fopen(argv[1], "w");
char x[array_max];
strncpy(x, argv[2], array_max);
x[array_max - 1] = '\0';

/* Write operation is safe within jail */
if (fwrite(x, sizeof(x[0]), sizeof(x)/sizeof(x[0]), fp) <
    sizeof(x)/sizeof(x[0])) {
  /* Handle error */
}

An alternative sequence is to first call chdir("chroot/jail") and then call chroot("."). However, calling chdir("/some/path"), then chroot("/some/path"), should be avoided because this sequence The chdir() system call may be susceptible to a race condition if called before chroot(). This is because : an attacker with sufficient privileges can delete the 'jail' directory so that the chdir() operation fails and then recreate it so that chroot() succeedsarrange for /some/path to refer to different directories in the two system calls. Consequently, the program will not start in its sandboxed environment (~/chroot/jail) and will have its current working directory not set to ~/chroot/jail. One mitigation strategy is to incorporate error checking to detect if chdir() failed. A more fool proof method is to use chdir() after chroot() so that it the new root directory. Using either chdir("/") after chroot() or chroot(".") after chdir() guarantees that the current working directory will be set to the chroot'ed directory, that is same directory as the new root.

Risk Assessment

Failing to follow this recommendation , wherever possible, may lead to full-system compromise if a security file system vulnerability is uncovered in a program or daemondiscovered and exploited.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

POS02

POS05-

A

C

medium

Medium

probable

Probable

high

High

P4

L3

Automated Detection

ToolVersionCheckerDescription
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V
BADFUNC.CHROOT
MISC.CHROOT.NOCHDIR
Use of chroot
chroot without chdir
Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rec. POS05-C

Checks for file manipulation after chroot() without chdir("/") (rec. fully covered)

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Bibliography

...


...

Image AddedImage AddedImage Added