Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b5ca2c3

Browse files
committed
Add additional tests from real world query run
1 parent 7122f29 commit b5ca2c3

3 files changed

Lines changed: 72 additions & 2 deletions

File tree

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
<p>Accessing paths controlled by users can allow an attacker to access unexpected resources. This
7+
can result in sensitive information being revealed or deleted, or an attacker being able to influence
8+
behavior by modifying unexpected files.</p>
9+
10+
<p>Paths that are naively constructed from data controlled by a user may contain unexpected special characters,
11+
such as "..". Such a path may potentially point to any directory on the file system.</p>
12+
13+
</overview>
14+
<recommendation>
15+
16+
<p>Validate user input before using it to construct a file path. Ideally, follow these rules:</p>
17+
18+
<ul>
19+
<li>Do not allow more than a single "." character.</li>
20+
<li>Do not allow directory separators such as "/" or "\" (depending on the file system).</li>
21+
<li>Do not rely on simply replacing problematic sequences such as "../". For example, after applying this filter to
22+
".../...//" the resulting string would still be "../".</li>
23+
<li>Ideally use a whitelist of known good patterns.</li>
24+
</ul>
25+
26+
</recommendation>
27+
<example>
28+
29+
<p>In this example, a file name is read from a <code>java.net.Socket</code> and then used to access a file in the
30+
user's home directory and send it back over the socket. However, a malicious user could enter a file name which contains special
31+
characters. For example, the string "../../etc/passwd" will result in the code reading the file located at
32+
"/home/[user]/../../etc/passwd", which is the system's password file. This file would then be sent back to the user,
33+
giving them access to all the system's passwords.</p>
34+
35+
<sample src="PartialPathTraversal.java" />
36+
37+
</example>
38+
<references>
39+
40+
<li>
41+
OWASP:
42+
<a href="https://owasp.org/www-community/attacks/Path_Traversal">Path Traversal</a>.
43+
</li>
44+
45+
</references>
46+
</qhelp>

java/ql/src/Security/CWE/CWE-023/PartialPathTraversal.ql

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,24 @@ class SystemPropFileSeparatorExpr extends FileSeparatorExpr {
3939
}
4040

4141
class StringLiteralFileSeparatorExpr extends FileSeparatorExpr, StringLiteral {
42-
StringLiteralFileSeparatorExpr() { this.getValue() = "/" }
42+
StringLiteralFileSeparatorExpr() {
43+
this.getValue().matches("%/") or this.getValue().matches("%\\")
44+
}
45+
}
46+
47+
class CharacterLiteralFileSeparatorExpr extends FileSeparatorExpr, CharacterLiteral {
48+
CharacterLiteralFileSeparatorExpr() { this.getValue() = "/" or this.getValue() = "\\" }
4349
}
4450

4551
class FileSeparatorAppend extends AddExpr {
4652
FileSeparatorAppend() { this.getRightOperand() instanceof FileSeparatorExpr }
4753
}
4854

49-
predicate isSafe(Expr expr) { DataFlow::localExprFlow(any(FileSeparatorAppend fsa), expr) }
55+
predicate isSafe(Expr expr) {
56+
DataFlow::localExprFlow(any(Expr e |
57+
e instanceof FileSeparatorAppend or e instanceof FileSeparatorExpr
58+
), expr)
59+
}
5060

5161
from MethodAccess ma
5262
where

java/ql/test/query-tests/security/CWE-023/semmle/tests/PartialPathTraversalTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,22 @@ void foo23(File dir, File parent) throws IOException {
218218
}
219219
}
220220

221+
void foo24(File dir, File parent) throws IOException {
222+
String parentCanonical = parent.getCanonicalPath();
223+
if (!dir.getCanonicalPath().startsWith(parentCanonical + '/')) {
224+
throw new IOException("Invalid directory: " + dir.getCanonicalPath());
225+
}
226+
}
227+
221228
public void doesNotFlag() {
222229
"hello".startsWith("goodbye");
223230
}
224231

232+
public void doesNotFlagBackslash(File file) throws IOException {
233+
// https://github.com/jenkinsci/jenkins/blob/be3cf6bffe7aa2fe2307c424fa418519f3bbd73b/core/src/main/java/hudson/util/jna/Kernel32Utils.java#L77-L77
234+
if (!file.getCanonicalPath().startsWith("\\\\")) {
235+
throw new RuntimeException("Boom");
236+
}
237+
}
238+
225239
}

0 commit comments

Comments
 (0)