Wiki Markup |
---|
According to the Java API \[[API 2006|AA. Bibliography#API 06]\] for class {{java.io.File}}: |
...
A path name,
...
whether
...
abstract
...
or
...
in
...
string
...
form,
...
may
...
be
...
either
...
absolute
...
or
...
relative.
...
An
...
absolute
...
path
...
name
...
is
...
complete
...
in
...
that
...
no
...
other
...
information
...
is
...
required
...
to
...
locate
...
the
...
file
...
that
...
it
...
denotes.
...
A
...
relative
...
path
...
name,
...
in
...
contrast,
...
must
...
be
...
interpreted
...
in
...
terms
...
of
...
information
...
taken
...
from
...
some
...
other
...
path
...
name.
...
Absolute or relative path names may contain file links such as symbolic (soft) links, hard links, short cuts, shadows, aliases, and junctions. These file links must be fully resolved before any file validation operations are performed. For example, the final target of a symbolic link called trace
might be the path name /home/system/trace
...
.
...
Path
...
names
...
may
...
also
...
contain
...
special
...
file
...
names
...
that
...
make
...
validation
...
difficult:
...
- "."
...
- refers
...
- to
...
- the
...
- directory
...
- itself.
...
- Inside
...
- a
...
- directory,
...
- the
...
- special
...
- file
...
- name
...
- ".."
...
- refers
...
- to
...
- the
...
- directory's
...
- parent
...
- directory.
...
In
...
addition
...
to
...
these
...
specific
...
issues,
...
there
...
are
...
a
...
wide
...
variety
...
of
...
operating
...
system-specific
...
and
...
file
...
system-specific
...
naming
...
conventions
...
that
...
make
...
validation
...
difficult.
...
The
...
process
...
of
...
canonicalizing
...
file
...
names
...
makes
...
it
...
easier
...
to
...
validate
...
a
...
path
...
name.
...
More
...
than
...
one
...
path
...
name
...
can
...
refer
...
to
...
a
...
single
...
directory
...
or
...
file.
...
Further,
...
the
...
textual
...
representation
...
of
...
a
...
path
...
name
...
may
...
yield
...
little
...
or
...
no
...
information
...
regarding
...
the
...
directory
...
or
...
file
...
to
...
which
...
it
...
refers.
...
Consequently,
...
all
...
path
...
names
...
must
...
be
...
fully
...
resolved
...
or
...
canonicalized
...
before
...
validation.
...
Validation
...
may
...
be
...
necessary,
...
for
...
example,
...
when
...
attempting
...
to
...
restrict
...
user
...
access
...
to
...
files
...
within
...
a
...
particular
...
directory
...
or
...
otherwise
...
make
...
security
...
decisions
...
based
...
on
...
the
...
name
...
of
...
a
...
file
...
name
...
or
...
path
...
name.
...
Frequently,
...
these
...
restrictions
...
can
...
be
...
circumvented
...
by
...
an
...
attacker
...
by
...
exploiting
...
a
...
directory
...
traversal
...
or
...
path
...
equivalence
...
vulnerability.
...
A
...
directory
...
traversal
...
vulnerability
...
allows
...
an
...
I/O
...
operation
...
to
...
escape
...
a
...
specified
...
operating
...
directory.
...
A
...
path
...
equivalence
...
vulnerability
...
occurs
...
when
...
an
...
attacker
...
provides
...
a
...
different
...
but
...
equivalent
...
name
...
for
...
a
...
resource
...
to
...
bypass
...
security
...
checks.
...
Canonicalization
...
contains
...
an
...
inherent
...
race
...
window
...
between
...
the
...
time
...
the
...
program
...
obtains
...
the
...
canonical
...
path
...
name
...
and
...
the
...
time
...
it
...
opens
...
the
...
file.
...
While
...
the
...
canonical
...
path
...
name
...
is
...
being
...
validated,
...
the
...
file
...
system
...
may
...
have
...
been
...
modified
...
and
...
the
...
canonical
...
path
...
name
...
may
...
no
...
longer
...
reference
...
the
...
original
...
valid
...
file.
...
Fortunately,
...
this
...
race
...
condition
...
can
...
be
...
easily
...
mitigated.
...
The
...
canonical
...
path
...
name
...
can
...
be
...
used
...
to
...
determine
...
whether
...
the
...
referenced
...
file
...
name
...
is
...
in
...
a
...
secure
...
directory
...
(see
...
rule
...
FIO00-J
...
for
...
more
...
information).
...
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
...
rule
...
IDS01-J.
...
Noncompliant
...
Code
...
Example
...
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.
...
It
...
also
...
uses
...
the
...
isInSecureDir()
...
method defined
...
in
...
rule
...
FIO00-J
...
to
...
ensure
...
that
...
the
...
file
...
is
...
in
...
a
...
secure
...
directory.
...
However,
...
it
...
neither
...
resolves
...
file
...
links
...
nor
...
eliminates
...
equivalence
...
errors.
Code Block | ||||
---|---|---|---|---|
| =
| |||
} public static void main(String[] args) { File f = new File(System.getProperty("user.home") + System.getProperty("file.separator") + args[0]); String absPath = f.getAbsolutePath(); if (!isInSecureDir(Paths.get(absPath))) { throw new IllegalArgumentException(); } if (!validate(absPath)) { // Validation throw new IllegalArgumentException(); } } {code} |
The
...
application
...
intends
...
to
...
restrict
...
the
...
user
...
from
...
operating
...
on
...
files
...
outside
...
of
...
their
...
home
...
directory.
...
The
...
validate()
...
method
...
attempts
...
to
...
ensure
...
that
...
the
...
path
...
name
...
resides
...
within
...
this
...
directory,
...
but
...
can
...
be
...
easily
...
circumvented.
...
For
...
example,
...
a
...
user
...
can
...
create
...
a
...
link
...
in
...
their
...
home
...
directory
...
that
...
refers
...
to
...
a
...
directory
...
or
...
file
...
outside
...
of
...
their
...
home
...
directory.
...
The
...
path
...
name
...
of
...
the
...
link
...
might
...
appear
...
to
...
the
...
validate()
...
method
...
to
...
reside
...
in
...
their
...
home
...
directory
...
and
...
consequently
...
pass
...
validation,
...
but
...
the
...
operation
...
will
...
actually
...
be
...
performed
...
on
...
the
...
final
...
target
...
of
...
the
...
link,
...
which
...
resides
...
outside
...
the
...
intended
...
directory.
...
Note
...
that
...
File.getAbsolutePath()
...
does
...
resolve
...
symbolic
...
links,
...
aliases,
...
and
...
short
...
cuts
...
on
...
Windows
...
and
...
Macintosh
...
platforms.
...
Nevertheless,
...
the
...
Java
...
Language
...
Specification
...
(JLS)
...
lacks
...
any
...
guarantee
...
that
...
this
...
behavior
...
is
...
present
...
on
...
all
...
platforms
...
or
...
that
...
it
...
will
...
continue
...
in
...
future
...
implementations.
...
Compliant
...
Solution
...
(
...
getCanonicalPath()
...
)
...
This
...
compliant
...
solution
...
uses
...
the
...
getCanonicalPath()
...
method,
...
introduced
...
in
...
Java
...
2,
...
because
...
it
...
resolves
...
all
...
aliases,
...
shortcuts,
...
and
...
symbolic
...
links
...
consistently
...
across
...
all
...
platforms.
...
Special
...
file
...
names
...
such
...
as
...
dot
...
dot
...
(
...
..
...
)
...
are
...
also
...
removed
...
so
...
that
...
the
...
input
...
is
...
reduced
...
to
...
a
...
canonicalized
...
form
...
before
...
validation
...
is
...
carried
...
out.
...
An
...
attacker
...
cannot
...
use
...
../
...
sequences
...
to
...
break
...
out
...
of
...
the
...
specified
...
directory
...
when
...
the
...
validate()
...
method
...
is
...
present.
Code Block | ||||
---|---|---|---|---|
| =
| |||
} public static void main(String[] args) throws IOException { File f = new File(System.getProperty("user.home") + System.getProperty("file.separator")+ args[0]); String canonicalPath = f.getCanonicalPath(); if (!isInSecureDir(Paths.get(canonicalPath))) { throw new IllegalArgumentException(); } if (!validate(canonicalPath)) { // Validation throw new IllegalArgumentException(); } } {code} The {{ |
The getCanonicalPath()
...
method
...
throws
...
a
...
security
...
exception
...
when
...
used
...
within
...
applets
...
because
...
it
...
reveals
...
too
...
much
...
information
...
about
...
the
...
host
...
machine.
...
The
...
getCanonicalFile()
...
method
...
behaves
...
like
...
getCanonicalPath()
...
but
...
returns
...
a
...
new
...
File
...
object
...
instead
...
of
...
a
...
String
...
.
Compliant Solution (Security
...
Manager)
...
A
...
comprehensive
...
way
...
of
...
handling
...
this
...
issue
...
is
...
to
...
grant
...
the
...
application
...
the
...
permissions
...
to
...
operate
...
only
...
on
...
files
...
present
...
within
...
the
...
intended
...
directory
...
— the
...
user's
...
home
...
directory
...
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
...
/home
...
/
...
me
and actions read
and write
.
Code Block | ||
---|---|---|
| ||
actions {{read}} and {{write}}. {code:bgColor=#ccccff} grant codeBase "file:/home/programpath/" { permission java.io.FilePermission "${user./home}/*me", "read, write"; }; {code} |
This
...
solution
...
requires
...
that
...
the
...
user's
...
home
...
directory
...
is
...
a
...
secure
...
directory
...
as
...
described
...
in
...
rule
...
FIO00-J.
Noncompliant Code Example
This noncompliant code example allows the user to specify the absolute path of a file name on which to operate. The user can specify files outside the intended directory (/img
in this example) by entering an argument that contains ../
sequences and consequently violates the intended security policies of the program.
Code Block | ||
---|---|---|
| ||
h2. Noncompliant Code Example This noncompliant code example allows the user to specify the absolute path of a file name on which to operate. The user can specify files outside the intended directory ({{/img}} in this example) by entering an argument that contains {{../}} sequences and consequently violates the intended security policies of the program. {code:bgColor=#FFCCCC} FileOutputStream fis = new FileOutputStream(new File("/img/" + args[0])); // ... {code} h2. Noncompliant Code Example This noncompliant code example attempts to mitigate the issue by using the {{ |
Noncompliant Code Example
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
...
.
...
Canonicalization
...
without
...
validation
...
is
...
insufficient
...
because
...
an
...
attacker
...
can
...
specify
...
files
...
outside
...
the
...
intended
...
directory.
Code Block | ||||
---|---|---|---|---|
| =
| |||
} File f = new File("/img/" + args[0]); String canonicalPath = f.getCanonicalPath(); FileOutputStream fis = new FileOutputStream(f); // ... {code} h2. Compliant Solution This compliant solution obtains the file name from the untrusted user input, canonicalizes it, and then validates it against a list of benign pathnames. It operates on the specified file only when validation succeeds; that is, only if the file is one of the two valid files {{file1.txt}} or {{file2.txt}} in {{/img/java}}. {code |
Compliant Solution
This compliant solution obtains the file name from the untrusted user input, canonicalizes it, and then validates it against a list of benign pathnames. It operates on the specified file only when validation succeeds; that is, only if the file is one of the two valid files file1.txt
or file2.txt
in /img/java
.
Code Block | ||
---|---|---|
| ||
:bgColor=#ccccff} File f = new File("/img/" + args[0]); String canonicalPath = f.getCanonicalPath(); if (!canonicalPath.equals("/img/java/file1.txt") && !canonicalPath.equals("/img/java/file2.txt")) { // Invalid file; handle error } FileInputStream fis = new FileInputStream(f); {code} The {{ |
The /img/java
...
directory
...
must
...
be
...
secure
...
to
...
eliminate
...
any
...
race
...
condition.
...
Compliant
...
Solution
...
(Security
...
Manager)
...
This
...
compliant
...
solution
...
grants
...
the
...
application
...
the
...
permissions
...
to
...
read
...
only
...
the
...
intended
...
files
...
or
...
directories.
...
For
...
example,
...
read
...
permission
...
is
...
granted
...
by
...
specifying
...
the
...
absolute
...
path
...
of
...
the
...
program
...
in
...
the
...
security
...
policy
...
file
...
and
...
granting
...
java.io.FilePermission
...
with
...
the
...
canonicalized
...
absolute
...
path
...
of
...
the
...
file
...
or
...
directory
...
as
...
the
...
target
...
name
...
and
...
with
...
the
...
action
...
set
...
to
...
read
...
.
Code Block | ||||
---|---|---|---|---|
| =
| |||
} // All files in /img/java can be read grant codeBase "file:/home/programpath/" { permission java.io.FilePermission "/img/java", "read"; }; {code} h2. 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. || Rule || Severity || Likelihood || Remediation Cost || Priority || Level || | IDS02-J | medium | unlikely | medium | {color:green}P4{color} | {color:green}L3{color} | h3. Related Vulnerabilities [CVE-2005-0789|http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2005-0789] describes a directory traversal vulnerability in LimeWire 3.9.6 through 4.6.0 that allows remote attackers to read arbitrary files via a .. (dot dot) in a magnet request. [CVE-2008-5518|http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-5518] describes multiple directory traversal vulnerabilities in the web administration console in Apache Geronimo Application Server 2.1 through 2.1.3 on Windows that allow remote attackers to upload files to arbitrary directories. h2. Related Guidelines | [The CERT C Secure Coding Standard|seccode:CERT C Secure Coding Standard] | [FIO02-C. Canonicalize path names originating from untrusted sources|seccode:FIO02-C. Canonicalize path names originating from untrusted sources] | | [The CERT C+\+ Secure Coding Standard|cplusplus:CERT C++ Secure Coding Standard] | [FIO02-CPP. Canonicalize path names originating from untrusted sources|cplusplus:FIO02-CPP. Canonicalize path names originating from untrusted sources] | | [ISO/IEC TR 24772:2010|http:// |
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.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
IDS02-J | medium | unlikely | medium | P4 | L3 |
Related Vulnerabilities
CVE-2005-0789 describes a directory traversal vulnerability in LimeWire 3.9.6 through 4.6.0 that allows remote attackers to read arbitrary files via a .. (dot dot) in a magnet request.
CVE-2008-5518 describes multiple directory traversal vulnerabilities in the web administration console in Apache Geronimo Application Server 2.1 through 2.1.3 on Windows that allow remote attackers to upload files to arbitrary directories.
Related Guidelines
FIO02-C. Canonicalize path names originating from untrusted sources | ||
FIO02-CPP. Canonicalize path names originating from untrusted sources | ||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="988b2a1b-21c8-4a48-9dd8-8c7d7915fb07"><ac:plain-text-body><![CDATA[ | [ISO/IEC TR 24772:2010 | http://www.aitcnet.org/isai/] |
...
Path |
...
Traversal |
...
[EWR |
...
] | ]]></ac:plain-text-body></ac:structured-macro> |
CWE-171. Cleansing, Canonicalization, and Comparison Errors | |
| CWE-647. Use of Non-Canonical URL Paths for Authorization Decisions |
Bibliography
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="8868c794-7f5e-4519-b656-6c9b4aa900c3"><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="eb86d40e-9fc9-4e60-bdad-552ae067396a"><ac:plain-text-body><![CDATA[ | [[Harold 1999 | AA. Bibliography#Harold 99]] |
| ]]></ac:plain-text-body></ac:structured-macro> |
...