Skip to content

Commit a2c98ba

Browse files
committed
Reordering
1 parent eb1806c commit a2c98ba

File tree

1 file changed

+87
-86
lines changed

1 file changed

+87
-86
lines changed

java/ql/src/experimental/Security/CWE/CWE-552/UnsafeUrlForward.qll

Lines changed: 87 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,37 @@ import semmle.code.java.frameworks.spring.SpringWeb
77
import semmle.code.java.security.RequestForgery
88
private import semmle.code.java.dataflow.StringPrefixes
99

10-
/** A sanitizer for unsafe url forward vulnerabilities. */
10+
/** A sink for unsafe URL forward vulnerabilities. */
11+
abstract class UnsafeUrlForwardSink extends DataFlow::Node { }
12+
13+
/** A sanitizer for unsafe URL forward vulnerabilities. */
1114
abstract class UnsafeUrlForwardSanitizer extends DataFlow::Node { }
1215

16+
/** A barrier guard that protects against URL forward vulnerabilities. */
17+
abstract class UnsafeUrlForwardBarrierGuard extends DataFlow::BarrierGuard { }
18+
19+
/** An argument to `getRequestDispatcher`. */
20+
private class RequestDispatcherSink extends UnsafeUrlForwardSink {
21+
RequestDispatcherSink() {
22+
exists(MethodAccess ma |
23+
ma.getMethod() instanceof GetRequestDispatcherMethod and
24+
ma.getArgument(0) = this.asExpr()
25+
)
26+
}
27+
}
28+
29+
/** An argument to `new ModelAndView` or `ModelAndView.setViewName`. */
30+
private class SpringModelAndViewSink extends UnsafeUrlForwardSink {
31+
SpringModelAndViewSink() {
32+
exists(ClassInstanceExpr cie |
33+
cie.getConstructedType() instanceof ModelAndView and
34+
cie.getArgument(0) = this.asExpr()
35+
)
36+
or
37+
exists(SpringModelAndViewSetViewNameCall smavsvnc | smavsvnc.getArgument(0) = this.asExpr())
38+
}
39+
}
40+
1341
private class PrimitiveSanitizer extends UnsafeUrlForwardSanitizer {
1442
PrimitiveSanitizer() {
1543
this.getType() instanceof PrimitiveType or
@@ -31,74 +59,6 @@ private class FollowsSanitizingPrefix extends UnsafeUrlForwardSanitizer {
3159
FollowsSanitizingPrefix() { this.asExpr() = any(SanitizingPrefix fp).getAnAppendedExpression() }
3260
}
3361

34-
/** A barrier guard that protects against URL forward vulnerabilities. */
35-
abstract class UnsafeUrlForwardBarrierGuard extends DataFlow::BarrierGuard { }
36-
37-
/**
38-
* Holds if `ma` is a call to a method that checks a path string.
39-
*/
40-
private predicate isStringPathMatch(MethodAccess ma) {
41-
ma.getMethod().getDeclaringType() instanceof TypeString and
42-
ma.getMethod().getName() =
43-
["contains", "startsWith", "matches", "regionMatches", "indexOf", "lastIndexOf"]
44-
}
45-
46-
/**
47-
* Holds if `ma` is a call to a method of `java.nio.file.Path` that checks a path.
48-
*/
49-
private predicate isFilePathMatch(MethodAccess ma) {
50-
ma.getMethod().getDeclaringType() instanceof TypePath and
51-
ma.getMethod().getName() = "startsWith"
52-
}
53-
54-
/** A complementary guard that protects against path traversal, by looking for the literal `..`. */
55-
private class PathTraversalGuard extends Guard instanceof MethodAccess {
56-
Expr checked;
57-
58-
PathTraversalGuard() {
59-
this.getMethod().getDeclaringType() instanceof TypeString and
60-
this.getMethod().hasName(["contains", "indexOf"]) and
61-
this.getAnArgument().(CompileTimeConstantExpr).getStringValue() = ".." and
62-
this.controls(checked.getBasicBlock(), false)
63-
}
64-
65-
predicate checks(Expr e) { checked = e }
66-
}
67-
68-
/** A complementary sanitizer that protects against path traversal using path normalization. */
69-
private class PathNormalizeSanitizer extends MethodAccess {
70-
PathNormalizeSanitizer() {
71-
this.getMethod().getDeclaringType().hasQualifiedName("java.nio.file", "Path") and
72-
this.getMethod().hasName("normalize")
73-
}
74-
}
75-
76-
/** A complementary guard that protects against double URL encoding, by looking for the literal `%`. */
77-
private class UrlEncodingGuard extends Guard instanceof MethodAccess {
78-
Expr checked;
79-
80-
UrlEncodingGuard() {
81-
this.getMethod().getDeclaringType() instanceof TypeString and
82-
this.getMethod().hasName(["contains", "indexOf"]) and
83-
this.getAnArgument().(CompileTimeConstantExpr).getStringValue() = "%" and
84-
this.controls(checked.getBasicBlock(), false)
85-
}
86-
87-
predicate checks(Expr e) { checked = e }
88-
}
89-
90-
/** A complementary sanitizer that protects against double URL encoding using URL decoding. */
91-
private class UrlDecodeSanitizer extends MethodAccess {
92-
UrlDecodeSanitizer() {
93-
this.getMethod().getDeclaringType().hasQualifiedName("java.net", "URLDecoder") and
94-
this.getMethod().hasName("decode")
95-
}
96-
}
97-
98-
private predicate isDisallowedWord(CompileTimeConstantExpr word) {
99-
word.getStringValue().matches(["%WEB-INF%", "%META-INF%", "%..%"])
100-
}
101-
10262
/**
10363
* A guard that considers safe a string being exactly compared to a trusted value.
10464
*/
@@ -176,27 +136,68 @@ private class BlockListCheckGuard extends UnsafeUrlForwardBarrierGuard instanceo
176136
}
177137
}
178138

