From ed7f68279f719ad4fe5bb350fda58bf85d74dfe5 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 25 Jun 2025 14:34:19 +0200 Subject: [PATCH] C#: Add cs/sql-injection tests for APIs in Microsoft.Data.SqlClient. --- .../CWE-089-2/SqlInjection.cs | 33 +++++++++++++++++++ .../CWE-089-2/SqlInjection.expected | 21 ++++++++++++ .../CWE-089-2/SqlInjection.ext.yml | 7 ++++ .../CWE-089-2/SqlInjection.qlref | 4 +++ .../Security Features/CWE-089-2/options | 4 +++ 5 files changed, 69 insertions(+) create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-089-2/SqlInjection.cs create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-089-2/SqlInjection.expected create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-089-2/SqlInjection.ext.yml create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-089-2/SqlInjection.qlref create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-089-2/options diff --git a/csharp/ql/test/query-tests/Security Features/CWE-089-2/SqlInjection.cs b/csharp/ql/test/query-tests/Security Features/CWE-089-2/SqlInjection.cs new file mode 100644 index 00000000000..739f0ea30ee --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-089-2/SqlInjection.cs @@ -0,0 +1,33 @@ +using System; +using Microsoft.Data; +using Microsoft.Data.SqlClient; + +namespace Test +{ + class SqlInjection + { + string connectionString; + System.Windows.Forms.TextBox box1; + + public void MakeSqlCommand() + { + // BAD: Text from a local textbox + using (var connection = new SqlConnection(connectionString)) + { + var queryString = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + box1.Text + "' ORDER BY PRICE"; // $ Source[cs/sql-injection] + var cmd = new SqlCommand(queryString); // $ Alert[cs/sql-injection] + var adapter = new SqlDataAdapter(cmd); // $ Alert[cs/sql-injection] + } + + // BAD: Input from the command line. + using (var connection = new SqlConnection(connectionString)) + { + var queryString = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + + Console.ReadLine() + "' ORDER BY PRICE"; // $ Source[cs/sql-injection] + var cmd = new SqlCommand(queryString); // $ Alert[cs/sql-injection] + var adapter = new SqlDataAdapter(cmd); // $ Alert[cs/sql-injection] + } + } + } +} diff --git a/csharp/ql/test/query-tests/Security Features/CWE-089-2/SqlInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-089-2/SqlInjection.expected new file mode 100644 index 00000000000..830dcd9e2e8 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-089-2/SqlInjection.expected @@ -0,0 +1,21 @@ +#select +| SqlInjection.cs:19:42:19:52 | access to local variable queryString | SqlInjection.cs:18:21:18:29 | access to property Text : String | SqlInjection.cs:19:42:19:52 | access to local variable queryString | This query depends on $@. | SqlInjection.cs:18:21:18:29 | access to property Text : String | this TextBox text | +| SqlInjection.cs:28:42:28:52 | access to local variable queryString | SqlInjection.cs:27:21:27:38 | call to method ReadLine : String | SqlInjection.cs:28:42:28:52 | access to local variable queryString | This query depends on $@. | SqlInjection.cs:27:21:27:38 | call to method ReadLine : String | this read from stdin | +edges +| SqlInjection.cs:17:21:17:31 | access to local variable queryString : String | SqlInjection.cs:19:42:19:52 | access to local variable queryString | provenance | | +| SqlInjection.cs:18:21:18:29 | access to property Text : String | SqlInjection.cs:17:21:17:31 | access to local variable queryString : String | provenance | | +| SqlInjection.cs:26:21:26:31 | access to local variable queryString : String | SqlInjection.cs:28:42:28:52 | access to local variable queryString | provenance | | +| SqlInjection.cs:27:21:27:38 | call to method ReadLine : String | SqlInjection.cs:26:21:26:31 | access to local variable queryString : String | provenance | Src:MaD:1 | +models +| 1 | Source: System; Console; false; ReadLine; ; ; ReturnValue; stdin; manual | +nodes +| SqlInjection.cs:17:21:17:31 | access to local variable queryString : String | semmle.label | access to local variable queryString : String | +| SqlInjection.cs:18:21:18:29 | access to property Text : String | semmle.label | access to property Text : String | +| SqlInjection.cs:19:42:19:52 | access to local variable queryString | semmle.label | access to local variable queryString | +| SqlInjection.cs:26:21:26:31 | access to local variable queryString : String | semmle.label | access to local variable queryString : String | +| SqlInjection.cs:27:21:27:38 | call to method ReadLine : String | semmle.label | call to method ReadLine : String | +| SqlInjection.cs:28:42:28:52 | access to local variable queryString | semmle.label | access to local variable queryString | +subpaths +testFailures +| SqlInjection.cs:20:56:20:83 | // ... | Missing result: Alert[cs/sql-injection] | +| SqlInjection.cs:29:56:29:83 | // ... | Missing result: Alert[cs/sql-injection] | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-089-2/SqlInjection.ext.yml b/csharp/ql/test/query-tests/Security Features/CWE-089-2/SqlInjection.ext.yml new file mode 100644 index 00000000000..82f107ae1d7 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-089-2/SqlInjection.ext.yml @@ -0,0 +1,7 @@ +extensions: + + - addsTo: + pack: codeql/threat-models + extensible: threatModelConfiguration + data: + - ["local", true, 0] \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-089-2/SqlInjection.qlref b/csharp/ql/test/query-tests/Security Features/CWE-089-2/SqlInjection.qlref new file mode 100644 index 00000000000..1421faac807 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-089-2/SqlInjection.qlref @@ -0,0 +1,4 @@ +query: Security Features/CWE-089/SqlInjection.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/csharp/ql/test/query-tests/Security Features/CWE-089-2/options b/csharp/ql/test/query-tests/Security Features/CWE-089-2/options new file mode 100644 index 00000000000..5601356ee48 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-089-2/options @@ -0,0 +1,4 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/Microsoft.Data.SqlClient/6.0.2/Microsoft.Data.SqlClient.csproj +semmle-extractor-options: ${testdir}/../../../resources/stubs/System.Windows.cs +semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.App.csproj