Skip to content

Commit 1b374e2

Browse files
committed
C#: Replace deprecated barrier guards.
1 parent 456f02f commit 1b374e2

File tree

4 files changed

+58
-63
lines changed

4 files changed

+58
-63
lines changed

csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,6 @@ private import semmle.code.csharp.frameworks.WCF
1919
*/
2020
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
2121

22-
/**
23-
* Holds if `guard` should be a sanitizer guard in all global taint flow configurations
24-
* but not in local taint.
25-
*/
26-
predicate defaultTaintSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
27-
2822
/**
2923
* Holds if default `TaintTracking::Configuration`s should allow implicit reads
3024
* of `c` at sinks and inputs to additional taint steps.

csharp/ql/lib/semmle/code/csharp/security/dataflow/UrlRedirectQuery.qll

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@ abstract class Sink extends DataFlow::ExprNode { }
2626
abstract class Sanitizer extends DataFlow::ExprNode { }
2727

2828
/**
29+
* DEPRECATED: Use `Sanitizer` instead.
30+
*
2931
* A guard for unvalidated URL redirect vulnerabilities.
3032
*/
31-
abstract class SanitizerGuard extends DataFlow::BarrierGuard { }
33+
abstract deprecated class SanitizerGuard extends DataFlow::BarrierGuard { }
3234

3335
/**
3436
* A taint-tracking configuration for reasoning about unvalidated URL redirect vulnerabilities.
@@ -42,7 +44,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
4244

4345
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
4446

45-
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
47+
deprecated override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
4648
guard instanceof SanitizerGuard
4749
}
4850
}
@@ -102,16 +104,17 @@ class HttpServerTransferSink extends Sink {
102104
}
103105
}
104106

107+
private predicate isLocalUrlSanitizer(Guard g, Expr e, AbstractValue v) {
108+
g.(MethodCall).getTarget().hasName("IsLocalUrl") and
109+
e = g.(MethodCall).getArgument(0) and
110+
v.(AbstractValues::BooleanValue).getValue() = true
111+
}
112+
105113
/**
106114
* A URL argument to a call to `UrlHelper.isLocalUrl()` that is a sanitizer for URL redirects.
107115
*/
108-
class IsLocalUrlSanitizer extends SanitizerGuard, MethodCall {
109-
IsLocalUrlSanitizer() { this.getTarget().hasName("IsLocalUrl") }
110-
111-
override predicate checks(Expr e, AbstractValue v) {
112-
e = this.getArgument(0) and
113-
v.(AbstractValues::BooleanValue).getValue() = true
114-
}
116+
class LocalUrlSanitizer extends Sanitizer {
117+
LocalUrlSanitizer() { this = DataFlow::BarrierGuard<isLocalUrlSanitizer/3>::getABarrierNode() }
115118
}
116119

117120
/**

csharp/ql/lib/semmle/code/csharp/security/dataflow/ZipSlipQuery.qll

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ abstract class Sink extends DataFlow::ExprNode { }
2121
abstract class Sanitizer extends DataFlow::ExprNode { }
2222

2323
/**
24+
* DEPRECATED: Use `Sanitizer` instead.
25+
*
2426
* A guard for unsafe zip extraction.
2527
*/
26-
abstract class SanitizerGuard extends DataFlow::BarrierGuard { }
28+
abstract deprecated class SanitizerGuard extends DataFlow::BarrierGuard { }
2729

2830
/** A taint tracking configuration for Zip Slip */
2931
class TaintTrackingConfiguration extends TaintTracking::Configuration {
@@ -35,7 +37,7 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration {
3537

3638
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
3739

38-
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
40+
deprecated override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
3941
guard instanceof SanitizerGuard
4042
}
4143
}
@@ -126,26 +128,22 @@ class SubstringSanitizer extends Sanitizer {
126128
}
127129
}
128130

131+
private predicate stringCheckGuard(Guard g, Expr e, AbstractValue v) {
132+
g.(MethodCall).getTarget().hasQualifiedName("System.String", "StartsWith") and
133+
g.(MethodCall).getQualifier() = e and
134+
// A StartsWith check against Path.Combine is not sufficient, because the ".." elements have
135+
// not yet been resolved.
136+
not exists(MethodCall combineCall |
137+
combineCall.getTarget().hasQualifiedName("System.IO.Path", "Combine") and
138+
DataFlow::localExprFlow(combineCall, e)
139+
) and
140+
v.(AbstractValues::BooleanValue).getValue() = true
141+
}
142+
129143
/**
130144
* A call to `String.StartsWith()` that indicates that the tainted path value is being
131145
* validated to ensure that it occurs within a permitted output path.
132146
*/
133-
class StringCheckGuard extends SanitizerGuard, MethodCall {
134-
private Expr q;
135-
136-
StringCheckGuard() {
137-
this.getTarget().hasQualifiedName("System.String", "StartsWith") and
138-
this.getQualifier() = q and
139-
// A StartsWith check against Path.Combine is not sufficient, because the ".." elements have
140-
// not yet been resolved.
141-
not exists(MethodCall combineCall |
142-
combineCall.getTarget().hasQualifiedName("System.IO.Path", "Combine") and
143-
DataFlow::localExprFlow(combineCall, q)
144-
)
145-
}
146-
147-
override predicate checks(Expr e, AbstractValue v) {
148-
e = q and
149-
v.(AbstractValues::BooleanValue).getValue() = true
150-
}
147+
class StringCheckSanitizer extends Sanitizer {
148+
StringCheckSanitizer() { this = DataFlow::BarrierGuard<stringCheckGuard/3>::getABarrierNode() }
151149
}

csharp/ql/src/experimental/CWE-918/RequestForgery.qll

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ module RequestForgery {
1818
abstract private class Sink extends DataFlow::ExprNode { }
1919

2020
/**
21-
* A data flow BarrierGuard which blocks the flow of taint for
21+
* A data flow Barrier that blocks the flow of taint for
2222
* server side request forgery vulnerabilities.
2323
*/
24-
abstract private class BarrierGuard extends DataFlow::BarrierGuard { }
24+
abstract private class Barrier extends DataFlow::Node { }
2525

2626
/**
2727
* A data flow configuration for detecting server side request forgery vulnerabilities.
@@ -51,9 +51,7 @@ module RequestForgery {
5151
pathCombineStep(prev, succ)
5252
}
5353

54-
override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
55-
guard instanceof BarrierGuard
56-
}
54+
override predicate isBarrier(DataFlow::Node node) { node instanceof Barrier }
5755
}
5856

5957
/**
@@ -129,36 +127,38 @@ module RequestForgery {
129127
* to be a guard for Server Side Request Forgery(SSRF) Vulnerabilities.
130128
* This guard considers all checks as valid.
131129
*/
132-
private class BaseUriGuard extends BarrierGuard, MethodCall {
133-
BaseUriGuard() { this.getTarget().hasQualifiedName("System.Uri", "IsBaseOf") }
134-
135-
override predicate checks(Expr e, AbstractValue v) {
136-
// we consider any checks against the tainted value to sainitize the taint.
137-
// This implies any check such as shown below block the taint flow.
138-
// Uri url = new Uri("whitelist.com")
139-
// if (url.isBaseOf(`taint1))
140-
(e = this.getArgument(0) or e = this.getQualifier()) and
141-
v.(AbstractValues::BooleanValue).getValue() = true
142-
}
130+
private predicate baseUriGuard(Guard g, Expr e, AbstractValue v) {
131+
g.(MethodCall).getTarget().hasQualifiedName("System.Uri", "IsBaseOf") and
132+
// we consider any checks against the tainted value to sainitize the taint.
133+
// This implies any check such as shown below block the taint flow.
134+
// Uri url = new Uri("whitelist.com")
135+
// if (url.isBaseOf(`taint1))
136+
(e = g.(MethodCall).getArgument(0) or e = g.(MethodCall).getQualifier()) and
137+
v.(AbstractValues::BooleanValue).getValue() = true
138+
}
139+
140+
private class BaseUriBarrier extends Barrier {
141+
BaseUriBarrier() { this = DataFlow::BarrierGuard<baseUriGuard/3>::getABarrierNode() }
143142
}
144143

145144
/**
146145
* A method call which checks if the Uri starts with a white-listed string is assumed
147146
* to be a guard for Server Side Request Forgery(SSRF) Vulnerabilities.
148147
* This guard considers all checks as valid.
149148
*/
150-
private class StringStartsWithBarrierGuard extends BarrierGuard, MethodCall {
151-
StringStartsWithBarrierGuard() {
152-
this.getTarget().hasQualifiedName("System.String", "StartsWith")
153-
}
154-
155-
override predicate checks(Expr e, AbstractValue v) {
156-
// Any check such as the ones shown below
157-
// "https://myurl.com/".startsWith(`taint`)
158-
// `taint`.startsWith("https://myurl.com/")
159-
// are assumed to sainitize the taint
160-
(e = this.getQualifier() or this.getArgument(0) = e) and
161-
v.(AbstractValues::BooleanValue).getValue() = true
149+
private predicate stringStartsWithGuard(Guard g, Expr e, AbstractValue v) {
150+
g.(MethodCall).getTarget().hasQualifiedName("System.String", "StartsWith") and
151+
// Any check such as the ones shown below
152+
// "https://myurl.com/".startsWith(`taint`)
153+
// `taint`.startsWith("https://myurl.com/")
154+
// are assumed to sainitize the taint
155+
(e = g.(MethodCall).getQualifier() or g.(MethodCall).getArgument(0) = e) and
156+
v.(AbstractValues::BooleanValue).getValue() = true
157+
}
158+
159+
private class StringStartsWithBarrier extends Barrier {
160+
StringStartsWithBarrier() {
161+
this = DataFlow::BarrierGuard<stringStartsWithGuard/3>::getABarrierNode()
162162
}
163163
}
164164

0 commit comments

Comments
 (0)