Skip to content

Commit 471d467

Browse files
authored
Merge pull request #74 from microsoft/users/chanely/insecure-sql-connection-versioncheck
Update to insecure sql connection to check for version
2 parents ee338e3 + 5dd5e80 commit 471d467

File tree

1 file changed

+36
-17
lines changed

1 file changed

+36
-17
lines changed

csharp/ql/src/Security Features/CWE-327/InsecureSQLConnection.ql

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,33 +13,50 @@
1313
import csharp
1414
import InsecureSqlConnection::PathGraph
1515

16-
/**
17-
* A data flow configuration for tracking strings passed to `SqlConnection[StringBuilder]` instances.
18-
*/
19-
module InsecureSqlConnectionConfig implements DataFlow::ConfigSig {
20-
predicate isSource(DataFlow::Node source) {
21-
exists(string s | s = source.asExpr().(StringLiteral).getValue().toLowerCase() |
22-
s.matches("%encrypt=false%")
23-
or
24-
not s.matches("%encrypt=%")
16+
class Source extends DataFlow::Node {
17+
string sourcestring;
18+
19+
Source() {
20+
sourcestring = this.asExpr().(StringLiteral).getValue().toLowerCase() and
21+
(
22+
not sourcestring.matches("%encrypt=%") or
23+
sourcestring.matches("%encrypt=false%")
2524
)
2625
}
2726

28-
predicate isSink(DataFlow::Node sink) {
27+
predicate setsEncryptFalse() { sourcestring.matches("%encrypt=false%") }
28+
}
29+
30+
class Sink extends DataFlow::Node {
31+
Version version;
32+
33+
Sink() {
2934
exists(ObjectCreation oc |
30-
oc.getRuntimeArgument(0) = sink.asExpr() and
35+
oc.getRuntimeArgument(0) = this.asExpr() and
3136
(
3237
oc.getType().getName() = "SqlConnectionStringBuilder"
3338
or
3439
oc.getType().getName() = "SqlConnection"
3540
) and
36-
not exists(MemberInitializer mi |
37-
mi = oc.getInitializer().(ObjectInitializer).getAMemberInitializer() and
38-
mi.getLValue().(PropertyAccess).getTarget().getName() = "Encrypt" and
39-
mi.getRValue().(BoolLiteral).getValue() = "true"
40-
)
41+
version = oc.getType().getALocation().(Assembly).getVersion()
4142
)
4243
}
44+
45+
predicate isEncryptedByDefault() { version.compareTo("4.0") >= 0 }
46+
}
47+
48+
predicate isEncryptTrue(Source source, Sink sink) {
49+
sink.isEncryptedByDefault() and
50+
not source.setsEncryptFalse()
51+
}
52+
53+
/**
54+
* A data flow configuration for tracking strings passed to `SqlConnection[StringBuilder]` instances.
55+
*/
56+
module InsecureSqlConnectionConfig implements DataFlow::ConfigSig {
57+
predicate isSource(DataFlow::Node source) { source instanceof Source }
58+
59+
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
4360
}
4461

4562
/**
@@ -48,7 +65,9 @@ module InsecureSqlConnectionConfig implements DataFlow::ConfigSig {
4865
module InsecureSqlConnection = DataFlow::Global<InsecureSqlConnectionConfig>;
4966

5067
from InsecureSqlConnection::PathNode source, InsecureSqlConnection::PathNode sink
51-
where InsecureSqlConnection::flowPath(source, sink)
68+
where
69+
InsecureSqlConnection::flowPath(source, sink) and
70+
not isEncryptTrue(source.getNode().(Source), sink.getNode().(Sink))
5271
select sink.getNode(), source, sink,
5372
"$@ flows to this SQL connection and does not specify `Encrypt=True`.", source.getNode(),
5473
"Connection string"

0 commit comments

Comments
 (0)