Skip to content

Commit 64aca26

Browse files
Fixing a false positive in cs/insecure-sql-connection, and adding a new query to remediate a false negative
1 parent 421258b commit 64aca26

File tree

9 files changed

+145
-4
lines changed

9 files changed

+145
-4
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import csharp
1414
import InsecureSqlConnection::PathGraph
15+
import InsecureSQLConnection
1516

1617
class Source extends DataFlow::Node {
1718
string sourcestring;
@@ -48,6 +49,11 @@ class Sink extends DataFlow::Node {
4849
predicate isEncryptTrue(Source source, Sink sink) {
4950
sink.isEncryptedByDefault() and
5051
not source.setsEncryptFalse()
52+
or
53+
exists(ObjectCreation oc, Expr e | oc.getRuntimeArgument(0) = sink.asExpr() |
54+
getInfoForInitializedConnEncryption(oc, e) and
55+
e.getValue().toString().toLowerCase() = "true"
56+
)
5157
}
5258

5359
/**
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import csharp
2+
3+
/**
4+
* Holds if `ObjectCreation` has an initializer for a member named `Encrypt`, set to `e`
5+
*/
6+
predicate getInfoForInitializedConnEncryption(ObjectCreation oc, Expr e) {
7+
exists(MemberInitializer mi | mi.getInitializedMember().hasName("Encrypt") |
8+
e = mi.getRValue() and
9+
oc.getInitializer().(ObjectInitializer).getAMemberInitializer() = mi
10+
)
11+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
<overview>
6+
7+
<p>
8+
SQL Server connections where the client is not enforcing the encryption in transit are susceptible to multiple attacks, including a man-in-the-middle, that would potentially compromise the user credentials and/or the TDS session.
9+
</p>
10+
11+
</overview>
12+
<recommendation>
13+
14+
<p>Ensure that the client code enforces the <code>Encrypt</code> option by setting it to <code>true</code> in the connection string or as a property.</p>
15+
<p>Explicitly setting the property <code>Encrypt</code> to <code>false</code> will result in unprotected connections.</p>
16+
17+
</recommendation>
18+
<example>
19+
20+
<p>The following example shows a SQL connection string that is explicitly disabling the <code>Encrypt</code> setting.</p>
21+
22+
<sample src="InsecureSQLConnectionInitializerBad.cs" />
23+
24+
<p>
25+
The following example shows a SQL connection string that is explicitly enabling the <code>Encrypt</code> setting to force encryption in transit.
26+
</p>
27+
28+
<sample src="InsecureSQLConnectionInitializerGood.cs" />
29+
30+
</example>
31+
<references>
32+
<li>Microsoft, SQL Protocols blog:
33+
<a href="https://blogs.msdn.microsoft.com/sql_protocols/2009/10/19/selectively-using-secure-connection-to-sql-server/">Selectively using secure connection to SQL Server</a>.
34+
</li>
35+
<li>Microsoft:
36+
<a href="https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectionstring(v=vs.110).aspx">SqlConnection.ConnectionString Property</a>.
37+
</li>
38+
<li>Microsoft:
39+
<a href="https://msdn.microsoft.com/en-us/library/ms130822.aspx">Using Connection String Keywords with SQL Server Native Client</a>.
40+
</li>
41+
<li>Microsoft:
42+
<a href="https://msdn.microsoft.com/en-us/library/ms378988(v=sql.110).aspx">Setting the connection properties</a>.
43+
</li>
44+
</references>
45+
</qhelp>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* @name Insecure SQL connection in Initializer
3+
* @description Using an SQL Server connection without enforcing encryption is a security vulnerability.
4+
* This rule variant will flag when the `encrypt` property is explicitly set to `false` during the object initializer
5+
* @kind path-problem
6+
* @id cs/insecure-sql-connection-initializer
7+
* @problem.severity error
8+
* @security-severity 7.5
9+
* @precision medium
10+
* @tags security
11+
* external/cwe/cwe-327
12+
*/
13+
14+
import csharp
15+
import InsecureSqlConnectionInitialize::PathGraph
16+
import InsecureSQLConnection
17+
18+
class Source extends DataFlow::Node {
19+
Source() { this.asExpr().(BoolLiteral).getBoolValue() = false }
20+
}
21+
22+
class Sink extends DataFlow::Node {
23+
Sink() { getInfoForInitializedConnEncryption(_, this.asExpr()) }
24+
}
25+
26+
/**
27+
* A data flow configuration for tracking strings passed to `SqlConnection[StringBuilder]` instances.
28+
*/
29+
module InsecureSqlConnectionInitializeConfig implements DataFlow::ConfigSig {
30+
predicate isSource(DataFlow::Node source) { source instanceof Source }
31+
32+
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
33+
}
34+
35+
/**
36+
* A data flow configuration for tracking strings passed to `SqlConnection[StringBuilder]` instances.
37+
*/
38+
module InsecureSqlConnectionInitialize = DataFlow::Global<InsecureSqlConnectionInitializeConfig>;
39+
40+
from
41+
ObjectCreation oc, InsecureSqlConnectionInitialize::PathNode source,
42+
InsecureSqlConnectionInitialize::PathNode sink
43+
where
44+
InsecureSqlConnectionInitialize::flowPath(source, sink) and
45+
getInfoForInitializedConnEncryption(oc, sink.getNode().asExpr())
46+
select sink.getNode(), source, sink,
47+
"A value evaluating to $@ flows to $@ and sets the `encrypt` property.", source.getNode(),
48+
"`false`", oc, "this SQL connection initializer"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
using System.Data.SqlClient;
2+
3+
// BAD, Encrypt not specified
4+
string connectString =
5+
"Server=1.2.3.4;Database=Anything;Integrated Security=true;";
6+
var builder = new SqlConnectionStringBuilder(SetToTrueConnStr) { Encrypt = false }
7+
var conn = new SqlConnection(builder.ConnectionString);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
using System.Data.SqlClient;
2+
3+
// BAD, Encrypt not specified
4+
string connectString =
5+
"Server=1.2.3.4;Database=Anything;Integrated Security=true;";
6+
var builder = new SqlConnectionStringBuilder(SetToTrueConnStr) { Encrypt = true }
7+
var conn = new SqlConnection(builder.ConnectionString);

csharp/ql/test/query-tests/Security Features/CWE-327/InsecureSQLConnection/InsecureSQLConnection.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.Data.SqlClient;
23

34
namespace InsecureSQLConnection
@@ -34,21 +35,21 @@ public void StringInBuilderProperty()
3435
public void StringInInitializer()
3536
{
3637
string connectString = "Server=1.2.3.4;Database=Anything;UID=ab;Pwd=cd;Encrypt=false";
37-
SqlConnectionStringBuilder conBuilder = new SqlConnectionStringBuilder(connectString) { Encrypt = true};
38+
SqlConnectionStringBuilder conBuilder = new SqlConnectionStringBuilder(connectString) { Encrypt = true}; // False Positive
3839
}
3940

4041

4142
public void TriggerThis()
4243
{
43-
// BAD, Encrypt not specified
44+
// BAD, Encrypt not specified (version dependent)
4445
SqlConnection conn = new SqlConnection("Server=myServerName\\myInstanceName;Database=myDataBase;User Id=myUsername;");
4546
}
4647

4748
void Test4()
4849
{
4950
string connectString =
5051
"Server=1.2.3.4;Database=Anything;UID=ab;Pwd=cd";
51-
// BAD, Encrypt not specified
52+
// BAD, Encrypt not specified (version dependent)
5253
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectString);
5354
var conn = new SqlConnection(builder.ConnectionString);
5455
}
@@ -61,5 +62,20 @@ void Test5()
6162
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectString);
6263
var conn = new SqlConnection(builder.ConnectionString);
6364
}
65+
66+
void Test6()
67+
{
68+
var conn = new SqlConnectionStringBuilder(SetToTrueConnStr) { Encrypt = false }; // Bug - cs/insecure-sql-connection-initializer
69+
}
70+
71+
void Test72ndPhase(bool encrypt)
72+
{
73+
var conn = new SqlConnectionStringBuilder(SetToTrueConnStr) { Encrypt = encrypt }; // Bug - cs/insecure-sql-connection-initializer (sink)
74+
}
75+
76+
void Test7()
77+
{
78+
Test72ndPhase(false); // Bug - cs/insecure-sql-connection-initializer (source)
79+
}
6480
}
6581
}
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Security Features/CWE-327/InsecureSQLConnection.ql
1+
Security Features/CWE-327/InsecureSQLConnectionInitializer.ql
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Security Features/CWE-327/InsecureSQLConnection.ql

0 commit comments

Comments
 (0)