From 18db40531882771fc9e4983e4f686931e0f0fbf0 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Fri, 27 Sep 2024 15:01:53 +0200 Subject: [PATCH] C#: Add and update tests and base them on stubs. --- .../InsecureCertificateValidation.expected | 34 +++++++++--- .../ql/test/experimental/CWE-295/Program.cs | 52 +++++++++++++++++-- csharp/ql/test/experimental/CWE-295/options | 2 + 3 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 csharp/ql/test/experimental/CWE-295/options diff --git a/csharp/ql/test/experimental/CWE-295/InsecureCertificateValidation.expected b/csharp/ql/test/experimental/CWE-295/InsecureCertificateValidation.expected index 55746006b7e8..d7739d3a69c4 100644 --- a/csharp/ql/test/experimental/CWE-295/InsecureCertificateValidation.expected +++ b/csharp/ql/test/experimental/CWE-295/InsecureCertificateValidation.expected @@ -1,6 +1,28 @@ -| Program.cs:19:13:19:78 | delegate creation of type RemoteCertificateValidationCallback | $@ that is defined $@ and accepts any certificate as valid, is used here. | Program.cs:19:13:19:78 | delegate creation of type RemoteCertificateValidationCallback | This certificate callback | Program.cs:39:24:39:48 | ValidateServerCertificate | here | -| Program.cs:60:61:60:106 | (...) => ... | $@ that is defined $@ and accepts any certificate as valid, is used here. | Program.cs:60:61:60:106 | (...) => ... | This certificate callback | Program.cs:60:61:60:106 | (...) => ... | here | -| Program.cs:67:67:67:132 | delegate creation of type RemoteCertificateValidationCallback | $@ that is defined $@ and accepts any certificate as valid, is used here. | Program.cs:67:67:67:132 | delegate creation of type RemoteCertificateValidationCallback | This certificate callback | Program.cs:39:24:39:48 | ValidateServerCertificate | here | -| Program.cs:68:67:68:112 | (...) => ... | $@ that is defined $@ and accepts any certificate as valid, is used here. | Program.cs:68:67:68:112 | (...) => ... | This certificate callback | Program.cs:68:67:68:112 | (...) => ... | here | -| Program.cs:69:67:69:91 | delegate creation of type RemoteCertificateValidationCallback | $@ that is defined $@ and accepts any certificate as valid, is used here. | Program.cs:69:67:69:91 | delegate creation of type RemoteCertificateValidationCallback | This certificate callback | Program.cs:39:24:39:48 | ValidateServerCertificate | here | -| Program.cs:75:55:75:79 | delegate creation of type RemoteCertificateValidationCallback | $@ that is defined $@ and accepts any certificate as valid, is used here. | Program.cs:75:55:75:79 | delegate creation of type RemoteCertificateValidationCallback | This certificate callback | Program.cs:39:24:39:48 | ValidateServerCertificate | here | +edges +| Program.cs:80:58:80:65 | callback : ValidateServerCertificate | Program.cs:82:67:82:74 | access to parameter callback | provenance | | +| Program.cs:87:45:87:52 | access to local variable callback : ValidateServerCertificate | Program.cs:89:25:89:32 | access to local variable callback : ValidateServerCertificate | provenance | | +| Program.cs:87:56:87:80 | delegate creation of type RemoteCertificateValidationCallback : ValidateServerCertificate | Program.cs:87:45:87:52 | access to local variable callback : ValidateServerCertificate | provenance | | +| Program.cs:89:25:89:32 | access to local variable callback : ValidateServerCertificate | Program.cs:80:58:80:65 | callback : ValidateServerCertificate | provenance | | +nodes +| Program.cs:18:13:18:78 | delegate creation of type RemoteCertificateValidationCallback | semmle.label | delegate creation of type RemoteCertificateValidationCallback | +| Program.cs:59:61:59:106 | (...) => ... | semmle.label | (...) => ... | +| Program.cs:66:67:66:132 | delegate creation of type RemoteCertificateValidationCallback | semmle.label | delegate creation of type RemoteCertificateValidationCallback | +| Program.cs:67:67:67:112 | (...) => ... | semmle.label | (...) => ... | +| Program.cs:68:67:68:91 | delegate creation of type RemoteCertificateValidationCallback | semmle.label | delegate creation of type RemoteCertificateValidationCallback | +| Program.cs:75:55:75:79 | delegate creation of type RemoteCertificateValidationCallback | semmle.label | delegate creation of type RemoteCertificateValidationCallback | +| Program.cs:80:58:80:65 | callback : ValidateServerCertificate | semmle.label | callback : ValidateServerCertificate | +| Program.cs:82:67:82:74 | access to parameter callback | semmle.label | access to parameter callback | +| Program.cs:87:45:87:52 | access to local variable callback : ValidateServerCertificate | semmle.label | access to local variable callback : ValidateServerCertificate | +| Program.cs:87:56:87:80 | delegate creation of type RemoteCertificateValidationCallback : ValidateServerCertificate | semmle.label | delegate creation of type RemoteCertificateValidationCallback : ValidateServerCertificate | +| Program.cs:89:25:89:32 | access to local variable callback : ValidateServerCertificate | semmle.label | access to local variable callback : ValidateServerCertificate | +| Program.cs:114:71:114:95 | delegate creation of type RemoteCertificateValidationCallback | semmle.label | delegate creation of type RemoteCertificateValidationCallback | +subpaths +#select +| Program.cs:18:13:18:78 | delegate creation of type RemoteCertificateValidationCallback | Program.cs:18:13:18:78 | delegate creation of type RemoteCertificateValidationCallback | Program.cs:18:13:18:78 | delegate creation of type RemoteCertificateValidationCallback | $@ that is defined $@ and accepts any certificate as valid, is used here. | Program.cs:18:13:18:78 | delegate creation of type RemoteCertificateValidationCallback | This certificate callback | Program.cs:18:13:18:78 | delegate creation of type RemoteCertificateValidationCallback | here | +| Program.cs:59:61:59:106 | (...) => ... | Program.cs:59:61:59:106 | (...) => ... | Program.cs:59:61:59:106 | (...) => ... | $@ that is defined $@ and accepts any certificate as valid, is used here. | Program.cs:59:61:59:106 | (...) => ... | This certificate callback | Program.cs:59:61:59:106 | (...) => ... | here | +| Program.cs:66:67:66:132 | delegate creation of type RemoteCertificateValidationCallback | Program.cs:66:67:66:132 | delegate creation of type RemoteCertificateValidationCallback | Program.cs:66:67:66:132 | delegate creation of type RemoteCertificateValidationCallback | $@ that is defined $@ and accepts any certificate as valid, is used here. | Program.cs:66:67:66:132 | delegate creation of type RemoteCertificateValidationCallback | This certificate callback | Program.cs:66:67:66:132 | delegate creation of type RemoteCertificateValidationCallback | here | +| Program.cs:67:67:67:112 | (...) => ... | Program.cs:67:67:67:112 | (...) => ... | Program.cs:67:67:67:112 | (...) => ... | $@ that is defined $@ and accepts any certificate as valid, is used here. | Program.cs:67:67:67:112 | (...) => ... | This certificate callback | Program.cs:67:67:67:112 | (...) => ... | here | +| Program.cs:68:67:68:91 | delegate creation of type RemoteCertificateValidationCallback | Program.cs:68:67:68:91 | delegate creation of type RemoteCertificateValidationCallback | Program.cs:68:67:68:91 | delegate creation of type RemoteCertificateValidationCallback | $@ that is defined $@ and accepts any certificate as valid, is used here. | Program.cs:68:67:68:91 | delegate creation of type RemoteCertificateValidationCallback | This certificate callback | Program.cs:68:67:68:91 | delegate creation of type RemoteCertificateValidationCallback | here | +| Program.cs:75:55:75:79 | delegate creation of type RemoteCertificateValidationCallback | Program.cs:75:55:75:79 | delegate creation of type RemoteCertificateValidationCallback | Program.cs:75:55:75:79 | delegate creation of type RemoteCertificateValidationCallback | $@ that is defined $@ and accepts any certificate as valid, is used here. | Program.cs:75:55:75:79 | delegate creation of type RemoteCertificateValidationCallback | This certificate callback | Program.cs:75:55:75:79 | delegate creation of type RemoteCertificateValidationCallback | here | +| Program.cs:82:67:82:74 | access to parameter callback | Program.cs:87:56:87:80 | delegate creation of type RemoteCertificateValidationCallback : ValidateServerCertificate | Program.cs:82:67:82:74 | access to parameter callback | $@ that is defined $@ and accepts any certificate as valid, is used here. | Program.cs:82:67:82:74 | access to parameter callback | This certificate callback | Program.cs:87:56:87:80 | delegate creation of type RemoteCertificateValidationCallback : ValidateServerCertificate | here | +| Program.cs:114:71:114:95 | delegate creation of type RemoteCertificateValidationCallback | Program.cs:114:71:114:95 | delegate creation of type RemoteCertificateValidationCallback | Program.cs:114:71:114:95 | delegate creation of type RemoteCertificateValidationCallback | $@ that is defined $@ and accepts any certificate as valid, is used here. | Program.cs:114:71:114:95 | delegate creation of type RemoteCertificateValidationCallback | This certificate callback | Program.cs:114:71:114:95 | delegate creation of type RemoteCertificateValidationCallback | here | diff --git a/csharp/ql/test/experimental/CWE-295/Program.cs b/csharp/ql/test/experimental/CWE-295/Program.cs index bd76d4f2879f..b2a050128323 100644 --- a/csharp/ql/test/experimental/CWE-295/Program.cs +++ b/csharp/ql/test/experimental/CWE-295/Program.cs @@ -1,4 +1,3 @@ -// semmle-extractor-options: /r:System.Net.Sockets.dll /r:System.Net.Security.dll /r:System.Security.Cryptography.Algorithms.dll /r:System.Net.Http.dll /r:System.Net.ServicePoint.dll /r:System.Security.Cryptography.dll /r:System.Net.Primitives.dll /r:System.Net.Requests.dll /r:System.Private.Uri.dll using System; using System.Net; using System.Net.Security; @@ -10,7 +9,7 @@ class Program { - static void First() + void M1() { TcpClient client = new TcpClient("www.example.com", 443); SslStream sslStream = new SslStream( @@ -54,7 +53,7 @@ public static bool SafeValidateServerCertificate( return sslPolicyErrors == SslPolicyErrors.None; } - static void Second() + void M2() { HttpClientHandler handler = new HttpClientHandler(); handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true; // BAD: unsafe callback used @@ -62,14 +61,15 @@ static void Second() HttpClient client = new HttpClient(handler); } - static void Third() + void M3() { ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate); // BAD: unsafe callback used ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true; // BAD: unsafe callback used ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate; // BAD: unsafe callback used ServicePointManager.ServerCertificateValidationCallback = SafeValidateServerCertificate; // GOOD: safe callback used } - static void Fourth() + + void M4() { HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.example.com"); request.ServerCertificateValidationCallback = ValidateServerCertificate; // BAD: unsafe callback used @@ -77,4 +77,46 @@ static void Fourth() } + void SetCallback(RemoteCertificateValidationCallback callback) + { + ServicePointManager.ServerCertificateValidationCallback = callback; // BAD: unsafe callback used + } + + void M5(bool b) + { + RemoteCertificateValidationCallback callback = ValidateServerCertificate; + if (b) { + SetCallback(callback); // BAD: unsafe callback used + } + } + + void M6(Settings settings) + { + RemoteCertificateValidationCallback callback = ValidateServerCertificate; + if (settings.IgnoreCertificateValidation) + { + SetCallback(callback); // GOOD: We don't do validation. + } + } + + void M7(Settings settings) + { + if (settings.IgnoreCertificateValidation) + { + ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate; // GOOD: We don't do validation. + } + } + + void M8(Settings settings) + { + if (!settings.IgnoreCertificateValidation) + { + ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate; // BAD: unsafe callback used + } + } +} + +public class Settings { + + public bool IgnoreCertificateValidation { get; set; } } diff --git a/csharp/ql/test/experimental/CWE-295/options b/csharp/ql/test/experimental/CWE-295/options new file mode 100644 index 000000000000..77b22963f5c8 --- /dev/null +++ b/csharp/ql/test/experimental/CWE-295/options @@ -0,0 +1,2 @@ +semmle-extractor-options: /nostdlib /noconfig +semmle-extractor-options: --load-sources-from-project:${testdir}/../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj