Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: added secure directory requirement to code samples

...

During this time the canonical path name may have been modified and may no longer be referencing a valid file. The canonical path name can be used to determine if the referenced file name is in a secure directory (see FIO00-J. Do not operate on files in shared directories). If the referenced file is in a secure directory, then by definition, an attacker cannot tamper with it, and cannot exploit the race condition.

This rule is a specific instance of IDS01-J. Normalize strings before validating them.

...

This noncompliant code example accepts a file path as a command line argument and uses the File.getAbsolutePath() method to obtain the absolute file path. This method It also uses the isInSecureDir() method defined in FIO00-J. Do not operate on files in shared directories to ensure that the file is in a secure directory. But it does not resolve file links or eliminate equivalence errors.

Code Block
bgColor#FFcccc
public static void main(String[] args) {
  File f = new File("/tmphome/me/" + args[0]);
  String absPath = f.getAbsolutePath();

  if (!isInSecureDir(Paths.get( absPath))) {
    throw new IllegalArgumentException();
  }
  if (!validate(absPath)) {  // Validation
    throw new IllegalArgumentException();
  }		  
}

Wiki Markup
The application intends to restrict the user from operating on files outside the {{/tmphome/me}} directory and uses a {{validate()}} method to enforce this condition. The path name validation can be easily circumvented.  For example, if the directory were not seucre, an attacker who can create symbolic links in {{/tmphome/me}} can cause the program to pass validation checks by supplying the unresolved path. All file operations performed are reflected in the file pointed to by the symbolic link. If the string {{filename}} is passed as {{argv\[0\]}} and {{/tmphome/me/filename}} is a symbolic link that refers to {{/dirname/filename}} the validation passes.  This is because the root directory of the compiled path name is still {{/tmphome/me}}, but the operations are carried out on the file {{/dirname/filename}}.

...

Code Block
bgColor#ccccff
public static void main(String[] args) throws IOException {
  File f = new File("/tmphome/me/" + args[0]);
  String canonicalPath = f.getCanonicalPath();

  if (!isInSecureDir(Paths.get(canonicalPath))) {
    throw new IllegalArgumentException();
  }
  if (!validate(canonicalPath)) {  // Validation
    throw new IllegalArgumentException();
  }
}

...

A comprehensive way of handling this issue is to grant the application the permissions to operate only on files present within the intended directory — /tmphome/me in this example. This compliant solution specifies the absolute path of the program in its security policy file, and grants java.io.FilePermission with target /tmphome/me and actions read and write.

Code Block
bgColor#ccccff
grant codeBase "file:/home/programpath/" {
  permission java.io.FilePermission "/tmphome/me", "read, write";
};

See rule ENV02-J. Create a secure sandbox using a Security Manager for additional information on using security managersThis solution does require that /home/me must be a secure directory, and associated code should check this requirement and abort if it is not met.

Noncompliant Code Example

...

Noncompliant Code Example

The following code examples assume that /img and /img/java are secure directories.

This noncompliant code example attempts to mitigate the issue by using the File.getCanonicalPath() method, which fully resolves the argument and constructs a canonicalized path. For example, the path /img/../etc/passwd resolves to /etc/passwd. Validation without canonicalization remains insecure because the user can specify files outside the intended directory.

...

Code Block
bgColor#ccccff
// All files in /img/java can be read
grant codeBase "file:/home/programpath/" {
  permission java.io.FilePermission "/img/java", "read";
};

See rule ENV02-J. Create a secure sandbox using a Security Manager for additional information on using security managers.

Risk Assessment

Using path names from untrusted sources without first canonicalizing them and then validating them can result in directory traversal and path equivalence vulnerabilities.

...

CERT C Secure Coding Standard

FIO02-C. Canonicalize path names originating from untrusted sources

CERT C++ Secure Coding Standard

FIO02-CPP. Canonicalize path names originating from untrusted sources

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="8dd8939a5e50f6a0-fd7c6c78-47c8491a-83c2b718-d1ac5de2578ad92fc740a874"><ac:plain-text-body><![CDATA[

[[MITRE 2009

AA. Bibliography#MITRE 09]]

[CWE ID 171

http://cwe.mitre.org/data/definitions/171.html] "Cleansing, Canonicalization, and Comparison Errors"]]></ac:plain-text-body></ac:structured-macro>

 

CWE ID 647 "Use of Non-Canonical URL Paths for Authorization Decisions"

...

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="af925a6b5681f28c-9058c19f-4d7540c9-9666a12a-e9e7923be933b02c10fe2039"><ac:plain-text-body><![CDATA[

[[API 2006

AA. Bibliography#API 06]]

[method getCanonicalPath()

http://java.sun.com/javase/6/docs/api/java/io/File.html#getCanonicalPath()]

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="4dbee4a7bb0ac3ea-6bf4eea0-448c43a1-aa3c92d9-5ec83d8047c352ec5b08d763"><ac:plain-text-body><![CDATA[

[[Harold 1999

AA. Bibliography#Harold 99]]

 

]]></ac:plain-text-body></ac:structured-macro>

...