179-
abstract class UnsafeUrlForwardSink extends DataFlow::Node { }
139+
/**
140+
* Holds if `ma` is a call to a method that checks a path string.
141+
*/
142+
private predicate isStringPathMatch(MethodAccess ma) {
143+
ma.getMethod().getDeclaringType() instanceof TypeString and
144+
ma.getMethod().getName() =
145+
["contains", "startsWith", "matches", "regionMatches", "indexOf", "lastIndexOf"]
146+
}
180147

181-
/** An argument to `getRequestDispatcher`. */
182-
private class RequestDispatcherSink extends UnsafeUrlForwardSink {
183-
RequestDispatcherSink() {
184-
exists(MethodAccess ma |
185-
ma.getMethod() instanceof GetRequestDispatcherMethod and
186-
ma.getArgument(0) = this.asExpr()
187-
)
148+
/**
149+
* Holds if `ma` is a call to a method of `java.nio.file.Path` that checks a path.
150+
*/
151+
private predicate isFilePathMatch(MethodAccess ma) {
152+
ma.getMethod().getDeclaringType() instanceof TypePath and
153+
ma.getMethod().getName() = "startsWith"
154+
}
155+
156+
private predicate isDisallowedWord(CompileTimeConstantExpr word) {
157+
word.getStringValue().matches(["%WEB-INF%", "%META-INF%", "%..%"])
158+
}
159+
160+
/** A complementary guard that protects against path traversal, by looking for the literal `..`. */
161+
private class PathTraversalGuard extends Guard instanceof MethodAccess {
162+
Expr checked;
163+
164+
PathTraversalGuard() {
165+
this.getMethod().getDeclaringType() instanceof TypeString and
166+
this.getMethod().hasName(["contains", "indexOf"]) and
167+
this.getAnArgument().(CompileTimeConstantExpr).getStringValue() = ".." and
168+
this.controls(checked.getBasicBlock(), false)
188169
}
170+
171+
predicate checks(Expr e) { checked = e }
189172
}
190173

191-
/** An argument to `new ModelAndView` or `ModelAndView.setViewName`. */
192-
private class SpringModelAndViewSink extends UnsafeUrlForwardSink {
193-
SpringModelAndViewSink() {
194-
exists(ClassInstanceExpr cie |
195-
cie.getConstructedType() instanceof ModelAndView and
196-
cie.getArgument(0) = this.asExpr()
197-
)
198-
or
199-
exists(SpringModelAndViewSetViewNameCall smavsvnc | smavsvnc.getArgument(0) = this.asExpr())
174+
/** A complementary sanitizer that protects against path traversal using path normalization. */
175+
private class PathNormalizeSanitizer extends MethodAccess {
176+
PathNormalizeSanitizer() {
177+
this.getMethod().getDeclaringType().hasQualifiedName("java.nio.file", "Path") and
178+
this.getMethod().hasName("normalize")
179+
}
180+
}
181+
182+
/** A complementary guard that protects against double URL encoding, by looking for the literal `%`. */
183+
private class UrlEncodingGuard extends Guard instanceof MethodAccess {
184+
Expr checked;
185+
186+
UrlEncodingGuard() {
187+
this.getMethod().getDeclaringType() instanceof TypeString and
188+
this.getMethod().hasName(["contains", "indexOf"]) and
189+
this.getAnArgument().(CompileTimeConstantExpr).getStringValue() = "%" and
190+
this.controls(checked.getBasicBlock(), false)
191+
}
192+
193+
predicate checks(Expr e) { checked = e }
194+
}
195+
196+
/** A complementary sanitizer that protects against double URL encoding using URL decoding. */
197+
private class UrlDecodeSanitizer extends MethodAccess {
198+
UrlDecodeSanitizer() {
199+
this.getMethod().getDeclaringType().hasQualifiedName("java.net", "URLDecoder") and
200+
this.getMethod().hasName("decode")
200201
}
201202
}
202203

0 commit comments

Comments
 (0)