diff --git a/csharp/ql/src/codeql-suites/csharp-security-experimental.qls b/csharp/ql/src/codeql-suites/csharp-security-experimental.qls deleted file mode 100644 index b47176b0e878..000000000000 --- a/csharp/ql/src/codeql-suites/csharp-security-experimental.qls +++ /dev/null @@ -1,4 +0,0 @@ -- description: Extended and experimental security queries for C# -- queries: . -- apply: security-experimental-selectors.yml - from: codeql/suite-helpers \ No newline at end of file diff --git a/csharp/ql/src/experimental/CWE-099/TaintedWebClient.cs b/csharp/ql/src/experimental/CWE-099/TaintedWebClient.cs deleted file mode 100644 index 5913e7e1bbf1..000000000000 --- a/csharp/ql/src/experimental/CWE-099/TaintedWebClient.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.IO; -using System.Web; -using System.Net; - -public class TaintedWebClientHandler : IHttpHandler -{ - public void ProcessRequest(HttpContext ctx) - { - String url = ctx.Request.QueryString["domain"]; - - // BAD: This could read any file on the filesystem. (../../../../etc/passwd) - using(WebClient client = new WebClient()) { - ctx.Response.Write(client.DownloadString(url)); - } - - // BAD: This could still read any file on the filesystem. (https://../../../../etc/passwd) - if (url.StartsWith("https://")){ - using(WebClient client = new WebClient()) { - ctx.Response.Write(client.DownloadString(url)); - } - } - - // GOOD: IsWellFormedUriString ensures that it is a valid URL - if (Uri.IsWellFormedUriString(url, UriKind.Absolute)){ - using(WebClient client = new WebClient()) { - ctx.Response.Write(client.DownloadString(url)); - } - } - } -} diff --git a/csharp/ql/src/experimental/CWE-099/TaintedWebClient.qhelp b/csharp/ql/src/experimental/CWE-099/TaintedWebClient.qhelp deleted file mode 100644 index d7f195905a84..000000000000 --- a/csharp/ql/src/experimental/CWE-099/TaintedWebClient.qhelp +++ /dev/null @@ -1,58 +0,0 @@ - - - -

The WebClient class provides a variety of methods for data transmission and -communication with a particular URI. Despite of the class' naming convention, -the URI scheme can also identify local resources, not only remote ones. Tainted -by user-supplied input, the URI can be leveraged to access resources available -on the local file system, therefore leading to the disclosure of sensitive -information. This can be trivially achieved by supplying path traversal -sequences (../) followed by an existing directory or file path.

- -

Sanitization of user-supplied URI values using the -StartsWith("https://") method is deemed insufficient in preventing -arbitrary file reads. This is due to the fact that .NET ignores the protocol -handler (https in this case) in URIs like the following: -"https://../../../../etc/passwd".

- -
- - -

Validate user input before using it to ensure that is a URI of an external -resource and not a local one. -Potential solutions:

- - - -
- - -

In the first example, a domain name is read from a HttpRequest -and then this domain is requested using the method DownloadString. -However, a malicious user could enter a local path - for example, -"../../../etc/passwd" instead of a domain. -In the second example, it appears that the user is restricted to the HTTPS -protocol handler. However, a malicious user could still enter a local path, -since as explained above the protocol handler will be ignored by .net. For -example, the string "https://../../../etc/passwd" will result in the code -reading the file located at "/etc/passwd", which is the system's password file. -This file would then be sent back to the user, giving them access to all the -system's passwords.

- - - -
- - -
  • -OWASP: -Path Traversal. -
  • - -
    -
    diff --git a/csharp/ql/src/experimental/CWE-099/TaintedWebClient.ql b/csharp/ql/src/experimental/CWE-099/TaintedWebClient.ql deleted file mode 100644 index 338036155441..000000000000 --- a/csharp/ql/src/experimental/CWE-099/TaintedWebClient.ql +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @name Uncontrolled data used in a WebClient - * @description The WebClient class allows developers to request resources, - * accessing resources influenced by users can allow an attacker to access local files. - * @kind path-problem - * @problem.severity error - * @precision high - * @id cs/webclient-path-injection - * @tags security - * experimental - * external/cwe/cwe-099 - * external/cwe/cwe-023 - * external/cwe/cwe-036 - * external/cwe/cwe-073 - */ - -import csharp -deprecated import TaintedWebClientLib -deprecated import TaintedWebClient::PathGraph - -deprecated query predicate problems( - DataFlow::Node sinkNode, TaintedWebClient::PathNode source, TaintedWebClient::PathNode sink, - string message1, DataFlow::Node sourceNode, string message2 -) { - TaintedWebClient::flowPath(source, sink) and - sinkNode = sink.getNode() and - message1 = "A method of WebClient depepends on a $@." and - sourceNode = source.getNode() and - message2 = "user-provided value" -} diff --git a/csharp/ql/src/experimental/CWE-099/TaintedWebClientLib.qll b/csharp/ql/src/experimental/CWE-099/TaintedWebClientLib.qll deleted file mode 100644 index a088f5100af8..000000000000 --- a/csharp/ql/src/experimental/CWE-099/TaintedWebClientLib.qll +++ /dev/null @@ -1,92 +0,0 @@ -deprecated module; - -import csharp -import semmle.code.csharp.frameworks.system.Net -import semmle.code.csharp.frameworks.System -import semmle.code.csharp.security.dataflow.flowsources.FlowSources -import semmle.code.csharp.security.Sanitizers - -//If this leaves experimental this should probably go in semmle.code.csharp.frameworks.system.Net -/** The `System.Net.WebClient` class. */ -class SystemNetWebClientClass extends SystemNetClass { - SystemNetWebClientClass() { this.hasName("WebClient") } - - /** Gets the `DownloadString` method. */ - Method getDownloadStringMethod() { result = this.getAMethod("DownloadString") } -} - -//If this leaves experimental this should probably go in semmle.code.csharp.frameworks.System -//Extend the already existent SystemUriClass to not touch the stdlib. -/** The `System.Uri` class. */ -class SystemUriClassExtra extends SystemUriClass { - /** Gets the `IsWellFormedUriString` method. */ - Method getIsWellFormedUriStringMethod() { result = this.getAMethod("IsWellFormedUriString") } -} - -//If this leaves experimental this should probably go in semmle.code.csharp.frameworks.system -/** - * A data flow source for uncontrolled data in path expression vulnerabilities. - */ -abstract class Source extends DataFlow::Node { } - -/** - * A data flow sink for uncontrolled data in path expression vulnerabilities. - */ -abstract class Sink extends DataFlow::ExprNode { } - -/** - * A sanitizer for uncontrolled data in path expression vulnerabilities. - */ -abstract class Sanitizer extends DataFlow::ExprNode { } - -/** - * A taint-tracking configuration for uncontrolled data in path expression vulnerabilities. - */ -private module TaintedWebClientConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } -} - -/** - * A taint-tracking module for uncontrolled data in path expression vulnerabilities. - */ -module TaintedWebClient = TaintTracking::Global; - -/** - * DEPRECATED: Use `ThreatModelSource` instead. - * - * A source of remote user input. - */ -deprecated class RemoteSource extends DataFlow::Node instanceof RemoteFlowSource { } - -/** A source supported by the current threat model. */ -class ThreatModelSource extends Source instanceof ActiveThreatModelSource { } - -/** - * A path argument to a `WebClient` method call that has an address argument. - */ -class WebClientSink extends Sink { - WebClientSink() { - exists(Method m | m = any(SystemNetWebClientClass f).getAMethod() | - this.getExpr() = m.getACall().getArgumentForName("address") - ) - } -} - -/** - * A call to `System.Uri.IsWellFormedUriString` that is considered to sanitize the input. - */ -class RequestMapPathSanitizer extends Sanitizer { - RequestMapPathSanitizer() { - exists(Method m | m = any(SystemUriClassExtra uri).getIsWellFormedUriStringMethod() | - this.getExpr() = m.getACall().getArgument(0) - ) - } -} - -private class SimpleTypeSanitizer extends Sanitizer, SimpleTypeSanitizedExpr { } - -private class GuidSanitizer extends Sanitizer, GuidSanitizedExpr { } diff --git a/csharp/ql/src/experimental/CWE-918/RequestForgery.cs b/csharp/ql/src/experimental/CWE-918/RequestForgery.cs deleted file mode 100644 index d9b83eeea3ce..000000000000 --- a/csharp/ql/src/experimental/CWE-918/RequestForgery.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace RequestForgery.Controllers -{ - public class SSRFController : Controller - { - [HttpPost] - [ValidateAntiForgeryToken] - public async Task Bad(string url) - { - var request = new HttpRequestMessage(HttpMethod.Get, url); - - var client = new HttpClient(); - await client.SendAsync(request); - - return View(); - } - - [HttpPost] - [ValidateAntiForgeryToken] - public async Task Good(string url) - { - string baseUrl = "www.mysecuresite.com/"; - if (url.StartsWith(baseUrl)) - { - var request = new HttpRequestMessage(HttpMethod.Get, url); - var client = new HttpClient(); - await client.SendAsync(request); - - } - - return View(); - } - } -} \ No newline at end of file diff --git a/csharp/ql/src/experimental/CWE-918/RequestForgery.qhelp b/csharp/ql/src/experimental/CWE-918/RequestForgery.qhelp deleted file mode 100644 index fb04540e13da..000000000000 --- a/csharp/ql/src/experimental/CWE-918/RequestForgery.qhelp +++ /dev/null @@ -1,35 +0,0 @@ - - - - - -

    Directly incorporating user input into a HTTP request without validating the input -can facilitate Server Side Request Forgery (SSRF) attacks. In these attacks, the server -may be tricked into making a request and interacting with an attacker-controlled server. -

    - -
    - - -

    To guard against SSRF attacks, it is advisable to avoid putting user input -directly into the request URL. Instead, maintain a list of authorized -URLs on the server; then choose from that list based on the user input provided.

    - -
    - - -

    The following example shows an HTTP request parameter being used directly in a forming a -new request without validating the input, which facilitates SSRF attacks. -It also shows how to remedy the problem by validating the user input against a known fixed string. -

    - - - -
    - -
  • - OWASP SSRF -
  • - -
    -
    diff --git a/csharp/ql/src/experimental/CWE-918/RequestForgery.ql b/csharp/ql/src/experimental/CWE-918/RequestForgery.ql deleted file mode 100644 index 313e3c76c0e8..000000000000 --- a/csharp/ql/src/experimental/CWE-918/RequestForgery.ql +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @name Server-side request forgery - * @description Making a network request with user-controlled data in the URL allows for request forgery attacks. - * @kind path-problem - * @problem.severity error - * @precision high - * @id cs/request-forgery - * @tags security - * experimental - * external/cwe/cwe-918 - */ - -import csharp -deprecated import RequestForgery::RequestForgery -deprecated import RequestForgeryFlow::PathGraph - -deprecated query predicate problems( - DataFlow::Node sinkNode, RequestForgeryFlow::PathNode source, RequestForgeryFlow::PathNode sink, - string message1, DataFlow::Node sourceNode, string message2 -) { - RequestForgeryFlow::flowPath(source, sink) and - sinkNode = sink.getNode() and - message1 = "The URL of this request depends on a $@." and - sourceNode = source.getNode() and - message2 = "user-provided value" -} diff --git a/csharp/ql/src/experimental/CWE-918/RequestForgery.qll b/csharp/ql/src/experimental/CWE-918/RequestForgery.qll deleted file mode 100644 index 9ab1351f4142..000000000000 --- a/csharp/ql/src/experimental/CWE-918/RequestForgery.qll +++ /dev/null @@ -1,240 +0,0 @@ -deprecated module; - -import csharp - -module RequestForgery { - import semmle.code.csharp.controlflow.Guards - import semmle.code.csharp.frameworks.System - import semmle.code.csharp.frameworks.system.Web - import semmle.code.csharp.frameworks.Format - import semmle.code.csharp.security.dataflow.flowsources.FlowSources - - /** - * A data flow source for server side request forgery vulnerabilities. - */ - abstract private class Source extends DataFlow::Node { } - - /** - * A data flow sink for server side request forgery vulnerabilities. - */ - abstract private class Sink extends DataFlow::ExprNode { } - - /** - * A data flow Barrier that blocks the flow of taint for - * server side request forgery vulnerabilities. - */ - abstract private class Barrier extends DataFlow::Node { } - - /** - * A data flow configuration for detecting server side request forgery vulnerabilities. - */ - private module RequestForgeryFlowConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source instanceof Source } - - predicate isSink(DataFlow::Node sink) { sink instanceof Sink } - - predicate isAdditionalFlowStep(DataFlow::Node prev, DataFlow::Node succ) { - interpolatedStringFlowStep(prev, succ) - or - stringReplaceStep(prev, succ) - or - uriCreationStep(prev, succ) - or - formatConvertStep(prev, succ) - or - toStringStep(prev, succ) - or - stringConcatStep(prev, succ) - or - stringFormatStep(prev, succ) - or - pathCombineStep(prev, succ) - } - - predicate isBarrier(DataFlow::Node node) { node instanceof Barrier } - } - - /** - * A data flow module for detecting server side request forgery vulnerabilities. - */ - module RequestForgeryFlow = DataFlow::Global; - - /** - * A dataflow source for Server Side Request Forgery(SSRF) Vulnerabilities. - */ - private class ThreatModelSource extends Source instanceof ActiveThreatModelSource { } - - /** - * An url argument to a `HttpRequestMessage` constructor call - * taken as a sink for Server Side Request Forgery(SSRF) Vulnerabilities. - */ - private class SystemWebHttpRequestMessageSink extends Sink { - SystemWebHttpRequestMessageSink() { - exists(Class c | c.hasFullyQualifiedName("System.Net.Http", "HttpRequestMessage") | - c.getAConstructor().getACall().getArgument(1) = this.asExpr() - ) - } - } - - /** - * An argument to a `WebRequest.Create` call taken as a - * sink for Server Side Request Forgery(SSRF) Vulnerabilities. * - */ - private class SystemNetWebRequestCreateSink extends Sink { - SystemNetWebRequestCreateSink() { - exists(Method m | - m.getDeclaringType().hasFullyQualifiedName("System.Net", "WebRequest") and - m.hasName("Create") - | - m.getACall().getArgument(0) = this.asExpr() - ) - } - } - - /** - * An argument to a new HTTP Request call of a `System.Net.Http.HttpClient` object - * taken as a sink for Server Side Request Forgery(SSRF) Vulnerabilities. - */ - private class SystemNetHttpClientSink extends Sink { - SystemNetHttpClientSink() { - exists(Method m | - m.getDeclaringType().hasFullyQualifiedName("System.Net.Http", "HttpClient") and - m.hasName([ - "DeleteAsync", "GetAsync", "GetByteArrayAsync", "GetStreamAsync", "GetStringAsync", - "PatchAsync", "PostAsync", "PutAsync" - ]) - | - m.getACall().getArgument(0) = this.asExpr() - ) - } - } - - /** - * An url argument to a method call of a `System.Net.WebClient` object - * taken as a sink for Server Side Request Forgery(SSRF) Vulnerabilities. - */ - private class SystemNetClientBaseAddressSink extends Sink { - SystemNetClientBaseAddressSink() { - exists(Property p, Type t | - p.hasName("BaseAddress") and - t = p.getDeclaringType() and - ( - t.hasFullyQualifiedName("System.Net", "WebClient") or - t.hasFullyQualifiedName("System.Net.Http", "HttpClient") - ) - | - p.getAnAssignedValue() = this.asExpr() - ) - } - } - - /** - * A method call which checks the base of the tainted uri is assumed - * to be a guard for Server Side Request Forgery(SSRF) Vulnerabilities. - * This guard considers all checks as valid. - */ - private predicate baseUriGuard(Guard g, Expr e, AbstractValue v) { - g.(MethodCall).getTarget().hasFullyQualifiedName("System", "Uri", "IsBaseOf") and - // we consider any checks against the tainted value to sainitize the taint. - // This implies any check such as shown below block the taint flow. - // Uri url = new Uri("whitelist.com") - // if (url.isBaseOf(`taint1)) - (e = g.(MethodCall).getArgument(0) or e = g.(MethodCall).getQualifier()) and - v.(AbstractValues::BooleanValue).getValue() = true - } - - private class BaseUriBarrier extends Barrier { - BaseUriBarrier() { this = DataFlow::BarrierGuard::getABarrierNode() } - } - - /** - * A method call which checks if the Uri starts with a white-listed string is assumed - * to be a guard for Server Side Request Forgery(SSRF) Vulnerabilities. - * This guard considers all checks as valid. - */ - private predicate stringStartsWithGuard(Guard g, Expr e, AbstractValue v) { - g.(MethodCall).getTarget().hasFullyQualifiedName("System", "String", "StartsWith") and - // Any check such as the ones shown below - // "https://myurl.com/".startsWith(`taint`) - // `taint`.startsWith("https://myurl.com/") - // are assumed to sainitize the taint - (e = g.(MethodCall).getQualifier() or g.(MethodCall).getArgument(0) = e) and - v.(AbstractValues::BooleanValue).getValue() = true - } - - private class StringStartsWithBarrier extends Barrier { - StringStartsWithBarrier() { - this = DataFlow::BarrierGuard::getABarrierNode() - } - } - - private predicate stringFormatStep(DataFlow::Node prev, DataFlow::Node succ) { - exists(FormatCall c | c.getArgument(0) = prev.asExpr() and c = succ.asExpr()) - } - - private predicate pathCombineStep(DataFlow::Node prev, DataFlow::Node succ) { - exists(MethodCall combineCall | - combineCall.getTarget().hasFullyQualifiedName("System.IO", "Path", "Combine") and - combineCall.getArgument(0) = prev.asExpr() and - combineCall = succ.asExpr() - ) - } - - private predicate uriCreationStep(DataFlow::Node prev, DataFlow::Node succ) { - exists(ObjectCreation oc | - oc.getTarget().getDeclaringType().hasFullyQualifiedName("System", "Uri") and - oc.getArgument(0) = prev.asExpr() and - oc = succ.asExpr() - ) - } - - private predicate interpolatedStringFlowStep(DataFlow::Node prev, DataFlow::Node succ) { - exists(InterpolatedStringExpr i | - // allow `$"http://{`taint`}/blabla/");"` or - // allow `$"https://{`taint`}/blabla/");"` - i.getText(0).getValue().matches(["http://", "http://"]) and - i.getInsert(1) = prev.asExpr() and - succ.asExpr() = i - or - // allow `$"{`taint`}/blabla/");"` - i.getInsert(0) = prev.asExpr() and - succ.asExpr() = i - ) - } - - private predicate stringReplaceStep(DataFlow::Node prev, DataFlow::Node succ) { - exists(MethodCall mc, SystemStringClass s | - mc = s.getReplaceMethod().getACall() and - mc.getQualifier() = prev.asExpr() and - succ.asExpr() = mc - ) - } - - private predicate stringConcatStep(DataFlow::Node prev, DataFlow::Node succ) { - exists(AddExpr a | - a.getLeftOperand() = prev.asExpr() - or - a.getRightOperand() = prev.asExpr() and - a.getLeftOperand().(StringLiteral).getValue() = ["http://", "https://"] - | - a = succ.asExpr() - ) - } - - private predicate formatConvertStep(DataFlow::Node prev, DataFlow::Node succ) { - exists(Method m | - m.hasFullyQualifiedName("System", "Convert", - ["FromBase64String", "FromHexString", "FromBase64CharArray"]) and - m.getParameter(0) = prev.asParameter() and - succ.asExpr() = m.getACall() - ) - } - - private predicate toStringStep(DataFlow::Node prev, DataFlow::Node succ) { - exists(MethodCall ma | - ma.getTarget().hasName("ToString") and - ma.getQualifier() = prev.asExpr() and - succ.asExpr() = ma - ) - } -} diff --git a/csharp/ql/src/experimental/README.md b/csharp/ql/src/experimental/README.md deleted file mode 100644 index fc07363b24f1..000000000000 --- a/csharp/ql/src/experimental/README.md +++ /dev/null @@ -1 +0,0 @@ -This directory contains [experimental](../../../../docs/experimental.md) CodeQL queries and libraries. diff --git a/csharp/ql/src/experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.qhelp b/csharp/ql/src/experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.qhelp deleted file mode 100644 index c7c10a3af9e5..000000000000 --- a/csharp/ql/src/experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.qhelp +++ /dev/null @@ -1,51 +0,0 @@ - - - - -

    -Cookies without HttpOnly flag are accessible to JavaScript running in the same origin. In case of -Cross-Site Scripting (XSS) vulnerability the cookie can be stolen by malicious script. -

    -
    - - -

    -Protect sensitive cookies, such as related to authentication, by setting HttpOnly to true to make -them not accessible to JavaScript. In ASP.NET case it is also possible to set the attribute via <httpCookies> element -of web.config with the attribute httpOnlyCookies="true". -

    -
    - - - -

    -In the example below Microsoft.AspNetCore.Http.CookieOptions.HttpOnly is set to true. -

    - - - -

    -In the following example CookiePolicyOptions are set programmatically to configure defaults. -

    - - - -

    -In the example below System.Web.HttpCookie.HttpOnly is set to true. -

    - - - -
    - - - -
  • CookieOptions.HttpOnly Property,
  • -
  • Set-Cookie Header,
  • -
  • HttpCookie.HttpOnly Property,
  • -
  • httpCookies Element,
  • - -
    -
    diff --git a/csharp/ql/src/experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql b/csharp/ql/src/experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql deleted file mode 100644 index 359ffbcd2f30..000000000000 --- a/csharp/ql/src/experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @name 'HttpOnly' attribute is not set to true - * @description Omitting the 'HttpOnly' attribute for security sensitive data allows - * malicious JavaScript to steal it in case of XSS vulnerability. Always set - * 'HttpOnly' to 'true' to authentication related cookie to make it - * not accessible by JavaScript. - * @kind problem - * @problem.severity warning - * @precision high - * @id cs/web/cookie-httponly-not-set - * @tags security - * experimental - * external/cwe/cwe-1004 - */ - -import csharp -import semmle.code.asp.WebConfig -import semmle.code.csharp.frameworks.system.Web -import semmle.code.csharp.frameworks.microsoft.AspNetCore -deprecated import experimental.dataflow.flowsources.AuthCookie - -deprecated query predicate problems(Expr httpOnlySink, string message) { - ( - exists(Assignment a, Expr val | - httpOnlySink = a.getRValue() and - val.getValue() = "false" and - ( - exists(ObjectCreation oc | - getAValueForProp(oc, a, "HttpOnly") = val and - ( - oc.getType() instanceof SystemWebHttpCookie and - isCookieWithSensitiveName(oc.getArgument(0)) - or - exists(MethodCall mc, MicrosoftAspNetCoreHttpResponseCookies iResponse | - oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and - iResponse.getAppendMethod() = mc.getTarget() and - isCookieWithSensitiveName(mc.getArgument(0)) and - // there is no callback `OnAppendCookie` that sets `HttpOnly` to true - not OnAppendCookieHttpOnlyTracking::flowTo(_) and - // Passed as third argument to `IResponseCookies.Append` - exists(DataFlow::Node creation, DataFlow::Node append | - CookieOptionsTracking::flow(creation, append) and - creation.asExpr() = oc and - append.asExpr() = mc.getArgument(2) - ) - ) - ) - ) - or - exists(PropertyWrite pw | - ( - pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreHttpCookieBuilder or - pw.getProperty().getDeclaringType() instanceof - MicrosoftAspNetCoreAuthenticationCookiesCookieAuthenticationOptions - ) and - pw.getProperty().getName() = "HttpOnly" and - a.getLValue() = pw and - DataFlow::localExprFlow(val, a.getRValue()) - ) - ) - ) - or - exists(Call c | - httpOnlySink = c and - ( - exists(MicrosoftAspNetCoreHttpResponseCookies iResponse, MethodCall mc | - // default is not configured or is not set to `Always` - not getAValueForCookiePolicyProp("HttpOnly").getValue() = "1" and - // there is no callback `OnAppendCookie` that sets `HttpOnly` to true - not OnAppendCookieHttpOnlyTracking::flowTo(_) and - iResponse.getAppendMethod() = mc.getTarget() and - isCookieWithSensitiveName(mc.getArgument(0)) and - ( - // `HttpOnly` property in `CookieOptions` passed to IResponseCookies.Append(...) wasn't set - exists(ObjectCreation oc | - oc = c and - oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and - not isPropertySet(oc, "HttpOnly") and - exists(DataFlow::Node creation | - CookieOptionsTracking::flow(creation, _) and - creation.asExpr() = oc - ) - ) - or - // IResponseCookies.Append(String, String) was called, `HttpOnly` is set to `false` by default - mc = c and - mc.getNumberOfArguments() < 3 - ) - ) - or - exists(ObjectCreation oc | - oc = c and - oc.getType() instanceof SystemWebHttpCookie and - isCookieWithSensitiveName(oc.getArgument(0)) and - // the property wasn't explicitly set, so a default value from config is used - not isPropertySet(oc, "HttpOnly") and - // the default in config is not set to `true` - not exists(XmlElement element | - element instanceof HttpCookiesElement and - element.(HttpCookiesElement).isHttpOnlyCookies() - ) - ) - ) - ) - ) and - message = "Cookie attribute 'HttpOnly' is not set to true." -} diff --git a/csharp/ql/src/experimental/Security Features/CWE-1004/cookiepolicyoptions.cs b/csharp/ql/src/experimental/Security Features/CWE-1004/cookiepolicyoptions.cs deleted file mode 100644 index a9adf0d99822..000000000000 --- a/csharp/ql/src/experimental/Security Features/CWE-1004/cookiepolicyoptions.cs +++ /dev/null @@ -1,12 +0,0 @@ -public class Startup -{ - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - app.UseCookiePolicy(new CookiePolicyOptions() - { - Secure = Microsoft.AspNetCore.Http.CookieSecurePolicy.Always, - HttpOnly = Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy.Always - }); - } -} \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/CWE-1004/httponlyflag.cs b/csharp/ql/src/experimental/Security Features/CWE-1004/httponlyflag.cs deleted file mode 100644 index 09f8dd8b1fa3..000000000000 --- a/csharp/ql/src/experimental/Security Features/CWE-1004/httponlyflag.cs +++ /dev/null @@ -1,7 +0,0 @@ -class MyController : Controller -{ - void Login() - { - var cookie = new System.Web.HttpCookie("cookieName") { HttpOnly = true }; - } -} \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/CWE-1004/httponlyflagcore.cs b/csharp/ql/src/experimental/Security Features/CWE-1004/httponlyflagcore.cs deleted file mode 100644 index 455675b5ba9e..000000000000 --- a/csharp/ql/src/experimental/Security Features/CWE-1004/httponlyflagcore.cs +++ /dev/null @@ -1,8 +0,0 @@ -class MyController : Controller -{ - void Login() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { HttpOnly = true }; - Response.Cookies.Append("auth", "secret", cookieOptions); - } -} \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.cs b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.cs deleted file mode 100644 index 0810516ee401..000000000000 --- a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.cs +++ /dev/null @@ -1,44 +0,0 @@ - -{ - SymmetricKey aesKey = new SymmetricKey(kid: "symencryptionkey"); - - // BAD: Using the outdated client side encryption version V1_0 - BlobEncryptionPolicy uploadPolicy = new BlobEncryptionPolicy(key: aesKey, keyResolver: null); - BlobRequestOptions uploadOptions = new BlobRequestOptions() { EncryptionPolicy = uploadPolicy }; - - MemoryStream stream = new MemoryStream(buffer); - blob.UploadFromStream(stream, length: size, accessCondition: null, options: uploadOptions); -} - -var client = new BlobClient(myConnectionString, new SpecializedBlobClientOptions() -{ - // BAD: Using an outdated SDK that does not support client side encryption version V2_0 - ClientSideEncryption = new ClientSideEncryptionOptions() - { - KeyEncryptionKey = myKey, - KeyResolver = myKeyResolver, - KeyWrapAlgorithm = myKeyWrapAlgorithm - } -}); - -var client = new BlobClient(myConnectionString, new SpecializedBlobClientOptions() -{ - // BAD: Using the outdated client side encryption version V1_0 - ClientSideEncryption = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V1_0) - { - KeyEncryptionKey = myKey, - KeyResolver = myKeyResolver, - KeyWrapAlgorithm = myKeyWrapAlgorithm - } -}); - -var client = new BlobClient(myConnectionString, new SpecializedBlobClientOptions() -{ - // GOOD: Using client side encryption version V2_0 - ClientSideEncryption = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V2_0) - { - KeyEncryptionKey = myKey, - KeyResolver = myKeyResolver, - KeyWrapAlgorithm = myKeyWrapAlgorithm - } -}); \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp deleted file mode 100644 index 54c9a4998b4c..000000000000 --- a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp +++ /dev/null @@ -1,29 +0,0 @@ - - - - - -

    Azure Storage .NET, Java, and Python SDKs support encryption on the client with a customer-managed key that is maintained in Azure Key Vault or another key store.

    -

    Current release versions of the Azure Storage SDKs use cipher block chaining (CBC mode) for client-side encryption (referred to as v1).

    - -
    - - -

    Consider switching to v2 client-side encryption.

    - -
    - - - - - - -
  • - Azure Storage Client Encryption Blog. -
  • -
  • - CVE-2022-30187 -
  • - -
    -
    diff --git a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql deleted file mode 100644 index d8bbbce70658..000000000000 --- a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @name Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-30187). - * @description Unsafe usage of v1 version of Azure Storage client-side encryption, please refer to http://aka.ms/azstorageclientencryptionblog - * @kind problem - * @tags security - * cryptography - * experimental - * external/cwe/cwe-327 - * @id cs/azure-storage/unsafe-usage-of-client-side-encryption-version - * @problem.severity error - * @precision high - */ - -import csharp - -/** - * Holds if `oc` is creating an object of type `c` = `Azure.Storage.ClientSideEncryptionOptions` - * and `e` is the `version` argument to the constructor - */ -predicate isCreatingAzureClientSideEncryptionObject(ObjectCreation oc, Class c, Expr e) { - exists(Parameter p | p.hasName("version") | - c.hasFullyQualifiedName("Azure.Storage", "ClientSideEncryptionOptions") and - oc.getTarget() = c.getAConstructor() and - e = oc.getArgumentForParameter(p) - ) -} - -/** - * Holds if `oc` is an object creation of the outdated type `c` = `Microsoft.Azure.Storage.Blob.BlobEncryptionPolicy` - */ -predicate isCreatingOutdatedAzureClientSideEncryptionObject(ObjectCreation oc, Class c) { - c.hasFullyQualifiedName("Microsoft.Azure.Storage.Blob", "BlobEncryptionPolicy") and - oc.getTarget() = c.getAConstructor() -} - -/** - * Holds if the Azure.Storage assembly for `c` is a version known to support - * version 2+ for client-side encryption - */ -predicate doesAzureStorageAssemblySupportSafeClientSideEncryption(Assembly asm) { - exists(int versionCompare | - versionCompare = asm.getVersion().compareTo("12.12.0.0") and - versionCompare >= 0 - ) and - asm.getName() = "Azure.Storage.Common" -} - -/** - * Holds if the Azure.Storage assembly for `c` is a version known to support - * version 2+ for client-side encryption and if the argument for the constructor `version` - * is set to a secure value. - */ -predicate isObjectCreationArgumentSafeAndUsingSafeVersionOfAssembly(Expr versionExpr, Assembly asm) { - // Check if the Azure.Storage assembly version has the fix - doesAzureStorageAssemblySupportSafeClientSideEncryption(asm) and - // and that the version argument for the constructor is guaranteed to be Version2 - isExprAnAccessToSafeClientSideEncryptionVersionValue(versionExpr) -} - -/** - * Holds if the expression `e` is an access to a safe version of the enum `ClientSideEncryptionVersion` - * or an equivalent numeric value - */ -predicate isExprAnAccessToSafeClientSideEncryptionVersionValue(Expr e) { - exists(EnumConstant ec | - ec.hasFullyQualifiedName("Azure.Storage.ClientSideEncryptionVersion", "V2_0") and - ec.getAnAccess() = e - ) -} - -deprecated query predicate problems(Expr e, string message) { - exists(Class c, Assembly asm | asm = c.getLocation() | - exists(Expr e2 | - isCreatingAzureClientSideEncryptionObject(e, c, e2) and - not isObjectCreationArgumentSafeAndUsingSafeVersionOfAssembly(e2, asm) - ) - or - isCreatingOutdatedAzureClientSideEncryptionObject(e, c) - ) and - message = "Unsafe usage of v1 version of Azure Storage client-side encryption." -} diff --git a/csharp/ql/src/experimental/Security Features/CWE-614/CookieWithoutSecure.qhelp b/csharp/ql/src/experimental/Security Features/CWE-614/CookieWithoutSecure.qhelp deleted file mode 100644 index ddf825aed26e..000000000000 --- a/csharp/ql/src/experimental/Security Features/CWE-614/CookieWithoutSecure.qhelp +++ /dev/null @@ -1,55 +0,0 @@ - - - - -

    -Sensitive data that is transmitted using HTTP is vulnerable to being read by a third party. By default, -cookies are sent via HTTP, not HTTPS. -

    -
    - - -

    -In ASP.NET case when using cookies ensure that HTTPS is used by setting the property Microsoft.AspNetCore.Http.CookieOptions.Secure to true. -

    -

    -In ASP.NET Core case when using cookies, ensure that HTTPS is used, either via the <forms> attribute above, or -the <httpCookies> element, with the attribute requireSSL="true". It is also possible to require cookies -to use HTTPS programmatically, by setting the property System.Web.HttpCookie.Secure to true. -

    -
    - - - -

    -In the example below Microsoft.AspNetCore.Http.CookieOptions.Secure is set to true programmatically. -

    - - - -

    -In the following example CookiePolicyOptions are set programmatically to configure defaults. -

    - - - -

    -In the example below System.Web.HttpCookie.Secure is set to true programmatically. -

    - - - -
    - - - -
  • CookieOptions.Secure Property,
  • -
  • Set-Cookie Header,
  • -
  • FormsAuthentication.RequireSSL Property,
  • -
  • forms Element for authentication,
  • -
  • httpCookies Element,
  • - -
    -
    diff --git a/csharp/ql/src/experimental/Security Features/CWE-614/CookieWithoutSecure.ql b/csharp/ql/src/experimental/Security Features/CWE-614/CookieWithoutSecure.ql deleted file mode 100644 index d7628f7b2c7b..000000000000 --- a/csharp/ql/src/experimental/Security Features/CWE-614/CookieWithoutSecure.ql +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @name 'Secure' attribute is not set to true - * @description Omitting the 'Secure' attribute allows data to be transmitted insecurely - * using HTTP. Always set 'Secure' to 'true' to ensure that HTTPS - * is used at all times. - * @kind problem - * @problem.severity error - * @precision high - * @id cs/web/cookie-secure-not-set - * @tags security - * experimental - * external/cwe/cwe-319 - * external/cwe/cwe-614 - */ - -import csharp -import semmle.code.asp.WebConfig -import semmle.code.csharp.frameworks.system.Web -import semmle.code.csharp.frameworks.microsoft.AspNetCore -deprecated import experimental.dataflow.flowsources.AuthCookie - -deprecated query predicate problems(Expr secureSink, string message) { - ( - exists(Call c | - secureSink = c and - ( - // default is not configured or is not set to `Always` or `SameAsRequest` - not ( - getAValueForCookiePolicyProp("Secure").getValue() = "0" or - getAValueForCookiePolicyProp("Secure").getValue() = "1" - ) and - // there is no callback `OnAppendCookie` that sets `Secure` to true - not OnAppendCookieSecureTracking::flowTo(_) and - ( - // `Secure` property in `CookieOptions` passed to IResponseCookies.Append(...) wasn't set - exists(ObjectCreation oc | - oc = c and - oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and - not isPropertySet(oc, "Secure") and - exists(DataFlow::Node creation | - CookieOptionsTracking::flow(creation, _) and - creation.asExpr() = oc - ) - ) - or - // IResponseCookies.Append(String, String) was called, `Secure` is set to `false` by default - exists(MethodCall mc, MicrosoftAspNetCoreHttpResponseCookies iResponse | - mc = c and - iResponse.getAppendMethod() = mc.getTarget() and - mc.getNumberOfArguments() < 3 - ) - ) - or - exists(ObjectCreation oc | - oc = c and - oc.getType() instanceof SystemWebHttpCookie and - // the property wasn't explicitly set, so a default value from config is used - not isPropertySet(oc, "Secure") and - // the default in config is not set to `true` - // the `exists` below covers the `cs/web/requiressl-not-set` - not exists(XmlElement element | - element instanceof FormsElement and - element.(FormsElement).isRequireSsl() - or - element instanceof HttpCookiesElement and - element.(HttpCookiesElement).isRequireSsl() - ) - ) - ) - ) - or - exists(Assignment a, Expr val | - secureSink = a.getRValue() and - ( - exists(ObjectCreation oc | - getAValueForProp(oc, a, "Secure") = val and - val.getValue() = "false" and - ( - oc.getType() instanceof SystemWebHttpCookie - or - oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and - // there is no callback `OnAppendCookie` that sets `Secure` to true - not OnAppendCookieSecureTracking::flowTo(_) and - // the cookie option is passed to `Append` - exists(DataFlow::Node creation | - CookieOptionsTracking::flow(creation, _) and - creation.asExpr() = oc - ) - ) - ) - or - exists(PropertyWrite pw | - ( - pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreHttpCookieBuilder or - pw.getProperty().getDeclaringType() instanceof - MicrosoftAspNetCoreAuthenticationCookiesCookieAuthenticationOptions - ) and - pw.getProperty().getName() = "SecurePolicy" and - a.getLValue() = pw and - DataFlow::localExprFlow(val, a.getRValue()) and - val.getValue() = "2" // None - ) - ) - ) - ) and - message = "Cookie attribute 'Secure' is not set to true." -} diff --git a/csharp/ql/src/experimental/Security Features/CWE-614/Web.config b/csharp/ql/src/experimental/Security Features/CWE-614/Web.config deleted file mode 100644 index 89d4561cd625..000000000000 --- a/csharp/ql/src/experimental/Security Features/CWE-614/Web.config +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - diff --git a/csharp/ql/src/experimental/Security Features/CWE-614/cookiepolicyoptions.cs b/csharp/ql/src/experimental/Security Features/CWE-614/cookiepolicyoptions.cs deleted file mode 100644 index a9adf0d99822..000000000000 --- a/csharp/ql/src/experimental/Security Features/CWE-614/cookiepolicyoptions.cs +++ /dev/null @@ -1,12 +0,0 @@ -public class Startup -{ - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - app.UseCookiePolicy(new CookiePolicyOptions() - { - Secure = Microsoft.AspNetCore.Http.CookieSecurePolicy.Always, - HttpOnly = Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy.Always - }); - } -} \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/CWE-614/secureflag.cs b/csharp/ql/src/experimental/Security Features/CWE-614/secureflag.cs deleted file mode 100644 index 4542d8630e2d..000000000000 --- a/csharp/ql/src/experimental/Security Features/CWE-614/secureflag.cs +++ /dev/null @@ -1,7 +0,0 @@ -class MyController : Controller -{ - void Login() - { - var cookie = new System.Web.HttpCookie("cookieName") { Secure = true }; - } -} \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/CWE-614/secureflagcore.cs b/csharp/ql/src/experimental/Security Features/CWE-614/secureflagcore.cs deleted file mode 100644 index 5d8163cdf8d6..000000000000 --- a/csharp/ql/src/experimental/Security Features/CWE-614/secureflagcore.cs +++ /dev/null @@ -1,8 +0,0 @@ -class MyController : Controller -{ - void Login() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { Secure = true }; - Response.Cookies.Append("auth", "secret", cookieOptions); - } -} \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/CWE-759/HashWithoutSalt.cs b/csharp/ql/src/experimental/Security Features/CWE-759/HashWithoutSalt.cs deleted file mode 100644 index 309d2e0d7851..000000000000 --- a/csharp/ql/src/experimental/Security Features/CWE-759/HashWithoutSalt.cs +++ /dev/null @@ -1,65 +0,0 @@ -public class Test -{ - private const int SaltSize = 32; - - // BAD - Hash without a salt. - public static String HashPassword(string password, string strAlgName ="SHA256") - { - IBuffer passBuff = CryptographicBuffer.ConvertStringToBinary(password, BinaryStringEncoding.Utf8); - HashAlgorithmProvider algProvider = HashAlgorithmProvider.OpenAlgorithm(strAlgName); - IBuffer hashBuff = algProvider.HashData(passBuff); - return CryptographicBuffer.EncodeToBase64String(hashBuff); - } - - // GOOD - Hash with a salt. - public static string HashPassword2(string password, string salt, string strAlgName ="SHA256") - { - // Concatenate the salt with the password. - IBuffer passBuff = CryptographicBuffer.ConvertStringToBinary(password+salt, BinaryStringEncoding.Utf8); - HashAlgorithmProvider algProvider = HashAlgorithmProvider.OpenAlgorithm(strAlgName); - IBuffer hashBuff = algProvider.HashData(passBuff); - return CryptographicBuffer.EncodeToBase64String(hashBuff); - } - - // BAD - Hash without a salt. - public static string HashPassword(string password) - { - SHA256 sha256Hash = SHA256.Create(); - byte[] passBytes = System.Text.Encoding.ASCII.GetBytes(password); - byte[] hashBytes = sha256Hash.ComputeHash(passBytes); - return Convert.ToBase64String(hashBytes); - } - - // GOOD - Hash with a salt. - public static string HashPassword2(string password) - { - byte[] passBytes = System.Text.Encoding.ASCII.GetBytes(password); - byte[] saltBytes = GenerateSalt(); - - // Add the salt to the hash. - byte[] rawSalted = new byte[passBytes.Length + saltBytes.Length]; - passBytes.CopyTo(rawSalted, 0); - saltBytes.CopyTo(rawSalted, passBytes.Length); - - //Create the salted hash. - SHA256 sha256 = SHA256.Create(); - byte[] saltedPassBytes = sha256.ComputeHash(rawSalted); - - // Add the salt value to the salted hash. - byte[] dbPassword = new byte[saltedPassBytes.Length + saltBytes.Length]; - saltedPassBytes.CopyTo(dbPassword, 0); - saltBytes.CopyTo(dbPassword, saltedPassBytes.Length); - - return Convert.ToBase64String(dbPassword); - } - - public static byte[] GenerateSalt() - { - using (var rng = new RNGCryptoServiceProvider()) - { - var randomNumber = new byte[SaltSize]; - rng.GetBytes(randomNumber); - return randomNumber; - } - } -} diff --git a/csharp/ql/src/experimental/Security Features/CWE-759/HashWithoutSalt.qhelp b/csharp/ql/src/experimental/Security Features/CWE-759/HashWithoutSalt.qhelp deleted file mode 100644 index 3e0583f92eac..000000000000 --- a/csharp/ql/src/experimental/Security Features/CWE-759/HashWithoutSalt.qhelp +++ /dev/null @@ -1,29 +0,0 @@ - - - - -

    In cryptography, a salt is some random data used as an additional input to a one-way function that hashes a password or pass-phrase. It makes dictionary attacks more difficult.

    - -

    Without a salt, it is much easier for attackers to pre-compute the hash value using dictionary attack techniques such as rainbow tables to crack passwords.

    -
    - - -

    Use a long random salt of at least 32 bytes then use the combination of password and salt to hash a password or password phrase.

    -
    - - -

    The following example shows two ways of hashing. In the 'BAD' cases, no salt is provided. In the 'GOOD' cases, a salt is provided.

    - -
    - - -
  • - DZone: - A Look at Java Cryptography -
  • -
  • - CWE: - CWE-759: Use of a One-Way Hash without a Salt -
  • -
    -
    diff --git a/csharp/ql/src/experimental/Security Features/CWE-759/HashWithoutSalt.ql b/csharp/ql/src/experimental/Security Features/CWE-759/HashWithoutSalt.ql deleted file mode 100644 index f18798c8b086..000000000000 --- a/csharp/ql/src/experimental/Security Features/CWE-759/HashWithoutSalt.ql +++ /dev/null @@ -1,204 +0,0 @@ -/** - * @name Use of a hash function without a salt - * @description Hashed passwords without a salt are vulnerable to dictionary attacks. - * @kind path-problem - * @problem.severity error - * @id cs/hash-without-salt - * @tags security - * experimental - * external/cwe/cwe-759 - */ - -import csharp -import HashWithoutSalt::PathGraph - -/** The C# class `Windows.Security.Cryptography.Core.HashAlgorithmProvider`. */ -class HashAlgorithmProvider extends RefType { - HashAlgorithmProvider() { - this.hasFullyQualifiedName("Windows.Security.Cryptography.Core", "HashAlgorithmProvider") - } -} - -/** The C# class `System.Security.Cryptography.HashAlgorithm`. */ -class HashAlgorithm extends RefType { - HashAlgorithm() { this.hasFullyQualifiedName("System.Security.Cryptography", "HashAlgorithm") } -} - -/** The C# class `System.Security.Cryptography.KeyedHashAlgorithm`. */ -class KeyedHashAlgorithm extends RefType { - KeyedHashAlgorithm() { - this.hasFullyQualifiedName("System.Security.Cryptography", "KeyedHashAlgorithm") - } -} - -/** - * The method `ComputeHash()`, `ComputeHashAsync`, `TryComputeHash`, `HashData`, or - * `TryHashData` declared in `System.Security.Cryptography.HashAlgorithm` and the method - * `HashData()` declared in `Windows.Security.Cryptography.Core.HashAlgorithmProvider`. - */ -class HashMethod extends Method { - HashMethod() { - this.getDeclaringType().getABaseType*() instanceof HashAlgorithm and - this.getName().matches(["%ComputeHash%", "%HashData"]) - or - this.getDeclaringType().getABaseType*() instanceof HashAlgorithmProvider and - this.hasName("HashData") - } -} - -/** - * Gets a regular expression for matching common names of variables that indicate the - * value being held is a password. - */ -string getPasswordRegex() { result = "(?i)pass(wd|word|code|phrase)" } - -/** Finds variables that hold password information judging by their names. */ -class PasswordVarExpr extends Expr { - PasswordVarExpr() { - exists(Variable v | this = v.getAnAccess() | v.getName().regexpMatch(getPasswordRegex())) - } -} - -/** - * Holds if `mc` is a hashing method call or invokes a hashing method call - * directly or indirectly. - */ -predicate isHashCall(MethodCall mc) { - mc.getTarget() instanceof HashMethod - or - exists(MethodCall mcc | - mc.getTarget().calls(mcc.getTarget()) and - isHashCall(mcc) and - DataFlow::localExprFlow(mc.getTarget().getAParameter().getAnAccess(), mcc.getAnArgument()) - ) -} - -/** Holds if there is another hashing method call. */ -predicate hasAnotherHashCall(MethodCall mc) { - exists(MethodCall mc2, DataFlow::Node src, DataFlow::Node sink | - isHashCall(mc2) and - mc2 != mc and - ( - src.asExpr() = mc.getQualifier() or - src.asExpr() = mc.getAnArgument() or - src.asExpr() = mc - ) and - ( - sink.asExpr() = mc2.getQualifier() or - sink.asExpr() = mc2.getAnArgument() - ) and - DataFlow::localFlow(src, sink) - ) -} - -/** Holds if a password hash without salt is further processed in another method call. */ -predicate hasFurtherProcessing(MethodCall mc) { - mc.getTarget().fromLibrary() and - ( - mc.getTarget().hasFullyQualifiedName("System", "Array", "Copy") or // Array.Copy(passwordHash, 0, password.Length), 0, key, 0, keyLen); - mc.getTarget().hasFullyQualifiedName("System", "String", "Concat") or // string.Concat(passwordHash, saltkey) - mc.getTarget().hasFullyQualifiedName("System", "Buffer", "BlockCopy") or // Buffer.BlockCopy(passwordHash, 0, allBytes, 0, 20) - mc.getTarget().hasFullyQualifiedName("System", "String", "Format") // String.Format("{0}:{1}:{2}", username, salt, password) - ) -} - -/** - * Holds if `mc` is part of a call graph that satisfies `isHashCall` but is not at the - * top of the call hierarchy. - */ -predicate hasHashAncestor(MethodCall mc) { - exists(MethodCall mpc | - mpc.getTarget().calls(mc.getTarget()) and - isHashCall(mpc) and - DataFlow::localExprFlow(mpc.getTarget().getAParameter().getAnAccess(), mc.getAnArgument()) - ) -} - -/** - * Taint configuration tracking flow from an expression whose name suggests it holds - * password data to a method call that generates a hash without a salt. - */ -module HashWithoutSaltConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { source.asExpr() instanceof PasswordVarExpr } - - predicate isSink(DataFlow::Node sink) { - exists(MethodCall mc | - sink.asExpr() = mc.getArgument(0) and - isHashCall(mc) and - not hasAnotherHashCall(mc) and - not hasHashAncestor(mc) and - not exists(MethodCall mmc | - hasFurtherProcessing(mmc) and - DataFlow::localExprFlow(mc, mmc.getAnArgument()) - ) and - not exists(Call c | - ( - c.getTarget().getDeclaringType().getABaseType*() instanceof HashAlgorithm or - c.getTarget() - .getDeclaringType() - .getABaseType*() - .hasFullyQualifiedName("System.Security.Cryptography", "DeriveBytes") - ) and - DataFlow::localExprFlow(mc, c.getAnArgument()) - ) - ) - } - - predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - exists(MethodCall mc | - mc.getTarget() - .hasFullyQualifiedName("Windows.Security.Cryptography", "CryptographicBuffer", - "ConvertStringToBinary") and - mc.getArgument(0) = node1.asExpr() and - mc = node2.asExpr() - ) - } - - /** - * Holds if a password is concatenated with a salt then hashed together through calls such as `System.Array.CopyTo()`, for example, - * `byte[] rawSalted = new byte[passBytes.Length + salt.Length];` - * `passBytes.CopyTo(rawSalted, 0);` - * `salt.CopyTo(rawSalted, passBytes.Length);` - * `byte[] saltedPassword = sha256.ComputeHash(rawSalted);` - * Or the password is concatenated with a salt as a string. - */ - predicate isBarrier(DataFlow::Node node) { - exists(MethodCall mc | - hasFurtherProcessing(mc) and - mc.getAnArgument() = node.asExpr() - ) - or - exists(AddExpr e | node.asExpr() = e.getAnOperand()) // password+salt - or - exists(InterpolatedStringExpr e | node.asExpr() = e.getAnInsert()) - or - exists(Call c | - c.getTarget() - .getDeclaringType() - .getABaseType*() - .hasFullyQualifiedName("System.Security.Cryptography", "DeriveBytes") - ) - or - // a salt or key is included in subclasses of `KeyedHashAlgorithm` - exists(MethodCall mc, Assignment a, ObjectCreation oc | - a.getRValue() = oc and - oc.getObjectType().getABaseType+() instanceof KeyedHashAlgorithm and - mc.getTarget() instanceof HashMethod and - a.getLValue() = mc.getQualifier().(VariableAccess).getTarget().getAnAccess() and - mc.getArgument(0) = node.asExpr() - ) - } -} - -module HashWithoutSalt = TaintTracking::Global; - -deprecated query predicate problems( - DataFlow::Node sinkNode, HashWithoutSalt::PathNode source, HashWithoutSalt::PathNode sink, - string message, DataFlow::Node sourceNode, string password -) { - sinkNode = sink.getNode() and - sourceNode = source.getNode() and - HashWithoutSalt::flowPath(source, sink) and - message = "$@ is hashed without a salt." and - password = "The password" -} diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll deleted file mode 100644 index ae2c1442e7c2..000000000000 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/JsonWebTokenHandlerLib.qll +++ /dev/null @@ -1,209 +0,0 @@ -deprecated module; - -import csharp -import DataFlow - -/** - * A sensitive property for `TokenValidationParameters` that updates the underlying value. - */ -class TokenValidationParametersPropertySensitiveValidation extends Property { - TokenValidationParametersPropertySensitiveValidation() { - exists(Class c | - c.hasFullyQualifiedName("Microsoft.IdentityModel.Tokens", "TokenValidationParameters") - | - c.getAProperty() = this and - this.getName() in [ - "ValidateIssuer", "ValidateAudience", "ValidateLifetime", "RequireExpirationTime", - "RequireAudience" - ] - ) - } -} - -/** - * A dataflow configuration from a `false` value to a write sensitive property for `TokenValidationParameters`. - */ -private module FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidationConfig - implements DataFlow::ConfigSig -{ - predicate isSource(DataFlow::Node source) { - source.asExpr().getValue() = "false" and - source.asExpr().getType() instanceof BoolType - } - - predicate isSink(DataFlow::Node sink) { - sink.asExpr() = any(TokenValidationParametersPropertySensitiveValidation p).getAnAssignedValue() - } -} - -module FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidation = - DataFlow::Global; - -/** - * Holds if `assemblyName` is older than version `ver` - */ -bindingset[ver] -predicate isAssemblyOlderVersion(string assemblyName, string ver) { - exists(Assembly a | - a.getName() = assemblyName and - a.getVersion().isEarlierThan(ver) - ) -} - -/** - * A method `ValidateToken` for `Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler` or other Token handler that shares the same behavior characteristics - */ -class JsonWebTokenHandlerValidateTokenMethod extends Method { - JsonWebTokenHandlerValidateTokenMethod() { - this.hasFullyQualifiedName("Microsoft.IdentityModel.JsonWebTokens", "JsonWebTokenHandler", - "ValidateToken") or - this.hasFullyQualifiedName("Microsoft.AzureAD.DeviceIdentification.Common.Tokens", - "JwtValidator", "ValidateEncryptedToken") - } -} - -/** - * A Call to `Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateToken` - */ -class JsonWebTokenHandlerValidateTokenCall extends MethodCall { - JsonWebTokenHandlerValidateTokenCall() { - this.getTarget() instanceof JsonWebTokenHandlerValidateTokenMethod - } -} - -/** - * A read access for properties `IsValid` or `Exception` for `Microsoft.IdentityModel.JsonWebTokens.JsonWebTokenHandler.ValidateToken` - */ -private class TokenValidationResultIsValidCall extends PropertyRead { - TokenValidationResultIsValidCall() { - exists(Property p | p.getAnAccess() = this | - p.hasName("IsValid") or - p.hasName("Exception") - ) - } -} - -/** - * A security-sensitive property for `Microsoft.IdentityModel.Tokens.TokenValidationParameters` - */ -class TokenValidationParametersProperty extends Property { - TokenValidationParametersProperty() { - exists(Class c | - c.hasFullyQualifiedName("Microsoft.IdentityModel.Tokens", "TokenValidationParameters") - | - c.getAProperty() = this and - this.getName() in [ - "SignatureValidator", "TokenReplayValidator", "AlgorithmValidator", "AudienceValidator", - "IssuerSigningKeyValidator", "LifetimeValidator" - ] - ) - } -} - -/** - * Holds if the callable has a return statement and it always returns true for all such statements - */ -predicate callableHasAReturnStmtAndAlwaysReturnsTrue(Callable c) { - c.getReturnType() instanceof BoolType and - not callableMayThrowException(c) and - forex(ReturnStmt rs | rs.getEnclosingCallable() = c | - rs.getNumberOfChildren() = 1 and - isExpressionAlwaysTrue(rs.getChildExpr(0)) - ) -} - -/** - * Holds if the lambda expression `le` always returns true - */ -predicate lambdaExprReturnsOnlyLiteralTrue(AnonymousFunctionExpr le) { - isExpressionAlwaysTrue(le.getExpressionBody()) -} - -class CallableAlwaysReturnsTrue extends Callable { - CallableAlwaysReturnsTrue() { - callableHasAReturnStmtAndAlwaysReturnsTrue(this) - or - lambdaExprReturnsOnlyLiteralTrue(this) - } -} - -/** - * Holds if any exception being thrown by the callable is of type `System.ArgumentNullException` - * It will also hold if no exceptions are thrown by the callable - */ -predicate callableOnlyThrowsArgumentNullException(Callable c) { - forall(ThrowElement thre | c = thre.getEnclosingCallable() | - thre.getThrownExceptionType().hasFullyQualifiedName("System", "ArgumentNullException") - ) -} - -/** - * A callable that returns a `string` and has a `string` as 1st argument - */ -private class CallableReturnsStringAndArg0IsString extends Callable { - CallableReturnsStringAndArg0IsString() { - this.getReturnType() instanceof StringType and - this.getParameter(0).getType() instanceof StringType - } -} - -/** - * A Callable that always return the 1st argument, both of `string` type - */ -class CallableAlwaysReturnsParameter0 extends CallableReturnsStringAndArg0IsString { - CallableAlwaysReturnsParameter0() { - forex(Expr ret | this.canReturn(ret) | - ret = this.getParameter(0).getAnAccess() - or - exists(CallableAlwaysReturnsParameter0 c | - ret = c.getACall() and - ret.(Call).getArgument(0) = this.getParameter(0).getAnAccess() - ) - ) - } -} - -/** - * A Callable that always return the 1st argument, both of `string` type. Higher precision - */ -class CallableAlwaysReturnsParameter0MayThrowExceptions extends CallableReturnsStringAndArg0IsString -{ - CallableAlwaysReturnsParameter0MayThrowExceptions() { - forex(Expr ret | this.canReturn(ret) | - ret = this.getParameter(0).getAnAccess() - or - exists(CallableAlwaysReturnsParameter0MayThrowExceptions c | - ret = c.getACall() and - ret.(Call).getArgument(0) = this.getParameter(0).getAnAccess() - ) - ) - } -} - -/** - * Hold if the `Expr` e is a `BoolLiteral` with value true, - * the expression has a predictable value == `true`, - * or if it is a `ConditionalExpr` where the `then` and `else` expressions meet `isExpressionAlwaysTrue` criteria - */ -predicate isExpressionAlwaysTrue(Expr e) { - e.(BoolLiteral).getBoolValue() = true - or - e.getValue() = "true" - or - e instanceof ConditionalExpr and - isExpressionAlwaysTrue(e.(ConditionalExpr).getThen()) and - isExpressionAlwaysTrue(e.(ConditionalExpr).getElse()) - or - exists(Callable callable | - callableHasAReturnStmtAndAlwaysReturnsTrue(callable) and - callable.getACall() = e - ) -} - -/** - * Holds if the `Callable` c throws any exception other than `ThrowsArgumentNullException` - */ -predicate callableMayThrowException(Callable c) { - exists(ThrowStmt thre | c = thre.getEnclosingCallable()) and - not callableOnlyThrowsArgumentNullException(c) -} diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true-bad.cs b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true-bad.cs deleted file mode 100644 index 2eda6821019a..000000000000 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true-bad.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using Microsoft.IdentityModel.Tokens; -class TestClass -{ - public void TestMethod() - { - TokenValidationParameters parameters = new TokenValidationParameters(); - parameters.AudienceValidator = (audiences, token, tvp) => { return true; }; - } -} \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true-good.cs b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true-good.cs deleted file mode 100644 index 28ba1d6f94ed..000000000000 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true-good.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using Microsoft.IdentityModel.Tokens; -class TestClass -{ - public void TestMethod() - { - TokenValidationParameters parameters = new TokenValidationParameters(); - parameters.AudienceValidator = (audiences, token, tvp) => - { - // Implement your own custom audience validation - if (PerformCustomAudienceValidation(audiences, token)) - return true; - else - return false; - }; - } -} \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.qhelp b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.qhelp deleted file mode 100644 index 8c4f8dff229c..000000000000 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.qhelp +++ /dev/null @@ -1,28 +0,0 @@ - - - -

    By setting critical TokenValidationParameter validation delegates to always return true, important authentication safeguards are disabled. Disabling safeguards can lead to incorrect validation of tokens from any issuer or expired tokens.

    - -
    - -

    Improve the logic of the delegate so not all code paths return true, which effectively disables that type of validation; or throw SecurityTokenInvalidAudienceException or SecurityTokenInvalidLifetimeException in failure cases when you want to fail validation and have other cases pass by returning true. -

    -
    - - -

    This example delegates AudienceValidator to a callable that always returns true.

    - - -

    To fix it, use a callable that performs a validation, and fails when appropriate.

    - - -
    - - - -
  • azure-activedirectory-identitymodel-extensions-for-dotnet ValidatingTokens wiki
  • - -
    -
    \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql deleted file mode 100644 index 0804f91d54e8..000000000000 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @name Delegated security sensitive validations for JsonWebTokenHandler always return true, medium precision - * @description Security sensitive validations for `JsonWebTokenHandler` are being delegated to a function that seems to always return true. - * Higher precision version checks for exception throws, so less false positives are expected. - * @kind problem - * @tags security - * experimental - * JsonWebTokenHandler - * manual-verification-required - * @id cs/json-webtoken-handler/delegated-security-validations-always-return-true - * @problem.severity error - * @precision high - */ - -import csharp -import DataFlow -deprecated import JsonWebTokenHandlerLib -import semmle.code.csharp.commons.QualifiedName - -deprecated query predicate problems( - CallableAlwaysReturnsTrue e, string message, TokenValidationParametersProperty p, - string fullyQualifiedName -) { - exists(string qualifier, string name | p.hasFullyQualifiedName(qualifier, name) | - fullyQualifiedName = getQualifiedName(qualifier, name) - ) and - e = p.getAnAssignedValue() and - message = - "JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns \"true\"." -} diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-bad.cs b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-bad.cs deleted file mode 100644 index 81df44fea9ad..000000000000 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-bad.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using Microsoft.IdentityModel.Tokens; -class TestClass -{ - public void TestMethod() - { - TokenValidationParameters parameters = new TokenValidationParameters(); - parameters.RequireExpirationTime = false; - parameters.ValidateAudience = false; - parameters.ValidateIssuer = false; - parameters.ValidateLifetime = false; - } -} \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-good.cs b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-good.cs deleted file mode 100644 index e2f74c0653da..000000000000 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-good.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using Microsoft.IdentityModel.Tokens; -class TestClass -{ - public void TestMethod() - { - TokenValidationParameters parameters = new TokenValidationParameters(); - parameters.RequireExpirationTime = true; - parameters.ValidateAudience = true; - parameters.ValidateIssuer = true; - parameters.ValidateLifetime = true; - } -} \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.qhelp b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.qhelp deleted file mode 100644 index 5c027ac3148b..000000000000 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.qhelp +++ /dev/null @@ -1,27 +0,0 @@ - - - -

    Token validation checks ensure that while validating tokens, all aspects are analyzed and verified. Turning off validation can lead to security holes by allowing untrusted tokens to make it through validation.

    - -
    - -

    Set Microsoft.IdentityModel.Tokens.TokenValidationParameters properties RequireExpirationTime, ValidateAudience, ValidateIssuer, or ValidateLifetime to true. Or, remove the assignment to false because the default value is true.

    -
    - - -

    This example disabled the validation.

    - - -

    To fix it, do not disable the validations or use the default value.

    - - -
    - - - -
  • azure-activedirectory-identitymodel-extensions-for-dotnet ValidatingTokens wiki
  • - -
    -
    \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql b/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql deleted file mode 100644 index ab4afe966963..000000000000 --- a/csharp/ql/src/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql +++ /dev/null @@ -1,29 +0,0 @@ -/** - * @name Security sensitive JsonWebTokenHandler validations are disabled - * @description Check if security sensitive token validations for `JsonWebTokenHandler` are being disabled. - * @kind problem - * @tags security - * experimental - * JsonWebTokenHandler - * manual-verification-required - * @id cs/json-webtoken-handler/security-validations-disabled - * @problem.severity error - * @precision high - */ - -import csharp -deprecated import JsonWebTokenHandlerLib -import semmle.code.csharp.commons.QualifiedName - -deprecated query predicate problems( - DataFlow::Node sink, string message, TokenValidationParametersPropertySensitiveValidation pw, - string fullyQualifiedName, DataFlow::Node source, string value -) { - FalseValueFlowsToTokenValidationParametersPropertyWriteToBypassValidation::flow(source, sink) and - sink.asExpr() = pw.getAnAssignedValue() and - exists(string qualifier, string name | pw.hasFullyQualifiedName(qualifier, name) | - fullyQualifiedName = getQualifiedName(qualifier, name) - ) and - message = "The security sensitive property $@ is being disabled by the following value: $@." and - value = "false" -} diff --git a/csharp/ql/src/experimental/Security Features/Serialization/DataSetSerialization.inc.qhelp b/csharp/ql/src/experimental/Security Features/Serialization/DataSetSerialization.inc.qhelp deleted file mode 100644 index 7575352f4f16..000000000000 --- a/csharp/ql/src/experimental/Security Features/Serialization/DataSetSerialization.inc.qhelp +++ /dev/null @@ -1,23 +0,0 @@ - - - -

    The DataSet and DataTable types are legacy .NET components that you can use to represent data sets as managed objects.

    - -

    While DataSet and DataTable do impose default limitations on the types that are allowed to be present while deserializing XML payloads, DataSet and DataTable are in general not safe when populated with untrusted input.

    - -

    Please visit DataSet and DataTable security guidance for more details.

    - -
    - - -

    Please review the DataSet and DataTable security guidance before making use of these types for serialization.

    - -
    - - -
  • Microsoft DocsDataSet and DataTable security guidance.
  • - -
    -
    diff --git a/csharp/ql/src/experimental/Security Features/Serialization/DataSetSerialization.qll b/csharp/ql/src/experimental/Security Features/Serialization/DataSetSerialization.qll deleted file mode 100644 index 324dc883a352..000000000000 --- a/csharp/ql/src/experimental/Security Features/Serialization/DataSetSerialization.qll +++ /dev/null @@ -1,95 +0,0 @@ -/** - * Provides classes for `DataSet` or `DataTable` deserialization queries. - * - * Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details. - */ -deprecated module; - -import csharp - -/** - * Abstract class that depends or inherits from `DataSet` or `DataTable` types. - */ -abstract class DataSetOrTableRelatedClass extends Class { } - -/** - * `DataSet`, `DataTable` types, or any types derived from them. - */ -class DataSetOrTable extends DataSetOrTableRelatedClass { - DataSetOrTable() { - this.getABaseType*().hasFullyQualifiedName("System.Data", "DataTable") or - this.getABaseType*().hasFullyQualifiedName("System.Data", "DataSet") - } -} - -/** - * A Class that include a property or generic collection of type `DataSet` and `DataTable` - */ -class ClassWithDataSetOrTableMember extends DataSetOrTableRelatedClass { - ClassWithDataSetOrTableMember() { - this.getAMember().(AssignableMember).getType() instanceof DataSetOrTable - or - exists(Property p | p = this.getAProperty() | - p.getType() instanceof DataSetOrTable or - p.getType().(ConstructedGeneric).getATypeArgument() instanceof DataSetOrTable - ) - } -} - -/** - * Serializable types - */ -class SerializableClass extends Class { - SerializableClass() { - ( - this.getABaseType*() - .hasFullyQualifiedName("System.Xml.Serialization", ["XmlSerializer", "IXmlSerializable"]) or - this.getABaseType*() - .hasFullyQualifiedName("System.Runtime.Serialization", - [ - "ISerializable", "XmlObjectSerializer", "ISerializationSurrogateProvider", - "XmlSerializableServices" - ]) - ) - or - exists(Attribute a | a = this.getAnAttribute() | - a.getType().hasFullyQualifiedName("System", "SerializableAttribute") - ) - } -} - -/** - * Holds if the serializable class `c` has a property or field `m` that is of `DataSet` or `DataTable` related type - */ -predicate isClassUnsafeXmlSerializerImplementation(SerializableClass c, AssignableMember am) { - am = c.getAMember() and - am.getType() instanceof DataSetOrTableRelatedClass -} - -/** - * Serializable class that has a property or field that is of `DataSet` or `DataTable` related type - */ -class UnsafeXmlSerializerImplementation extends SerializableClass { - UnsafeXmlSerializerImplementation() { isClassUnsafeXmlSerializerImplementation(this, _) } -} - -/** - * Method that may be unsafe when used to deserialize DataSet and DataTable related types - */ -class UnsafeXmlReadMethod extends Method { - UnsafeXmlReadMethod() { - this.hasFullyQualifiedName("System.Data", ["DataTable", "DataSet"], ["ReadXml", "ReadXmlSchema"]) - or - this.getName().matches("ReadXml%") and - exists(Class c | c.getAMethod() = this | - c.getABaseType*() instanceof DataSetOrTableRelatedClass - ) - } -} - -/** - * MethodCall that may be unsafe when used to deserialize DataSet and DataTable related types - */ -class UnsafeXmlReadMethodCall extends MethodCall { - UnsafeXmlReadMethodCall() { exists(UnsafeXmlReadMethod uxrm | uxrm.getACall() = this) } -} diff --git a/csharp/ql/src/experimental/Security Features/Serialization/DefiningDatasetRelatedType.qhelp b/csharp/ql/src/experimental/Security Features/Serialization/DefiningDatasetRelatedType.qhelp deleted file mode 100644 index bbc0a82f2f7e..000000000000 --- a/csharp/ql/src/experimental/Security Features/Serialization/DefiningDatasetRelatedType.qhelp +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/csharp/ql/src/experimental/Security Features/Serialization/DefiningDatasetRelatedType.ql b/csharp/ql/src/experimental/Security Features/Serialization/DefiningDatasetRelatedType.ql deleted file mode 100644 index 2e62f406c1a4..000000000000 --- a/csharp/ql/src/experimental/Security Features/Serialization/DefiningDatasetRelatedType.ql +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @name Defining a class that inherits or has a property derived from the obsolete DataSet or DataTable types - * @description Defining a class that inherits or has a property derived from the obsolete DataSet or DataTable types may lead to the usage of dangerous functionality. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details. - * @kind problem - * @problem.severity warning - * @id cs/dataset-serialization/defining-dataset-related-type - * @tags security - * experimental - */ - -import csharp -deprecated import DataSetSerialization - -deprecated query predicate problems(DataSetOrTableRelatedClass dstc, string message) { - dstc.fromSource() and - message = - "Defining a class that inherits or has a property derived from the obsolete DataSet or DataTable types. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details." -} diff --git a/csharp/ql/src/experimental/Security Features/Serialization/DefiningPotentiallyUnsafeXmlSerializer.qhelp b/csharp/ql/src/experimental/Security Features/Serialization/DefiningPotentiallyUnsafeXmlSerializer.qhelp deleted file mode 100644 index bbc0a82f2f7e..000000000000 --- a/csharp/ql/src/experimental/Security Features/Serialization/DefiningPotentiallyUnsafeXmlSerializer.qhelp +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/csharp/ql/src/experimental/Security Features/Serialization/DefiningPotentiallyUnsafeXmlSerializer.ql b/csharp/ql/src/experimental/Security Features/Serialization/DefiningPotentiallyUnsafeXmlSerializer.ql deleted file mode 100644 index 7b8631eac395..000000000000 --- a/csharp/ql/src/experimental/Security Features/Serialization/DefiningPotentiallyUnsafeXmlSerializer.ql +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @name Defining a potentially unsafe XML serializer - * @description Defining an XML serializable class that includes members that derive from DataSet or DataTable type may lead to a security problem. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details. - * @kind problem - * @problem.severity error - * @precision medium - * @id cs/dataset-serialization/defining-potentially-unsafe-xml-serializer - * @tags security - * experimental - */ - -import csharp -deprecated import DataSetSerialization - -deprecated query predicate problems( - Member m, string message, UnsafeXmlSerializerImplementation c, string classMessage, Member member, - string memberMessage -) { - c.fromSource() and - isClassUnsafeXmlSerializerImplementation(c, m) and - message = - "Defining an serializable class $@ that has member $@ of a type that is derived from DataSet or DataTable types and may lead to a security problem. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details." and - classMessage = c.toString() and - member = m and - memberMessage = m.toString() -} diff --git a/csharp/ql/src/experimental/Security Features/Serialization/UnsafeTypeUsedDataContractSerializer.qhelp b/csharp/ql/src/experimental/Security Features/Serialization/UnsafeTypeUsedDataContractSerializer.qhelp deleted file mode 100644 index bbc0a82f2f7e..000000000000 --- a/csharp/ql/src/experimental/Security Features/Serialization/UnsafeTypeUsedDataContractSerializer.qhelp +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/csharp/ql/src/experimental/Security Features/Serialization/UnsafeTypeUsedDataContractSerializer.ql b/csharp/ql/src/experimental/Security Features/Serialization/UnsafeTypeUsedDataContractSerializer.ql deleted file mode 100644 index 49245d3d8f56..000000000000 --- a/csharp/ql/src/experimental/Security Features/Serialization/UnsafeTypeUsedDataContractSerializer.ql +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @name Unsafe type is used in data contract serializer - * @description Unsafe type is used in data contract serializer. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details." - * @kind problem - * @problem.severity error - * @precision medium - * @id cs/dataset-serialization/unsafe-type-used-data-contract-serializer - * @tags security - * experimental - */ - -import csharp -deprecated import DataSetSerialization - -predicate xmlSerializerConstructorArgument(Expr e) { - exists(ObjectCreation oc, Constructor c | e = oc.getArgument(0) | - c = oc.getTarget() and - c.getDeclaringType() - .getABaseType*() - .hasFullyQualifiedName("System.Xml.Serialization", "XmlSerializer") - ) -} - -deprecated predicate unsafeDataContractTypeCreation(Expr e) { - exists(MethodCall gt | - gt.getTarget().getName() = "GetType" and - e = gt and - gt.getQualifier().getType() instanceof DataSetOrTableRelatedClass - ) - or - e.(TypeofExpr).getTypeAccess().getTarget() instanceof DataSetOrTableRelatedClass -} - -deprecated module FlowToDataSerializerConstructorConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node node) { unsafeDataContractTypeCreation(node.asExpr()) } - - predicate isSink(DataFlow::Node node) { xmlSerializerConstructorArgument(node.asExpr()) } -} - -deprecated module FlowToDataSerializerConstructor = - DataFlow::Global; - -deprecated query predicate problems( - DataFlow::Node sink, string message, DataFlow::Node source, string sourceMessage -) { - FlowToDataSerializerConstructor::flow(source, sink) and - message = - "Unsafe type is used in data contract serializer. Make sure $@ comes from the trusted source." and - sourceMessage = source.toString() -} diff --git a/csharp/ql/src/experimental/Security Features/Serialization/XmlDeserializationWithDataSet.qhelp b/csharp/ql/src/experimental/Security Features/Serialization/XmlDeserializationWithDataSet.qhelp deleted file mode 100644 index bbc0a82f2f7e..000000000000 --- a/csharp/ql/src/experimental/Security Features/Serialization/XmlDeserializationWithDataSet.qhelp +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/csharp/ql/src/experimental/Security Features/Serialization/XmlDeserializationWithDataSet.ql b/csharp/ql/src/experimental/Security Features/Serialization/XmlDeserializationWithDataSet.ql deleted file mode 100644 index 8e820135af10..000000000000 --- a/csharp/ql/src/experimental/Security Features/Serialization/XmlDeserializationWithDataSet.ql +++ /dev/null @@ -1,19 +0,0 @@ -/** - * @name XML deserialization with a type type derived from DataSet or DataTable - * @description Making an XML deserialization call with a type derived from DataSet or DataTable types and may lead to a security problem. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details." - * @kind problem - * @problem.severity error - * @precision medium - * @id cs/dataset-serialization/xml-deserialization-with-dataset - * @tags security - * experimental - */ - -import csharp -deprecated import DataSetSerialization - -deprecated query predicate problems(UnsafeXmlReadMethodCall mc, string message) { - message = - "Making an XML deserialization call with a type derived from DataSet or DataTable types and may lead to a security problem. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details." and - exists(mc) -} diff --git a/csharp/ql/src/experimental/Security Features/backdoor/DangerousNativeFunctionCall.qhelp b/csharp/ql/src/experimental/Security Features/backdoor/DangerousNativeFunctionCall.qhelp deleted file mode 100644 index f499eebfdbf0..000000000000 --- a/csharp/ql/src/experimental/Security Features/backdoor/DangerousNativeFunctionCall.qhelp +++ /dev/null @@ -1,14 +0,0 @@ - - - -

    This query finds native calls to external functions that are often used in creating backdoors or are generally attributed to unsafe code practices. This is an example of a query that may be useful for detecting potential backdoors. Solorigate is one example that uses this mechanism.

    -
    - - -

    Any findings from this rule are only intended to indicate suspicious code that shares similarities with known portions of code used for the Solorigate attack. There is no certainty that the code is related or that the code is part of any attack.

    -

    For more information about Solorigate, please visit https://aka.ms/solorigate.

    -
    - -
    \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/backdoor/DangerousNativeFunctionCall.ql b/csharp/ql/src/experimental/Security Features/backdoor/DangerousNativeFunctionCall.ql deleted file mode 100644 index 347f3f507a37..000000000000 --- a/csharp/ql/src/experimental/Security Features/backdoor/DangerousNativeFunctionCall.ql +++ /dev/null @@ -1,55 +0,0 @@ -/** - * @name Potential dangerous use of native functions - * @description Detects the use of native functions that can be used for malicious intent or unsafe handling. - * @kind problem - * @problem.severity warning - * @precision low - * @id cs/backdoor/dangerous-native-functions - * @tags security - * experimental - * solorigate - */ - -import csharp -import semmle.code.csharp.frameworks.system.runtime.InteropServices - -predicate isDangerousMethod(Method m) { - m.getName() = "OpenProcessToken" or - m.getName() = "OpenThreadToken" or - m.getName() = "DuplicateToken" or - m.getName() = "DuplicateTokenEx" or - m.getName().matches("LogonUser%") or - m.getName().matches("WNetAddConnection%") or - m.getName() = "DeviceIoControl" or - m.getName().matches("LoadLibrary%") or - m.getName() = "GetProcAddress" or - m.getName().matches("CreateProcess%") or - m.getName().matches("InitiateSystemShutdown%") or - m.getName() = "GetCurrentProcess" or - m.getName() = "GetCurrentProcessToken" or - m.getName() = "GetCurrentThreadToken" or - m.getName() = "GetCurrentThreadEffectiveToken" or - m.getName() = "OpenThreadToken" or - m.getName() = "SetTokenInformation" or - m.getName().matches("LookupPrivilegeValue%") or - m.getName() = "AdjustTokenPrivileges" or - m.getName() = "SetProcessPrivilege" or - m.getName() = "ImpersonateLoggedOnUser" or - m.getName().matches("Add%Ace%") -} - -predicate isExternMethod(Method externMethod) { - externMethod.isExtern() - or - externMethod.getAnAttribute().getType() instanceof - SystemRuntimeInteropServicesDllImportAttributeClass - or - externMethod.getDeclaringType().getAnAttribute().getType() instanceof - SystemRuntimeInteropServicesComImportAttributeClass -} - -deprecated query predicate problems(MethodCall mc, string message) { - isExternMethod(mc.getTarget()) and - isDangerousMethod(mc.getTarget()) and - message = "Call to an external method '" + mc.getTarget().getName() + "'." -} diff --git a/csharp/ql/src/experimental/Security Features/backdoor/PotentialTimeBomb.qhelp b/csharp/ql/src/experimental/Security Features/backdoor/PotentialTimeBomb.qhelp deleted file mode 100644 index 57a8c5719fac..000000000000 --- a/csharp/ql/src/experimental/Security Features/backdoor/PotentialTimeBomb.qhelp +++ /dev/null @@ -1,14 +0,0 @@ - - - -

    This query detects situations in which an offset to a last file modification time is used to conditionally execute a particular block of code. This is a common pattern in backdoors, where the file's modification timestamp is the time at which the backdoor was planted, and the time offset is used as a time bomb before a particular code block is executed.

    -
    - - -

    Any findings from this rule are only intended to indicate suspicious code that shares similarities with known portions of code used for the Solorigate attack. There is no certainty that the code is related or that the code is part of any attack.

    -

    For more information about Solorigate, please visit https://aka.ms/solorigate.

    -
    - -
    \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/backdoor/PotentialTimeBomb.ql b/csharp/ql/src/experimental/Security Features/backdoor/PotentialTimeBomb.ql deleted file mode 100644 index 6a4eeb002b33..000000000000 --- a/csharp/ql/src/experimental/Security Features/backdoor/PotentialTimeBomb.ql +++ /dev/null @@ -1,189 +0,0 @@ -/** - * @name Potential Timebomb - * @description If there is data flow from a file's last modification date and an offset to a condition statement, this could trigger a "time bomb". - * @kind path-problem - * @precision Low - * @problem.severity warning - * @id cs/backdoor/potential-time-bomb - * @tags security - * experimental - * solorigate - */ - -import csharp -import Flow::PathGraph - -query predicate edges(Flow::PathNode a, Flow::PathNode b, string key, string val) { - Flow::PathGraph::edges(a, b, key, val) - or - FlowsFromGetLastWriteTimeConfigToTimeSpanArithmeticCallableConfig::isSink(a.getNode()) and - FlowsFromTimeSpanArithmeticToTimeComparisonCallableConfig::isSource(b.getNode()) and - key = "provenance" and - val = "" - or - FlowsFromTimeSpanArithmeticToTimeComparisonCallableConfig::isSink(a.getNode()) and - FlowsFromTimeComparisonCallableToSelectionStatementConditionConfig::isSource(b.getNode()) and - key = "provenance" and - val = "" -} - -/** - * Class that will help to find the source for the trigger file-modification date. - * - * May be extended as new patterns for similar time bombs are found. - */ -class GetLastWriteTimeMethod extends Method { - GetLastWriteTimeMethod() { - this.hasFullyQualifiedName("System.IO.File", - ["GetLastWriteTime", "GetFileCreationTime", "GetCreationTimeUtc", "GetLastAccessTimeUtc"]) - } -} - -/** - * Abstracts `System.DateTime` structure - */ -class DateTimeStruct extends Struct { - DateTimeStruct() { this.hasFullyQualifiedName("System", "DateTime") } - - /** - * holds if the Callable is used for DateTime arithmetic operations - */ - Callable getATimeSpanArithmeticCallable() { - (result = this.getAnOperator() or result = this.getAMethod()) and - result.getName() in [ - "Add", "AddDays", "AddHours", "AddMilliseconds", "AddMinutes", "AddMonths", "AddSeconds", - "AddTicks", "AddYears", "+", "-" - ] - } - - /** - * Holds if the Callable is used for DateTime comparison - */ - Callable getAComparisonCallable() { - (result = this.getAnOperator() or result = this.getAMethod()) and - result.getName() in ["Compare", "CompareTo", "Equals", "==", "!=", "<", ">", "<=", ">="] - } -} - -/** - * Configuration to find flow from a GetLastWriteTime source to a DateTime arithmetic operation - */ -private module FlowsFromGetLastWriteTimeConfigToTimeSpanArithmeticCallableConfig implements - DataFlow::ConfigSig -{ - predicate isSource(DataFlow::Node source) { - exists(Call call, GetLastWriteTimeMethod m | - m.getACall() = call and - source.asExpr() = call - ) - } - - predicate isSink(DataFlow::Node sink) { - exists(Call call, DateTimeStruct dateTime | - call.getAChild*() = sink.asExpr() and - call = dateTime.getATimeSpanArithmeticCallable().getACall() - ) - } -} - -/** - * Tainttracking module to find flow from a GetLastWriteTime source to a DateTime arithmetic operation - */ -private module FlowsFromGetLastWriteTimeConfigToTimeSpanArithmeticCallable = - TaintTracking::Global; - -/** - * Configuration to find flow from a DateTime arithmetic operation to a DateTime comparison operation - */ -private module FlowsFromTimeSpanArithmeticToTimeComparisonCallableConfig implements - DataFlow::ConfigSig -{ - predicate isSource(DataFlow::Node source) { - exists(DateTimeStruct dateTime, Call call | source.asExpr() = call | - call = dateTime.getATimeSpanArithmeticCallable().getACall() - ) - } - - predicate isSink(DataFlow::Node sink) { - exists(Call call, DateTimeStruct dateTime | - call.getAnArgument().getAChild*() = sink.asExpr() and - call = dateTime.getAComparisonCallable().getACall() - ) - } -} - -/** - * Tainttracking module to find flow from a DateTime arithmetic operation to a DateTime comparison operation - */ -private module FlowsFromTimeSpanArithmeticToTimeComparisonCallable = - TaintTracking::Global; - -/** - * Configuration to find flow from a DateTime comparison operation to a Selection Statement (such as an If) - */ -private module FlowsFromTimeComparisonCallableToSelectionStatementConditionConfig implements - DataFlow::ConfigSig -{ - predicate isSource(DataFlow::Node source) { - exists(DateTimeStruct dateTime, Call call | source.asExpr() = call | - call = dateTime.getAComparisonCallable().getACall() - ) - } - - predicate isSink(DataFlow::Node sink) { - exists(SelectionStmt sel | sel.getCondition().getAChild*() = sink.asExpr()) - } -} - -/** - * Tainttracking module to find flow from a DateTime comparison operation to a Selection Statement (such as an If) - */ -private module FlowsFromTimeComparisonCallableToSelectionStatementCondition = - TaintTracking::Global; - -private module Flow = - DataFlow::MergePathGraph3; - -/** - * Holds if the last file modification date from the call to getLastWriteTimeMethodCall will be used in a DateTime arithmetic operation timeArithmeticCall, - * which is then used for a DateTime comparison timeComparisonCall and the result flows to a Selection statement which is likely a TimeBomb trigger - */ -predicate isPotentialTimeBomb( - Flow::PathNode pathSource, Flow::PathNode pathSink, Call getLastWriteTimeMethodCall, - Call timeArithmeticCall, Call timeComparisonCall, SelectionStmt selStatement -) { - exists(DataFlow::Node sink, DateTimeStruct dateTime, DataFlow::Node sink2, DataFlow::Node sink3 | - pathSource.getNode() = DataFlow::exprNode(getLastWriteTimeMethodCall) and - FlowsFromGetLastWriteTimeConfigToTimeSpanArithmeticCallable::flow(DataFlow::exprNode(getLastWriteTimeMethodCall), - sink) and - timeArithmeticCall = dateTime.getATimeSpanArithmeticCallable().getACall() and - timeArithmeticCall.getAChild*() = sink.asExpr() and - FlowsFromTimeSpanArithmeticToTimeComparisonCallable::flow(DataFlow::exprNode(timeArithmeticCall), - sink2) and - timeComparisonCall = dateTime.getAComparisonCallable().getACall() and - timeComparisonCall.getAnArgument().getAChild*() = sink2.asExpr() and - FlowsFromTimeComparisonCallableToSelectionStatementCondition::flow(DataFlow::exprNode(timeComparisonCall), - sink3) and - selStatement.getCondition().getAChild*() = sink3.asExpr() and - pathSink.getNode() = sink3 - ) -} - -deprecated query predicate problems( - SelectionStmt selStatement, Flow::PathNode source, Flow::PathNode sink, string message, - Call timeComparisonCall, string timeComparisonCallString, Call timeArithmeticCall, string offset, - Call getLastWriteTimeMethodCall, string lastWriteTimeMethodCallMessage -) { - isPotentialTimeBomb(source, sink, getLastWriteTimeMethodCall, timeArithmeticCall, - timeComparisonCall, selStatement) and - message = - "Possible TimeBomb logic triggered by an $@ that takes into account $@ from the $@ as part of the potential trigger." and - timeComparisonCallString = timeComparisonCall.toString() and - offset = "offset" and - lastWriteTimeMethodCallMessage = "last modification time of a file" -} diff --git a/csharp/ql/src/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.qhelp b/csharp/ql/src/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.qhelp deleted file mode 100644 index cb1faf86974d..000000000000 --- a/csharp/ql/src/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.qhelp +++ /dev/null @@ -1,15 +0,0 @@ - - - -

    This query detects code flow from ProcessName property on the Process class into a hash function.

    -

    Such flow is often used in code backdoors to detect running processes and compare them to an obfuscated list of antivirus processes to avoid detection. Solorigate is one example that uses this mechanism.

    -
    - - -

    Any findings from this rule are only intended to indicate suspicious code that shares similarities with known portions of code used for the Solorigate attack. There is no certainty that the code is related or that the code is part of any attack.

    -

    For more information about Solorigate, please visit https://aka.ms/solorigate.

    -
    - -
    \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.ql b/csharp/ql/src/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.ql deleted file mode 100644 index c8b23f476fd2..000000000000 --- a/csharp/ql/src/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.ql +++ /dev/null @@ -1,56 +0,0 @@ -/** - * @name ProcessName to hash function flow - * @description Flow from a function retrieving process name to a hash function. - * @kind path-problem - * @tags security - * experimental - * solorigate - * @problem.severity warning - * @precision medium - * @id cs/backdoor/process-name-to-hash-function - */ - -import csharp -import experimental.code.csharp.Cryptography.NonCryptographicHashes -import DataFlowFromMethodToHash::PathGraph - -module DataFlowFromMethodToHashConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { isSuspiciousPropertyName(source.asExpr()) } - - predicate isSink(DataFlow::Node sink) { isGetHash(sink.asExpr()) } -} - -module DataFlowFromMethodToHash = TaintTracking::Global; - -predicate isGetHash(Expr arg) { - exists(MethodCall mc | - ( - mc.getTarget().getName().matches("%Hash%") or - mc.getTarget().getName().regexpMatch("Md[4-5]|Sha[1-9]{1,3}") - ) and - mc.getAnArgument() = arg - ) - or - exists(Callable callable, Parameter param, Call call | - isCallableAPotentialNonCryptographicHashFunction(callable, param) and - call = callable.getACall() and - arg = call.getArgumentForParameter(param) - ) -} - -predicate isSuspiciousPropertyName(PropertyRead pr) { - pr.getTarget().hasFullyQualifiedName("System.Diagnostics", "Process", "ProcessName") -} - -deprecated query predicate problems( - DataFlow::Node srcNode, DataFlowFromMethodToHash::PathNode src, - DataFlowFromMethodToHash::PathNode sink, string message, DataFlow::Node sinkNode, - string sinkMessage -) { - srcNode = src.getNode() and - sinkNode = sink.getNode() and - DataFlowFromMethodToHash::flow(srcNode, sinkNode) and - message = - "The hash is calculated on $@, may be related to a backdoor. Please review the code for possible malicious intent." and - sinkMessage = "this process name" -} diff --git a/csharp/ql/src/experimental/dataflow/flowsources/AuthCookie.qll b/csharp/ql/src/experimental/dataflow/flowsources/AuthCookie.qll deleted file mode 100644 index e91ae9de5385..000000000000 --- a/csharp/ql/src/experimental/dataflow/flowsources/AuthCookie.qll +++ /dev/null @@ -1,196 +0,0 @@ -/** - * Provides classes and predicates for detecting insecure cookies. - */ -deprecated module; - -import csharp -import semmle.code.csharp.frameworks.microsoft.AspNetCore - -/** - * Holds if the expression is a variable with a sensitive name. - */ -predicate isCookieWithSensitiveName(Expr cookieExpr) { - exists(DataFlow::Node sink | - AuthCookieName::flowTo(sink) and - sink.asExpr() = cookieExpr - ) -} - -/** - * Configuration for tracking if a variable with a sensitive name is used as an argument. - */ -private module AuthCookieNameConfig implements DataFlow::ConfigSig { - private predicate isAuthVariable(Expr expr) { - exists(string val | - ( - val = expr.getValue() or - val = expr.(Access).getTarget().getName() - ) and - val.regexpMatch("(?i).*(session|login|token|user|auth|credential).*") and - not val.regexpMatch("(?i).*(xsrf|csrf|forgery).*") - ) - } - - predicate isSource(DataFlow::Node source) { isAuthVariable(source.asExpr()) } - - predicate isSink(DataFlow::Node sink) { exists(Call c | sink.asExpr() = c.getAnArgument()) } -} - -/** - * Tracks if a variable with a sensitive name is used as an argument. - */ -private module AuthCookieName = DataFlow::Global; - -/** - * Configuration module tracking creation of `CookieOptions` to `IResponseCookies.Append(String, String, CookieOptions)` - * calls as a third parameter. - */ -private module CookieOptionsTrackingConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { - source.asExpr().(ObjectCreation).getType() instanceof MicrosoftAspNetCoreHttpCookieOptions - } - - predicate isSink(DataFlow::Node sink) { - exists(MicrosoftAspNetCoreHttpResponseCookies iResponse, MethodCall mc | - iResponse.getAppendMethod() = mc.getTarget() and - mc.getArgument(2) = sink.asExpr() - ) - } -} - -/** - * Tracking creation of `CookieOptions` to `IResponseCookies.Append(String, String, CookieOptions)` - * calls as a third parameter. - */ -module CookieOptionsTracking = DataFlow::Global; - -/** - * Looks for property value of `CookiePolicyOptions` passed to `app.UseCookiePolicy` in `Startup.Configure`. - */ -Expr getAValueForCookiePolicyProp(string prop) { - exists(Method m, MethodCall mc, ObjectCreation oc, Expr val | - m.getName() = "Configure" and - m.getDeclaringType().getName() = "Startup" and - m.getBody().getAChild+() = mc and - mc.getTarget() = - any(MicrosoftAspNetCoreBuilderCookiePolicyAppBuilderExtensions e).getUseCookiePolicyMethod() and - oc.getType() instanceof MicrosoftAspNetCoreBuilderCookiePolicyOptions and - getAValueForProp(oc, _, prop) = val and - result = val - ) -} - -/** - * A simplistic points-to alternative: given an object creation and a property name, get the values that property can be assigned. - * - * Assumptions: - * - we don't reassign the variable that the creation is stored in - * - we always access the creation through the same variable it is initially assigned to - * - * This should cover most typical patterns... - */ -Expr getAValueForProp(ObjectCreation create, Assignment a, string prop) { - // values set in object init - exists(MemberInitializer init, Expr src, PropertyAccess pa | - a.getLValue() = pa and - pa.getTarget().hasName(prop) and - init = create.getInitializer().(ObjectInitializer).getAMemberInitializer() and - init.getLValue() = pa and - DataFlow::localExprFlow(src, init.getRValue()) and - result = src - ) - or - // values set on var that create is assigned to - exists(Expr src, PropertyAccess pa | - a.getLValue() = pa and - pa.getTarget().hasName(prop) and - DataFlow::localExprFlow(create, pa.getQualifier()) and - DataFlow::localExprFlow(src, a.getRValue()) and - result = src - ) -} - -/** - * Checks if the given property was explicitly set to a value. - */ -predicate isPropertySet(ObjectCreation oc, string prop) { exists(getAValueForProp(oc, _, prop)) } - -private signature string propertyName(); - -/** - * Configuration for tracking if a callback used in `OnAppendCookie` sets a cookie property to `true`. - */ -private module OnAppendCookieTrackingConfig implements - DataFlow::ConfigSig -{ - /** - * Specifies the cookie property name to track. - */ - predicate isSource(DataFlow::Node source) { - exists(PropertyWrite pw, Assignment delegateAssign, Callable c | - pw.getProperty().getName() = "OnAppendCookie" and - pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreBuilderCookiePolicyOptions and - delegateAssign.getLValue() = pw and - ( - exists(LambdaExpr lambda | - delegateAssign.getRValue() = lambda and - lambda = c - ) - or - exists(DelegateCreation delegate | - delegateAssign.getRValue() = delegate and - delegate.getArgument().(CallableAccess).getTarget() = c - ) - ) and - c.getParameter(0) = source.asParameter() - ) - } - - predicate isSink(DataFlow::Node sink) { - exists(PropertyWrite pw, Assignment a | - pw.getProperty().getDeclaringType() instanceof MicrosoftAspNetCoreHttpCookieOptions and - pw.getProperty().getName() = getPropertyName() and - a.getLValue() = pw and - exists(Expr val | - DataFlow::localExprFlow(val, a.getRValue()) and - val.getValue() = "true" - ) and - sink.asExpr() = pw.getQualifier() - ) - } - - predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - node2.asExpr() = - any(PropertyRead pr | - pr.getQualifier() = node1.asExpr() and - pr.getProperty().getDeclaringType() instanceof - MicrosoftAspNetCoreCookiePolicyAppendCookieContext - ) - } -} - -private string getPropertyNameSecure() { result = "Secure" } - -/** - * Configuration module for tracking if a callback used in `OnAppendCookie` sets `Secure` to `true`. - */ -private module OnAppendCookieSecureTrackingConfig = - OnAppendCookieTrackingConfig; - -/** - * Tracks if a callback used in `OnAppendCookie` sets `Secure` to `true`. - */ -module OnAppendCookieSecureTracking = DataFlow::Global; - -private string getPropertyNameHttpOnly() { result = "HttpOnly" } - -/** - * Configuration module for tracking if a callback used in `OnAppendCookie` sets `HttpOnly` to `true`. - */ -private module OnAppendCookieHttpOnlyTrackingConfig = - OnAppendCookieTrackingConfig; - -/** - * Tracks if a callback used in `OnAppendCookie` sets `HttpOnly` to `true`. - */ -module OnAppendCookieHttpOnlyTracking = DataFlow::Global; diff --git a/csharp/ql/test/experimental/CWE-918/RequestForgery.cs b/csharp/ql/test/experimental/CWE-918/RequestForgery.cs deleted file mode 100644 index 02e851d8df10..000000000000 --- a/csharp/ql/test/experimental/CWE-918/RequestForgery.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Threading.Tasks; -using System.Web.Mvc; -using System.Net.Http; - -namespace RequestForgery.Controllers -{ - public class SSRFController : Controller - { - [HttpPost] - [ValidateAntiForgeryToken] - public async Task Bad(string url) - { - var request = new HttpRequestMessage(HttpMethod.Get, url); - - var client = new HttpClient(); - await client.SendAsync(request); - - return View(); - } - - [HttpPost] - [ValidateAntiForgeryToken] - public async Task Good(string url) - { - string baseUrl = "www.mysecuresite.com/"; - if (url.StartsWith(baseUrl)) - { - var request = new HttpRequestMessage(HttpMethod.Get, url); - var client = new HttpClient(); - await client.SendAsync(request); - - } - - return View(); - } - } -} diff --git a/csharp/ql/test/experimental/CWE-918/RequestForgery.expected b/csharp/ql/test/experimental/CWE-918/RequestForgery.expected deleted file mode 100644 index d0e8e0281f84..000000000000 --- a/csharp/ql/test/experimental/CWE-918/RequestForgery.expected +++ /dev/null @@ -1,8 +0,0 @@ -edges -| RequestForgery.cs:12:52:12:54 | url : String | RequestForgery.cs:14:66:14:68 | access to parameter url | provenance | | -nodes -| RequestForgery.cs:12:52:12:54 | url : String | semmle.label | url : String | -| RequestForgery.cs:14:66:14:68 | access to parameter url | semmle.label | access to parameter url | -subpaths -problems -| RequestForgery.cs:14:66:14:68 | access to parameter url | RequestForgery.cs:12:52:12:54 | url : String | RequestForgery.cs:14:66:14:68 | access to parameter url | The URL of this request depends on a $@. | RequestForgery.cs:12:52:12:54 | url | user-provided value | diff --git a/csharp/ql/test/experimental/CWE-918/RequestForgery.qlref b/csharp/ql/test/experimental/CWE-918/RequestForgery.qlref deleted file mode 100644 index 3d529ae5a2ca..000000000000 --- a/csharp/ql/test/experimental/CWE-918/RequestForgery.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/CWE-918/RequestForgery.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/CWE-918/options b/csharp/ql/test/experimental/CWE-918/options deleted file mode 100644 index 09b08bf4d270..000000000000 --- a/csharp/ql/test/experimental/CWE-918/options +++ /dev/null @@ -1,3 +0,0 @@ -semmle-extractor-options: /nostdlib /noconfig -semmle-extractor-options: --load-sources-from-project:${testdir}/../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj -semmle-extractor-options: ${testdir}/../../resources/stubs/System.Web.cs \ No newline at end of file diff --git a/csharp/ql/test/experimental/README.md b/csharp/ql/test/experimental/README.md deleted file mode 100644 index 2a9db304b9f7..000000000000 --- a/csharp/ql/test/experimental/README.md +++ /dev/null @@ -1 +0,0 @@ -This directory contains tests for [experimental](../../../../docs/experimental.md) CodeQL queries and libraries. diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/CookieBuilder/HttpOnly.expected b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/CookieBuilder/HttpOnly.expected deleted file mode 100644 index cf0986a446cd..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/CookieBuilder/HttpOnly.expected +++ /dev/null @@ -1,2 +0,0 @@ -| Program.cs:13:33:13:37 | false | Cookie attribute 'HttpOnly' is not set to true. | -| Program.cs:20:39:20:43 | false | Cookie attribute 'HttpOnly' is not set to true. | diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/CookieBuilder/HttpOnly.qlref b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/CookieBuilder/HttpOnly.qlref deleted file mode 100644 index 91ce226003c3..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/CookieBuilder/HttpOnly.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/CookieBuilder/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/CookieBuilder/Program.cs deleted file mode 100644 index 4f51bdb5bc5d..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/CookieBuilder/Program.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Authentication; - -public class Startup -{ - public void ConfigureServices(IServiceCollection services) - { - services.AddAuthentication().AddCookie(o => - { - o.Cookie.HttpOnly = false; - o.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.None; - }); - - services.AddSession(options => - { - options.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.None; - options.Cookie.HttpOnly = false; - }); - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/NoPolicy/HttpOnly.expected b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/NoPolicy/HttpOnly.expected deleted file mode 100644 index 968e28976a8a..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/NoPolicy/HttpOnly.expected +++ /dev/null @@ -1,4 +0,0 @@ -| Program.cs:25:34:25:38 | false | Cookie attribute 'HttpOnly' is not set to true. | -| Program.cs:38:88:38:92 | false | Cookie attribute 'HttpOnly' is not set to true. | -| Program.cs:61:34:61:34 | access to local variable v | Cookie attribute 'HttpOnly' is not set to true. | -| Program.cs:68:88:68:88 | access to local variable v | Cookie attribute 'HttpOnly' is not set to true. | diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/NoPolicy/HttpOnly.qlref b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/NoPolicy/HttpOnly.qlref deleted file mode 100644 index 91ce226003c3..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/NoPolicy/HttpOnly.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/NoPolicy/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/NoPolicy/Program.cs deleted file mode 100644 index 6f12958fba74..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/NoPolicy/Program.cs +++ /dev/null @@ -1,71 +0,0 @@ -public class MyController : Microsoft.AspNetCore.Mvc.Controller -{ - public void CookieDelete() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - Response.Cookies.Delete("auth", cookieOptions); // GOOD: Delete call - } - - void CookieDirectTrue() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - cookieOptions.HttpOnly = true; - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD - } - - void CookieDirectTrueInitializer() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { HttpOnly = true }; - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD - } - - void CookieDirectFalse() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - cookieOptions.HttpOnly = false; - Response.Cookies.Append("auth", "secret", cookieOptions); // BAD - } - - void CookieDirectFalseForgery() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - cookieOptions.HttpOnly = false; - Response.Cookies.Append("antiforgerytoken", "secret", cookieOptions); // GOOD: not an auth cookie - } - - void CookieDirectFalseInitializer() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { HttpOnly = false }; - Response.Cookies.Append("auth", "secret", cookieOptions); // BAD - } - - void CookieIntermediateTrue() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - bool v = true; - cookieOptions.HttpOnly = v; - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: should track local data flow - } - - void CookieIntermediateTrueInitializer() - { - bool v = true; - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { HttpOnly = v }; - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: should track local data flow - } - - void CookieIntermediateFalse() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - bool v = false; - cookieOptions.HttpOnly = v; - Response.Cookies.Append("auth", "secret", cookieOptions); // BAD - } - - void CookieIntermediateFalseInitializer() - { - bool v = false; - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { HttpOnly = v }; - Response.Cookies.Append("auth", "secret", cookieOptions); // BAD - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/UseCookiePolicyCallback/HttpOnly.expected b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/UseCookiePolicyCallback/HttpOnly.expected deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/UseCookiePolicyCallback/HttpOnly.qlref b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/UseCookiePolicyCallback/HttpOnly.qlref deleted file mode 100644 index 91ce226003c3..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/UseCookiePolicyCallback/HttpOnly.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/UseCookiePolicyCallback/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/UseCookiePolicyCallback/Program.cs deleted file mode 100644 index 60f217eff20e..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/UseCookiePolicyCallback/Program.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.AspNetCore.Http; - -public class MyController : Microsoft.AspNetCore.Mvc.Controller -{ - public void CookieDefault() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - cookieOptions.HttpOnly = false; - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: HttpOnly is set in callback - } -} - -public class Startup -{ - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - app.UseCookiePolicy(); - } - - public void ConfigureServices(IServiceCollection services) - { - services.Configure(options => - { - options.OnAppendCookie = cookieContext => SetCookies(cookieContext.CookieOptions); - }); - } - - private void SetCookies(CookieOptions options) - { - options.Secure = true; - options.HttpOnly = true; - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/options b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/options deleted file mode 100644 index ce3f295ed117..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseAspNetCore/options +++ /dev/null @@ -1,3 +0,0 @@ -semmle-extractor-options: /nostdlib /noconfig -semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj -semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.App.csproj diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseSystemWeb/HttpOnly.expected b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseSystemWeb/HttpOnly.expected deleted file mode 100644 index 288445958592..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseSystemWeb/HttpOnly.expected +++ /dev/null @@ -1,4 +0,0 @@ -| Program.cs:23:27:23:31 | false | Cookie attribute 'HttpOnly' is not set to true. | -| Program.cs:28:74:28:78 | false | Cookie attribute 'HttpOnly' is not set to true. | -| Program.cs:48:27:48:27 | access to local variable v | Cookie attribute 'HttpOnly' is not set to true. | -| Program.cs:54:74:54:74 | access to local variable v | Cookie attribute 'HttpOnly' is not set to true. | diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseSystemWeb/HttpOnly.qlref b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseSystemWeb/HttpOnly.qlref deleted file mode 100644 index 91ce226003c3..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseSystemWeb/HttpOnly.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseSystemWeb/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseSystemWeb/Program.cs deleted file mode 100644 index 6ab389f63cce..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseSystemWeb/Program.cs +++ /dev/null @@ -1,56 +0,0 @@ -class Program -{ - void CookieDirectTrue() - { - var cookie = new System.Web.HttpCookie("sessionID"); - cookie.HttpOnly = true; // GOOD - } - - void CookieDirectTrueInitializer() - { - var cookie = new System.Web.HttpCookie("sessionID") { HttpOnly = true }; // GOOD - } - - void CookieForgeryDirectFalse() - { - var cookie = new System.Web.HttpCookie("antiforgerytoken"); - cookie.HttpOnly = false; // GOOD: not an auth cookie - } - - void CookieDirectFalse() - { - var cookie = new System.Web.HttpCookie("sessionID"); - cookie.HttpOnly = false; // BAD - } - - void CookieDirectFalseInitializer() - { - var cookie = new System.Web.HttpCookie("sessionID") { HttpOnly = false }; // BAD - } - - void CookieIntermediateTrue() - { - var cookie = new System.Web.HttpCookie("sessionID"); - bool v = true; - cookie.HttpOnly = v; // GOOD: should track local data flow - } - - void CookieIntermediateTrueInitializer() - { - bool v = true; - var cookie = new System.Web.HttpCookie("sessionID") { HttpOnly = v }; // GOOD: should track local data flow - } - - void CookieIntermediateFalse() - { - var cookie = new System.Web.HttpCookie("sessionID"); - bool v = false; - cookie.HttpOnly = v; // BAD - } - - void CookieIntermediateFalseInitializer() - { - bool v = false; - var cookie = new System.Web.HttpCookie("sessionID") { HttpOnly = v }; // BAD - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseSystemWeb/Web.config b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseSystemWeb/Web.config deleted file mode 100644 index 96fd10c05b72..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseSystemWeb/Web.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseSystemWeb/options b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseSystemWeb/options deleted file mode 100644 index 9290f65d5b22..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieHttpOnlyFalseSystemWeb/options +++ /dev/null @@ -1,3 +0,0 @@ -semmle-extractor-options: /nostdlib /noconfig -semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj -semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/NoPolicy/HttpOnly.expected b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/NoPolicy/HttpOnly.expected deleted file mode 100644 index aac509883026..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/NoPolicy/HttpOnly.expected +++ /dev/null @@ -1,2 +0,0 @@ -| Program.cs:5:9:5:49 | call to method Append | Cookie attribute 'HttpOnly' is not set to true. | -| Program.cs:15:29:15:73 | object creation of type CookieOptions | Cookie attribute 'HttpOnly' is not set to true. | diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/NoPolicy/HttpOnly.qlref b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/NoPolicy/HttpOnly.qlref deleted file mode 100644 index 91ce226003c3..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/NoPolicy/HttpOnly.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/NoPolicy/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/NoPolicy/Program.cs deleted file mode 100644 index 945c5be55dbc..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/NoPolicy/Program.cs +++ /dev/null @@ -1,52 +0,0 @@ -public class MyController : Microsoft.AspNetCore.Mvc.Controller -{ - public void CookieDefault() - { - Response.Cookies.Append("auth", "secret"); // BAD: HttpOnly is set to false by default - } - - public void CookieDefaultForgery() - { - Response.Cookies.Append("antiforgerytoken", "secret"); // GOOD: not an auth cookie - } - - public void CookieDefault2() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - Response.Cookies.Append("auth", "secret", cookieOptions); // BAD: HttpOnly is set to false by default - } - - public void CookieDelete() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - Response.Cookies.Delete("auth", cookieOptions); // GOOD: Delete call - } - - void CookieDirectTrue() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - cookieOptions.HttpOnly = true; - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD - } - - void CookieDirectTrueInitializer() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { HttpOnly = true }; - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD - } - - void CookieIntermediateTrue() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - bool v = true; - cookieOptions.HttpOnly = v; - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: should track local data flow - } - - void CookieIntermediateTrueInitializer() - { - bool v = true; - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { HttpOnly = v }; - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: should track local data flow - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyAlways/HttpOnly.expected b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyAlways/HttpOnly.expected deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyAlways/HttpOnly.qlref b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyAlways/HttpOnly.qlref deleted file mode 100644 index 91ce226003c3..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyAlways/HttpOnly.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyAlways/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyAlways/Program.cs deleted file mode 100644 index 115f448a39b4..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyAlways/Program.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; - -public class MyController : Microsoft.AspNetCore.Mvc.Controller -{ - public void CookieDefault() - { - Response.Cookies.Append("auth", "secret"); // GOOD: HttpOnly is set in policy - } - - public void CookieDefault2() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: HttpOnly is set in policy - } -} - -public class Startup -{ - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - app.UseCookiePolicy(new CookiePolicyOptions() { HttpOnly = Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy.Always}); - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyCallback/HttpOnly.expected b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyCallback/HttpOnly.expected deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyCallback/HttpOnly.qlref b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyCallback/HttpOnly.qlref deleted file mode 100644 index 91ce226003c3..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyCallback/HttpOnly.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyCallback/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyCallback/Program.cs deleted file mode 100644 index 417b1f77277c..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyCallback/Program.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.AspNetCore.Http; - -public class MyController : Microsoft.AspNetCore.Mvc.Controller -{ - public void CookieDefault() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: HttpOnly is set in callback - } -} - -public class Startup -{ - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - app.UseCookiePolicy(); - } - - public void ConfigureServices(IServiceCollection services) - { - services.Configure(options => - { - options.OnAppendCookie = cookieContext => SetCookies(cookieContext.CookieOptions); - }); - } - - private void SetCookies(CookieOptions options) - { - options.Secure = true; - options.HttpOnly = true; - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyNone/HttpOnly.expected b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyNone/HttpOnly.expected deleted file mode 100644 index adfb1ab3efab..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyNone/HttpOnly.expected +++ /dev/null @@ -1,2 +0,0 @@ -| Program.cs:8:9:8:49 | call to method Append | Cookie attribute 'HttpOnly' is not set to true. | -| Program.cs:13:29:13:73 | object creation of type CookieOptions | Cookie attribute 'HttpOnly' is not set to true. | diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyNone/HttpOnly.qlref b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyNone/HttpOnly.qlref deleted file mode 100644 index 91ce226003c3..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyNone/HttpOnly.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyNone/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyNone/Program.cs deleted file mode 100644 index 7be845aadfea..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/UseCookiePolicyNone/Program.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; - -public class MyController : Microsoft.AspNetCore.Mvc.Controller -{ - public void CookieDefault() - { - Response.Cookies.Append("auth", "secret"); // Bad: HttpOnly policy set to None - } - - public void CookieDefault2() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - Response.Cookies.Append("auth", "secret", cookieOptions); // Bad: HttpOnly policy set to None - } -} - -public class Startup -{ - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - app.UseCookiePolicy(new CookiePolicyOptions() { HttpOnly = Microsoft.AspNetCore.CookiePolicy.HttpOnlyPolicy.None }); - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/options b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/options deleted file mode 100644 index ce3f295ed117..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlyAspNetCore/options +++ /dev/null @@ -1,3 +0,0 @@ -semmle-extractor-options: /nostdlib /noconfig -semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj -semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.App.csproj diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigEmpty/HttpOnly.expected b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigEmpty/HttpOnly.expected deleted file mode 100644 index 85b07c94e9e2..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigEmpty/HttpOnly.expected +++ /dev/null @@ -1 +0,0 @@ -| Program.cs:5:22:5:59 | object creation of type HttpCookie | Cookie attribute 'HttpOnly' is not set to true. | diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigEmpty/HttpOnly.qlref b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigEmpty/HttpOnly.qlref deleted file mode 100644 index 91ce226003c3..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigEmpty/HttpOnly.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigEmpty/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigEmpty/Program.cs deleted file mode 100644 index bc66b526fa51..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigEmpty/Program.cs +++ /dev/null @@ -1,36 +0,0 @@ -class Program -{ - void CookieDefault() - { - var cookie = new System.Web.HttpCookie("sessionID"); // BAD: httpOnlyCookies is set to false by default - } - - void CookieDefaultForgery() - { - var cookie = new System.Web.HttpCookie("anticsrftoken"); // GOOD: not an auth cookie - } - - void CookieDirectTrue() - { - var cookie = new System.Web.HttpCookie("sessionID"); - cookie.HttpOnly = true; // GOOD - } - - void CookieDirectTrueInitializer() - { - var cookie = new System.Web.HttpCookie("sessionID") { HttpOnly = true }; // GOOD - } - - void CookieIntermediateTrue() - { - var cookie = new System.Web.HttpCookie("sessionID"); - bool v = true; - cookie.HttpOnly = v; // GOOD: should track local data flow - } - - void CookieIntermediateTrueInitializer() - { - bool v = true; - var cookie = new System.Web.HttpCookie("sessionID") { HttpOnly = v }; // GOOD: should track local data flow - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigEmpty/Web.config b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigEmpty/Web.config deleted file mode 100644 index 96fd10c05b72..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigEmpty/Web.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigEmpty/options b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigEmpty/options deleted file mode 100644 index 9d05f9bf06d4..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigEmpty/options +++ /dev/null @@ -1,3 +0,0 @@ -semmle-extractor-options: /nostdlib /noconfig -semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj -semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigFalse/HttpOnly.expected b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigFalse/HttpOnly.expected deleted file mode 100644 index 85b07c94e9e2..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigFalse/HttpOnly.expected +++ /dev/null @@ -1 +0,0 @@ -| Program.cs:5:22:5:59 | object creation of type HttpCookie | Cookie attribute 'HttpOnly' is not set to true. | diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigFalse/HttpOnly.qlref b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigFalse/HttpOnly.qlref deleted file mode 100644 index 91ce226003c3..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigFalse/HttpOnly.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigFalse/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigFalse/Program.cs deleted file mode 100644 index 52ef13373f72..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigFalse/Program.cs +++ /dev/null @@ -1,36 +0,0 @@ -class Program -{ - void CookieDefault() - { - var cookie = new System.Web.HttpCookie("sessionID"); // BAD: httpOnlyCookies is set to false in config - } - - void CookieDefaultForgery() - { - var cookie = new System.Web.HttpCookie("anticsrftoken"); // GOOD: not an auth cookie - } - - void CookieDirectTrue() - { - var cookie = new System.Web.HttpCookie("sessionID"); - cookie.HttpOnly = true; // GOOD - } - - void CookieDirectTrueInitializer() - { - var cookie = new System.Web.HttpCookie("sessionID") { HttpOnly = true }; // GOOD - } - - void CookieIntermediateTrue() - { - var cookie = new System.Web.HttpCookie("sessionID"); - bool v = true; - cookie.HttpOnly = v; // GOOD: should track local data flow - } - - void CookieIntermediateTrueInitializer() - { - bool v = true; - var cookie = new System.Web.HttpCookie("sessionID") { HttpOnly = v }; // GOOD: should track local data flow - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigFalse/Web.config b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigFalse/Web.config deleted file mode 100644 index d6202a55188c..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigFalse/Web.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigFalse/options b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigFalse/options deleted file mode 100644 index 9d05f9bf06d4..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/ConfigFalse/options +++ /dev/null @@ -1,3 +0,0 @@ -semmle-extractor-options: /nostdlib /noconfig -semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj -semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/HttpCookiesTrue/HttpOnly.expected b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/HttpCookiesTrue/HttpOnly.expected deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/HttpCookiesTrue/HttpOnly.qlref b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/HttpCookiesTrue/HttpOnly.qlref deleted file mode 100644 index 91ce226003c3..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/HttpCookiesTrue/HttpOnly.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-1004/CookieWithoutHttpOnly.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/HttpCookiesTrue/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/HttpCookiesTrue/Program.cs deleted file mode 100644 index 6eeb4f6d3343..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/HttpCookiesTrue/Program.cs +++ /dev/null @@ -1,36 +0,0 @@ -class Program -{ - void CookieDefault() - { - var cookie = new System.Web.HttpCookie("sessionID"); // GOOD: httpOnlyCookies is set to true in config - } - - void CookieDefaultForgery() - { - var cookie = new System.Web.HttpCookie("anticsrftoken"); // GOOD: not an auth cookie - } - - void CookieDirectTrue() - { - var cookie = new System.Web.HttpCookie("sessionID"); - cookie.HttpOnly = true; // GOOD - } - - void CookieDirectTrueInitializer() - { - var cookie = new System.Web.HttpCookie("sessionID") { HttpOnly = true }; // GOOD - } - - void CookieIntermediateTrue() - { - var cookie = new System.Web.HttpCookie("sessionID"); - bool v = true; - cookie.HttpOnly = v; // GOOD: should track local data flow - } - - void CookieIntermediateTrueInitializer() - { - bool v = true; - var cookie = new System.Web.HttpCookie("sessionID") { HttpOnly = v }; // GOOD: should track local data flow - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/HttpCookiesTrue/Web.config b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/HttpCookiesTrue/Web.config deleted file mode 100644 index fc2621492116..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/HttpCookiesTrue/Web.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/HttpCookiesTrue/options b/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/HttpCookiesTrue/options deleted file mode 100644 index 9d05f9bf06d4..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-1004/CookieWithoutHttpOnlySystemWeb/HttpCookiesTrue/options +++ /dev/null @@ -1,3 +0,0 @@ -semmle-extractor-options: /nostdlib /noconfig -semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj -semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/NoPolicy/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/NoPolicy/Program.cs deleted file mode 100644 index 9c21416940b2..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/NoPolicy/Program.cs +++ /dev/null @@ -1,47 +0,0 @@ -public class MyController : Microsoft.AspNetCore.Mvc.Controller -{ - public void CookieDefault() - { - Response.Cookies.Append("name", "value"); // BAD: requireSSL is set to false by default - } - - public void CookieDefault2() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - Response.Cookies.Append("name", "value", cookieOptions); // BAD: requireSSL is set to false by default - } - - public void CookieDelete() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - Response.Cookies.Delete("name", cookieOptions); // GOOD: Delete call - } - - void CookieDirectTrue() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - cookieOptions.Secure = true; - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD - } - - void CookieDirectTrueInitializer() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { Secure = true }; - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD - } - - void CookieIntermediateTrue() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - bool v = true; - cookieOptions.Secure = v; - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: should track local data flow - } - - void CookieIntermediateTrueInitializer() - { - bool v = true; - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { Secure = v }; - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: should track local data flow - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/NoPolicy/RequireSSL.expected b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/NoPolicy/RequireSSL.expected deleted file mode 100644 index f96df31ad21a..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/NoPolicy/RequireSSL.expected +++ /dev/null @@ -1,2 +0,0 @@ -| Program.cs:5:9:5:48 | call to method Append | Cookie attribute 'Secure' is not set to true. | -| Program.cs:10:29:10:73 | object creation of type CookieOptions | Cookie attribute 'Secure' is not set to true. | diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/NoPolicy/RequireSSL.qlref b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/NoPolicy/RequireSSL.qlref deleted file mode 100644 index f76146a862b9..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/NoPolicy/RequireSSL.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-614/CookieWithoutSecure.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyAlways/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyAlways/Program.cs deleted file mode 100644 index 7c125f9265d2..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyAlways/Program.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; - -public class MyController : Microsoft.AspNetCore.Mvc.Controller -{ - public void CookieDefault() - { - Response.Cookies.Append("auth", "secret"); // GOOD: Secure is set in policy - } - - public void CookieDefault2() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: Secure is set in policy - } -} - -public class Startup -{ - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - app.UseCookiePolicy(new CookiePolicyOptions() { Secure = Microsoft.AspNetCore.Http.CookieSecurePolicy.Always }); - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyAlways/RequireSSL.expected b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyAlways/RequireSSL.expected deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyAlways/RequireSSL.qlref b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyAlways/RequireSSL.qlref deleted file mode 100644 index f76146a862b9..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyAlways/RequireSSL.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-614/CookieWithoutSecure.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyCallback/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyCallback/Program.cs deleted file mode 100644 index 85bd3bedd6db..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyCallback/Program.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.AspNetCore.Http; - -public class MyController : Microsoft.AspNetCore.Mvc.Controller -{ - public void CookieDefault() - { - Response.Cookies.Append("auth", "secret"); // GOOD: Secure is set in callback - } - - public void CookieDefault2() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: Secure is set in callback - } -} - -public class Startup -{ - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - app.UseCookiePolicy(); - } - - public void ConfigureServices(IServiceCollection services) - { - services.Configure(options => - { - options.OnAppendCookie = cookieContext => SetCookies(cookieContext.CookieOptions); - }); - } - - private void SetCookies(CookieOptions options) - { - options.Secure = true; - options.HttpOnly = true; - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyCallback/RequireSSL.expected b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyCallback/RequireSSL.expected deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyCallback/RequireSSL.qlref b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyCallback/RequireSSL.qlref deleted file mode 100644 index f76146a862b9..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyCallback/RequireSSL.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-614/CookieWithoutSecure.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyNone/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyNone/Program.cs deleted file mode 100644 index 9db1f5380d49..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyNone/Program.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; - -public class MyController : Microsoft.AspNetCore.Mvc.Controller -{ - public void CookieDefault() - { - Response.Cookies.Append("auth", "secret"); // Bad: Secure policy set to None - } - - public void CookieDefault2() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - Response.Cookies.Append("auth", "secret", cookieOptions); // Bad: Secure policy set to None - } -} - -public class Startup -{ - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - app.UseCookiePolicy(new CookiePolicyOptions() { Secure = Microsoft.AspNetCore.Http.CookieSecurePolicy.None }); - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyNone/RequireSSL.expected b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyNone/RequireSSL.expected deleted file mode 100644 index 030293f7b7ee..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyNone/RequireSSL.expected +++ /dev/null @@ -1,2 +0,0 @@ -| Program.cs:8:9:8:49 | call to method Append | Cookie attribute 'Secure' is not set to true. | -| Program.cs:13:29:13:73 | object creation of type CookieOptions | Cookie attribute 'Secure' is not set to true. | diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyNone/RequireSSL.qlref b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyNone/RequireSSL.qlref deleted file mode 100644 index f76146a862b9..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/UseCookiePolicyNone/RequireSSL.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-614/CookieWithoutSecure.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/options b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/options deleted file mode 100644 index ce3f295ed117..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLAspNetCore/options +++ /dev/null @@ -1,3 +0,0 @@ -semmle-extractor-options: /nostdlib /noconfig -semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj -semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.App.csproj diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/CookieBuilder/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/CookieBuilder/Program.cs deleted file mode 100644 index 4f51bdb5bc5d..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/CookieBuilder/Program.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Authentication; - -public class Startup -{ - public void ConfigureServices(IServiceCollection services) - { - services.AddAuthentication().AddCookie(o => - { - o.Cookie.HttpOnly = false; - o.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.None; - }); - - services.AddSession(options => - { - options.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.None; - options.Cookie.HttpOnly = false; - }); - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/CookieBuilder/RequireSSL.expected b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/CookieBuilder/RequireSSL.expected deleted file mode 100644 index fdddb5357bdb..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/CookieBuilder/RequireSSL.expected +++ /dev/null @@ -1,2 +0,0 @@ -| Program.cs:14:37:14:85 | access to constant None | Cookie attribute 'Secure' is not set to true. | -| Program.cs:19:43:19:91 | access to constant None | Cookie attribute 'Secure' is not set to true. | diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/CookieBuilder/RequireSSL.qlref b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/CookieBuilder/RequireSSL.qlref deleted file mode 100644 index f76146a862b9..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/CookieBuilder/RequireSSL.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-614/CookieWithoutSecure.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/NoPolicy/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/NoPolicy/Program.cs deleted file mode 100644 index b1ad1aede91e..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/NoPolicy/Program.cs +++ /dev/null @@ -1,64 +0,0 @@ -public class MyController : Microsoft.AspNetCore.Mvc.Controller -{ - public void CookieDelete() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - Response.Cookies.Delete("name", cookieOptions); // GOOD: Delete call - } - - void CookieDirectTrue() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - cookieOptions.Secure = true; - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD - } - - void CookieDirectTrueInitializer() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { Secure = true }; - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD - } - - void CookieDirectFalse() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - cookieOptions.Secure = false; - Response.Cookies.Append("auth", "secret", cookieOptions); // BAD - } - - void CookieDirectFalseInitializer() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { Secure = false }; - Response.Cookies.Append("auth", "secret", cookieOptions); // BAD - } - - void CookieIntermediateTrue() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - bool v = true; - cookieOptions.Secure = v; - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: should track local data flow - } - - void CookieIntermediateTrueInitializer() - { - bool v = true; - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { Secure = v }; - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: should track local data flow - } - - void CookieIntermediateFalse() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - bool v = false; - cookieOptions.Secure = v; - Response.Cookies.Append("auth", "secret", cookieOptions); // BAD - } - - void CookieIntermediateFalseInitializer() - { - bool v = false; - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions() { Secure = v }; - Response.Cookies.Append("auth", "secret", cookieOptions); // BAD - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/NoPolicy/RequireSSL.expected b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/NoPolicy/RequireSSL.expected deleted file mode 100644 index 7b7bc3439420..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/NoPolicy/RequireSSL.expected +++ /dev/null @@ -1,4 +0,0 @@ -| Program.cs:25:32:25:36 | false | Cookie attribute 'Secure' is not set to true. | -| Program.cs:31:86:31:90 | false | Cookie attribute 'Secure' is not set to true. | -| Program.cs:54:32:54:32 | access to local variable v | Cookie attribute 'Secure' is not set to true. | -| Program.cs:61:86:61:86 | access to local variable v | Cookie attribute 'Secure' is not set to true. | diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/NoPolicy/RequireSSL.qlref b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/NoPolicy/RequireSSL.qlref deleted file mode 100644 index f76146a862b9..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/NoPolicy/RequireSSL.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-614/CookieWithoutSecure.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/UseCookiePolicyCallback/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/UseCookiePolicyCallback/Program.cs deleted file mode 100644 index 542b1a298fa7..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/UseCookiePolicyCallback/Program.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.AspNetCore.Http; - -public class MyController : Microsoft.AspNetCore.Mvc.Controller -{ - public void CookieDefault() - { - var cookieOptions = new Microsoft.AspNetCore.Http.CookieOptions(); - cookieOptions.Secure = false; - Response.Cookies.Append("auth", "secret", cookieOptions); // GOOD: Secure is set in callback - } -} - -public class Startup -{ - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - app.UseCookiePolicy(); - } - - public void ConfigureServices(IServiceCollection services) - { - services.Configure(options => - { - options.OnAppendCookie = cookieContext => SetCookies(cookieContext.CookieOptions); - }); - } - - private void SetCookies(CookieOptions options) - { - options.Secure = true; - options.HttpOnly = true; - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/UseCookiePolicyCallback/RequireSSL.expected b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/UseCookiePolicyCallback/RequireSSL.expected deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/UseCookiePolicyCallback/RequireSSL.qlref b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/UseCookiePolicyCallback/RequireSSL.qlref deleted file mode 100644 index f76146a862b9..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/UseCookiePolicyCallback/RequireSSL.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-614/CookieWithoutSecure.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/options b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/options deleted file mode 100644 index ce3f295ed117..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseAspNetCore/options +++ /dev/null @@ -1,3 +0,0 @@ -semmle-extractor-options: /nostdlib /noconfig -semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj -semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.App.csproj diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseSystemWeb/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseSystemWeb/Program.cs deleted file mode 100644 index 3a6d80b50c9d..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseSystemWeb/Program.cs +++ /dev/null @@ -1,50 +0,0 @@ -class Program -{ - void CookieDirectTrue() - { - var cookie = new System.Web.HttpCookie("cookieName"); - cookie.Secure = true; // GOOD - } - - void CookieDirectTrueInitializer() - { - var cookie = new System.Web.HttpCookie("cookieName") { Secure = true }; // GOOD - } - - void CookieDirectFalse() - { - var cookie = new System.Web.HttpCookie("cookieName"); - cookie.Secure = false; // BAD - } - - void CookieDirectFalseInitializer() - { - var cookie = new System.Web.HttpCookie("cookieName") { Secure = false }; // BAD - } - - void CookieIntermediateTrue() - { - var cookie = new System.Web.HttpCookie("cookieName"); - bool v = true; - cookie.Secure = v; // GOOD: should track local data flow - } - - void CookieIntermediateTrueInitializer() - { - bool v = true; - var cookie = new System.Web.HttpCookie("cookieName") { Secure = v }; // GOOD: should track local data flow - } - - void CookieIntermediateFalse() - { - var cookie = new System.Web.HttpCookie("cookieName"); - bool v = false; - cookie.Secure = v; // BAD - } - - void CookieIntermediateFalseInitializer() - { - bool v = false; - var cookie = new System.Web.HttpCookie("cookieName") { Secure = v }; // BAD - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseSystemWeb/RequireSSL.expected b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseSystemWeb/RequireSSL.expected deleted file mode 100644 index fb6b5e842e29..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseSystemWeb/RequireSSL.expected +++ /dev/null @@ -1,4 +0,0 @@ -| Program.cs:17:25:17:29 | false | Cookie attribute 'Secure' is not set to true. | -| Program.cs:22:73:22:77 | false | Cookie attribute 'Secure' is not set to true. | -| Program.cs:42:25:42:25 | access to local variable v | Cookie attribute 'Secure' is not set to true. | -| Program.cs:48:73:48:73 | access to local variable v | Cookie attribute 'Secure' is not set to true. | diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseSystemWeb/RequireSSL.qlref b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseSystemWeb/RequireSSL.qlref deleted file mode 100644 index f76146a862b9..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseSystemWeb/RequireSSL.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-614/CookieWithoutSecure.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseSystemWeb/Web.config b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseSystemWeb/Web.config deleted file mode 100644 index 96fd10c05b72..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseSystemWeb/Web.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseSystemWeb/options b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseSystemWeb/options deleted file mode 100644 index 9290f65d5b22..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLFalseSystemWeb/options +++ /dev/null @@ -1,3 +0,0 @@ -semmle-extractor-options: /nostdlib /noconfig -semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj -semmle-extractor-options: ${testdir}/../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigEmpty/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigEmpty/Program.cs deleted file mode 100644 index 4011a7d1a63d..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigEmpty/Program.cs +++ /dev/null @@ -1,31 +0,0 @@ -class Program -{ - void CookieDefault() - { - var cookie = new System.Web.HttpCookie("cookieName"); // BAD: requireSSL is set to false by default - } - - void CookieDirectTrue() - { - var cookie = new System.Web.HttpCookie("cookieName"); - cookie.Secure = true; // GOOD - } - - void CookieDirectTrueInitializer() - { - var cookie = new System.Web.HttpCookie("cookieName") { Secure = true }; // GOOD - } - - void CookieIntermediateTrue() - { - var cookie = new System.Web.HttpCookie("cookieName"); - bool v = true; - cookie.Secure = v; // GOOD: should track local data flow - } - - void CookieIntermediateTrueInitializer() - { - bool v = true; - var cookie = new System.Web.HttpCookie("cookieName") { Secure = v }; // GOOD: should track local data flow - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigEmpty/RequireSSL.expected b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigEmpty/RequireSSL.expected deleted file mode 100644 index 6c224aab89dc..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigEmpty/RequireSSL.expected +++ /dev/null @@ -1 +0,0 @@ -| Program.cs:5:22:5:60 | object creation of type HttpCookie | Cookie attribute 'Secure' is not set to true. | diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigEmpty/RequireSSL.qlref b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigEmpty/RequireSSL.qlref deleted file mode 100644 index f76146a862b9..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigEmpty/RequireSSL.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-614/CookieWithoutSecure.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigEmpty/Web.config b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigEmpty/Web.config deleted file mode 100644 index 96fd10c05b72..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigEmpty/Web.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigEmpty/options b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigEmpty/options deleted file mode 100644 index 9d05f9bf06d4..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigEmpty/options +++ /dev/null @@ -1,3 +0,0 @@ -semmle-extractor-options: /nostdlib /noconfig -semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj -semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigFalse/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigFalse/Program.cs deleted file mode 100644 index 392366a72d27..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigFalse/Program.cs +++ /dev/null @@ -1,31 +0,0 @@ -class Program -{ - void CookieDefault() - { - var cookie = new System.Web.HttpCookie("cookieName"); // BAD: requireSSL is set to false in config - } - - void CookieDirectTrue() - { - var cookie = new System.Web.HttpCookie("cookieName"); - cookie.Secure = true; // GOOD - } - - void CookieDirectTrueInitializer() - { - var cookie = new System.Web.HttpCookie("cookieName") { Secure = true }; // GOOD - } - - void CookieIntermediateTrue() - { - var cookie = new System.Web.HttpCookie("cookieName"); - bool v = true; - cookie.Secure = v; // GOOD: should track local data flow - } - - void CookieIntermediateTrueInitializer() - { - bool v = true; - var cookie = new System.Web.HttpCookie("cookieName") { Secure = v }; // GOOD: should track local data flow - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigFalse/RequireSSL.expected b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigFalse/RequireSSL.expected deleted file mode 100644 index 6c224aab89dc..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigFalse/RequireSSL.expected +++ /dev/null @@ -1 +0,0 @@ -| Program.cs:5:22:5:60 | object creation of type HttpCookie | Cookie attribute 'Secure' is not set to true. | diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigFalse/RequireSSL.qlref b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigFalse/RequireSSL.qlref deleted file mode 100644 index f76146a862b9..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigFalse/RequireSSL.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-614/CookieWithoutSecure.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigFalse/Web.config b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigFalse/Web.config deleted file mode 100644 index ec7b88761ca4..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigFalse/Web.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigFalse/options b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigFalse/options deleted file mode 100644 index 9d05f9bf06d4..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/ConfigFalse/options +++ /dev/null @@ -1,3 +0,0 @@ -semmle-extractor-options: /nostdlib /noconfig -semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj -semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/FormsTrue/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/FormsTrue/Program.cs deleted file mode 100644 index be53a64ae6ed..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/FormsTrue/Program.cs +++ /dev/null @@ -1,31 +0,0 @@ -class Program -{ - void CookieDefault() - { - var cookie = new System.Web.HttpCookie("cookieName"); // GOOD: requireSSL is set to true in config - } - - void CookieDirectTrue() - { - var cookie = new System.Web.HttpCookie("cookieName"); - cookie.Secure = true; // GOOD - } - - void CookieDirectTrueInitializer() - { - var cookie = new System.Web.HttpCookie("cookieName") { Secure = true }; // GOOD - } - - void CookieIntermediateTrue() - { - var cookie = new System.Web.HttpCookie("cookieName"); - bool v = true; - cookie.Secure = v; // GOOD: should track local data flow - } - - void CookieIntermediateTrueInitializer() - { - bool v = true; - var cookie = new System.Web.HttpCookie("cookieName") { Secure = v }; // GOOD: should track local data flow - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/FormsTrue/RequireSSL.expected b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/FormsTrue/RequireSSL.expected deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/FormsTrue/RequireSSL.qlref b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/FormsTrue/RequireSSL.qlref deleted file mode 100644 index f76146a862b9..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/FormsTrue/RequireSSL.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-614/CookieWithoutSecure.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/FormsTrue/Web.config b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/FormsTrue/Web.config deleted file mode 100644 index c65c506b5122..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/FormsTrue/Web.config +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/FormsTrue/options b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/FormsTrue/options deleted file mode 100644 index 9d05f9bf06d4..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/FormsTrue/options +++ /dev/null @@ -1,3 +0,0 @@ -semmle-extractor-options: /nostdlib /noconfig -semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj -semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/HttpCookiesTrue/Program.cs b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/HttpCookiesTrue/Program.cs deleted file mode 100644 index be53a64ae6ed..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/HttpCookiesTrue/Program.cs +++ /dev/null @@ -1,31 +0,0 @@ -class Program -{ - void CookieDefault() - { - var cookie = new System.Web.HttpCookie("cookieName"); // GOOD: requireSSL is set to true in config - } - - void CookieDirectTrue() - { - var cookie = new System.Web.HttpCookie("cookieName"); - cookie.Secure = true; // GOOD - } - - void CookieDirectTrueInitializer() - { - var cookie = new System.Web.HttpCookie("cookieName") { Secure = true }; // GOOD - } - - void CookieIntermediateTrue() - { - var cookie = new System.Web.HttpCookie("cookieName"); - bool v = true; - cookie.Secure = v; // GOOD: should track local data flow - } - - void CookieIntermediateTrueInitializer() - { - bool v = true; - var cookie = new System.Web.HttpCookie("cookieName") { Secure = v }; // GOOD: should track local data flow - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/HttpCookiesTrue/RequireSSL.expected b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/HttpCookiesTrue/RequireSSL.expected deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/HttpCookiesTrue/RequireSSL.qlref b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/HttpCookiesTrue/RequireSSL.qlref deleted file mode 100644 index f76146a862b9..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/HttpCookiesTrue/RequireSSL.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/CWE-614/CookieWithoutSecure.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/HttpCookiesTrue/Web.config b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/HttpCookiesTrue/Web.config deleted file mode 100644 index 831693f09316..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/HttpCookiesTrue/Web.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/HttpCookiesTrue/options b/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/HttpCookiesTrue/options deleted file mode 100644 index 9d05f9bf06d4..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-614/RequireSSLSystemWeb/HttpCookiesTrue/options +++ /dev/null @@ -1,3 +0,0 @@ -semmle-extractor-options: /nostdlib /noconfig -semmle-extractor-options: --load-sources-from-project:${testdir}/../../../../../resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.NETCore.App.csproj -semmle-extractor-options: ${testdir}/../../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/experimental/Security Features/CWE-759/HashWithoutSalt.cs b/csharp/ql/test/experimental/Security Features/CWE-759/HashWithoutSalt.cs deleted file mode 100644 index 302936c0ea62..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-759/HashWithoutSalt.cs +++ /dev/null @@ -1,202 +0,0 @@ -// semmle-extractor-options: /r:System.Security.Cryptography.Primitives.dll /r:System.Security.Cryptography.Csp.dll /r:System.Security.Cryptography.Algorithms.dll - -using System; -using System.Text; -using System.Security.Cryptography; - -using Windows.Security.Cryptography; -using Windows.Security.Cryptography.Core; -using Windows.Storage.Streams; - -public class Test -{ - private const int SaltSize = 32; - - // BAD - Hash without a salt. - public static String HashPassword(string password, string strAlgName ="SHA256") - { - IBuffer passBuff = CryptographicBuffer.ConvertStringToBinary(password, BinaryStringEncoding.Utf8); - HashAlgorithmProvider algProvider = HashAlgorithmProvider.OpenAlgorithm(strAlgName); - IBuffer hashBuff = algProvider.HashData(passBuff); - return CryptographicBuffer.EncodeToBase64String(hashBuff); - } - - // GOOD - Hash with a salt. - public static string HashPassword2(string password, string salt, string strAlgName ="SHA256") - { - // Concatenate the salt with the password. - IBuffer passBuff = CryptographicBuffer.ConvertStringToBinary(password+salt, BinaryStringEncoding.Utf8); - HashAlgorithmProvider algProvider = HashAlgorithmProvider.OpenAlgorithm(strAlgName); - IBuffer hashBuff = algProvider.HashData(passBuff); - return CryptographicBuffer.EncodeToBase64String(hashBuff); - } - - // BAD - Hash without a salt. - public static string HashPassword(string password) - { - SHA256 sha256Hash = SHA256.Create(); - byte[] passBytes = System.Text.Encoding.ASCII.GetBytes(password); - byte[] hashBytes = sha256Hash.ComputeHash(passBytes); - return Convert.ToBase64String(hashBytes); - } - - // GOOD - Hash with a salt. - public static string HashPassword2(string password) - { - byte[] passBytes = System.Text.Encoding.ASCII.GetBytes(password); - byte[] saltBytes = GenerateSalt(); - - // Add the salt to the hash. - byte[] rawSalted = new byte[passBytes.Length + saltBytes.Length]; - passBytes.CopyTo(rawSalted, 0); - saltBytes.CopyTo(rawSalted, passBytes.Length); - - //Create the salted hash. - SHA256 sha256 = SHA256.Create(); - byte[] saltedPassBytes = sha256.ComputeHash(rawSalted); - - // Add the salt value to the salted hash. - byte[] dbPassword = new byte[saltedPassBytes.Length + saltBytes.Length]; - saltedPassBytes.CopyTo(dbPassword, 0); - saltBytes.CopyTo(dbPassword, saltedPassBytes.Length); - - return Convert.ToBase64String(dbPassword); - } - - // BAD - Hash without a salt. - public static string HashPassword3(string password) - { - HashAlgorithm hashAlg = new SHA256CryptoServiceProvider(); - byte[] passBytes = System.Text.Encoding.ASCII.GetBytes(password); - byte[] hashBytes = hashAlg.ComputeHash(passBytes); - return Convert.ToBase64String(hashBytes); - } - - // GOOD - Hash with a salt. - public bool VerifyPasswordHash(string password, byte[] passwordHash, byte[] passwordSalt) - { - using(var hmac = new System.Security.Cryptography.HMACSHA512(passwordSalt)) - { - var computedHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password)); - for(int i = 0;i throw null; - - public static string EncodeToBase64String(Windows.Storage.Streams.IBuffer buffer) => throw null; - } -} - -namespace Windows.Storage.Streams -{ - public interface IBuffer { - public uint Capacity { get; } - - public uint Length { get; set; } - } -} - -namespace Windows.Security.Cryptography.Core -{ - public sealed class CryptographicKey { } - - public sealed class SymmetricKeyAlgorithmProvider - { - public CryptographicKey CreateSymmetricKey(Windows.Storage.Streams.IBuffer keyMaterial) => throw null; - } - - public sealed class HashAlgorithmProvider { - public string AlgorithmName { get; } - - public uint HashLength { get; } - - public static HashAlgorithmProvider OpenAlgorithm(string algorithm) => throw null; - - public Windows.Storage.Streams.IBuffer HashData(Windows.Storage.Streams.IBuffer data) => throw null; - } -} diff --git a/csharp/ql/test/experimental/Security Features/CWE-759/options b/csharp/ql/test/experimental/Security Features/CWE-759/options deleted file mode 100644 index 2d27f665cab3..000000000000 --- a/csharp/ql/test/experimental/Security Features/CWE-759/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: /r:System.Security.Cryptography.dll \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected deleted file mode 100644 index a76e9660cec0..000000000000 --- a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.expected +++ /dev/null @@ -1,7 +0,0 @@ -| delegation-test.cs:101:63:101:186 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:54:34:54:50 | LifetimeValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.LifetimeValidator | -| delegation-test.cs:102:63:102:178 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | -| delegation-test.cs:115:63:115:190 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | -| delegation-test.cs:116:63:116:180 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | -| delegation-test.cs:117:63:117:217 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | -| delegation-test.cs:118:63:118:248 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | -| delegation-test.cs:119:63:119:177 | (...) => ... | JsonWebTokenHandler security-sensitive property $@ is being delegated to this callable that always returns "true". | stubs.cs:55:34:55:50 | AudienceValidator | Microsoft.IdentityModel.Tokens.TokenValidationParameters.AudienceValidator | diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.qlref b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.qlref deleted file mode 100644 index 527ea9259733..000000000000 --- a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/JsonWebTokenHandler/delegated-security-validations-always-return-true.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegation-test.cs b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegation-test.cs deleted file mode 100644 index 01af41c4b0c0..000000000000 --- a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/delegation-test.cs +++ /dev/null @@ -1,137 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.IdentityModel.Tokens; -using Microsoft.IdentityModel.JsonWebTokens; - -namespace JsonWebTokenHandlerTest -{ - public class JsonWebTokenHandler_00 - { - public static object ThrowIfNull(string name, object value) - { - if (value == null) - { - throw new System.ArgumentNullException(name); - } - return value; - } - - private static bool MayThrowException(SecurityToken token) - { - if (token.Id == null) - { - throw new Exception("foobar"); - } - return true; - } - - private static void DoesNotThrowException(SecurityToken token) - { - int x = 0; - } - - private static bool ValidateLifetime_FP01( - SecurityToken token, - TokenValidationParameters validationParameters) - { - if (token == null) - { - throw new System.ArgumentNullException("token"); - } - - MayThrowException(token); - - return true; - } - - private static bool ValidateLifetime_P01( - SecurityToken token, - TokenValidationParameters validationParameters) - { - if (token == null) - { - throw new System.ArgumentNullException("token"); - } - - DoesNotThrowException(token); - - return true; - } - - - internal static bool ValidateLifetimeAlwaysTrue( - SecurityToken token, - TokenValidationParameters validationParameters) - { - if (token is null) - { - return true; - } - return true; - } - - internal static bool ValidateLifetime( - string token, - TokenValidationParameters validationParameters) - { - if (token is null) - { - return false; - } - return true; - } - - public void TestCase01() - { - TokenValidationParameters tokenValidationParamsBaseline = new TokenValidationParameters - { - ClockSkew = TimeSpan.FromMinutes(5), - ValidateActor = true, - ValidateIssuerSigningKey = true, - ValidateIssuer = true, - ValidateAudience = true, - ValidateLifetime = true, - RequireExpirationTime = true, - ValidateTokenReplay = true, - RequireSignedTokens = true, - RequireAudience = true, - SaveSigninToken = true - }; - - tokenValidationParamsBaseline.LifetimeValidator = (notBefore, expires, securityToken, validationParameters) => ValidateLifetimeAlwaysTrue(securityToken, validationParameters); // BUG delegated-security-validations-always-return-true - tokenValidationParamsBaseline.AudienceValidator = (IEnumerable audiences, SecurityToken securityToken, TokenValidationParameters validationParameters) => true; // BUG delegated-security-validations-always-return-true - tokenValidationParamsBaseline.TokenReplayValidator = (DateTime? expirationTime, string securityToken, TokenValidationParameters validationParameters) => // GOOD - { - if (securityToken is null) - { - return false; - } - return true; - }; - - tokenValidationParamsBaseline.LifetimeValidator = (notBefore, expires, securityToken, validationParameters) => ValidateLifetime02(securityToken, validationParameters); // GOOD - tokenValidationParamsBaseline.AudienceValidator = (IEnumerable audiences, SecurityToken securityToken, TokenValidationParameters validationParameters) => {return securityToken is null?false:true; }; // GOOD - - tokenValidationParamsBaseline.AudienceValidator = (IEnumerable audiences, SecurityToken securityToken, TokenValidationParameters validationParameters) => { return true; }; // BUG - tokenValidationParamsBaseline.AudienceValidator = (IEnumerable audiences, SecurityToken securityToken, TokenValidationParameters validationParameters) => !false ; // BUG - tokenValidationParamsBaseline.AudienceValidator = (IEnumerable audiences, SecurityToken securityToken, TokenValidationParameters validationParameters) => { return securityToken is null?true:true; }; // BUG - tokenValidationParamsBaseline.AudienceValidator = (IEnumerable audiences, SecurityToken securityToken, TokenValidationParameters validationParameters) => { return ValidateLifetimeAlwaysTrue(securityToken, validationParameters);}; //BUG - tokenValidationParamsBaseline.AudienceValidator = (audiences, securityToken, validationParameters) => ValidateLifetimeAlwaysTrue(securityToken, validationParameters); //BUG - - } - - internal static bool ValidateLifetime02( - SecurityToken token, - TokenValidationParameters validationParameters) - { - return token is null?false:true; - } - - internal static bool ValidateLifetimeAlwaysTrue02( - SecurityToken token, - TokenValidationParameters validationParameters) - { - return !false; - } - } -} \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-test.cs b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-test.cs deleted file mode 100644 index 505aba41416f..000000000000 --- a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled-test.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.IdentityModel.Tokens; - -namespace JsonWebTokenHandlerTest -{ - public class JsonWebTokenHandler_class01 - { - public void TestCase01() - { - TokenValidationParameters tokenValidationParamsBaseline = new TokenValidationParameters - { - ClockSkew = TimeSpan.FromMinutes(5), - ValidateActor = true, - ValidateIssuerSigningKey = true, - ValidateIssuer = true, - ValidateAudience = true, - ValidateLifetime = true, - RequireExpirationTime = true, - ValidateTokenReplay = true, - RequireSignedTokens = true, - RequireAudience = true, - SaveSigninToken = true - }; - - TokenValidationParameters tokenValidationParams = new TokenValidationParameters - { - ClockSkew = TimeSpan.FromMinutes(5), - ValidateActor = false, - ValidateIssuerSigningKey = false, - ValidateIssuer = false, // BUG - ValidateAudience = false, // BUG - ValidateLifetime = false, // BUG - RequireExpirationTime = false, // BUG - ValidateTokenReplay = false, - RequireSignedTokens = false, - RequireAudience = false, // BUG - SaveSigninToken = false - }; - } - - } -} \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected deleted file mode 100644 index 4a0a5afce6fa..000000000000 --- a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.expected +++ /dev/null @@ -1,5 +0,0 @@ -| security-validation-disabled-test.cs:31:34:31:38 | false | The security sensitive property $@ is being disabled by the following value: $@. | stubs.cs:43:21:43:34 | ValidateIssuer | Microsoft.IdentityModel.Tokens.TokenValidationParameters.ValidateIssuer | security-validation-disabled-test.cs:31:34:31:38 | false | false | -| security-validation-disabled-test.cs:32:36:32:40 | false | The security sensitive property $@ is being disabled by the following value: $@. | stubs.cs:44:21:44:36 | ValidateAudience | Microsoft.IdentityModel.Tokens.TokenValidationParameters.ValidateAudience | security-validation-disabled-test.cs:32:36:32:40 | false | false | -| security-validation-disabled-test.cs:33:36:33:40 | false | The security sensitive property $@ is being disabled by the following value: $@. | stubs.cs:45:21:45:36 | ValidateLifetime | Microsoft.IdentityModel.Tokens.TokenValidationParameters.ValidateLifetime | security-validation-disabled-test.cs:33:36:33:40 | false | false | -| security-validation-disabled-test.cs:34:41:34:45 | false | The security sensitive property $@ is being disabled by the following value: $@. | stubs.cs:51:21:51:41 | RequireExpirationTime | Microsoft.IdentityModel.Tokens.TokenValidationParameters.RequireExpirationTime | security-validation-disabled-test.cs:34:41:34:45 | false | false | -| security-validation-disabled-test.cs:37:35:37:39 | false | The security sensitive property $@ is being disabled by the following value: $@. | stubs.cs:50:21:50:35 | RequireAudience | Microsoft.IdentityModel.Tokens.TokenValidationParameters.RequireAudience | security-validation-disabled-test.cs:37:35:37:39 | false | false | diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.qlref b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.qlref deleted file mode 100644 index ee07957fa06c..000000000000 --- a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/JsonWebTokenHandler/security-validation-disabled.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/stubs.cs b/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/stubs.cs deleted file mode 100644 index 1d0e0de00a36..000000000000 --- a/csharp/ql/test/experimental/Security Features/JsonWebTokenHandler/stubs.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Microsoft.IdentityModel -{ - -} - -namespace Microsoft.IdentityModel.Tokens -{ - public abstract class SecurityToken - { - protected SecurityToken() { } - public string Id { get; } - public string Issuer { get; } - public DateTime ValidFrom { get; } - public DateTime ValidTo { get; } - } - - public abstract class TokenHandler - { - public static readonly int DefaultTokenLifetimeInMinutes; - - protected TokenHandler() { } - - public virtual int MaximumTokenSizeInBytes { get; set; } - public bool SetDefaultTimesOnTokenCreation { get; set; } - public int TokenLifetimeInMinutes { get; set; } - } - - public delegate bool LifetimeValidator(DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValidationParameters validationParameters); - public delegate bool AudienceValidator(IEnumerable audiences, SecurityToken securityToken, TokenValidationParameters validationParameters); - public delegate bool TokenReplayValidator(DateTime? expirationTime, string securityToken, TokenValidationParameters validationParameters); - public delegate string IssuerValidator(string issuer, SecurityToken securityToken, TokenValidationParameters validationParameters); - - public class TokenValidationParameters - { - public const int DefaultMaximumTokenSizeInBytes = 256000; - public static readonly string DefaultAuthenticationType; - public static readonly TimeSpan DefaultClockSkew; - public TimeSpan ClockSkew { get; set; } - public bool SaveSigninToken { get; set; } - public bool ValidateIssuer { get; set; } - public bool ValidateAudience { get; set; } - public bool ValidateLifetime { get; set; } - public bool ValidateIssuerSigningKey { get; set; } - public bool ValidateTokenReplay { get; set; } - public bool ValidateActor { get; set; } - public bool RequireSignedTokens { get; set; } - public bool RequireAudience { get; set; } - public bool RequireExpirationTime { get; set; } - - // Delegation - public LifetimeValidator LifetimeValidator { get; set; } - public AudienceValidator AudienceValidator { get; set; } - public TokenReplayValidator TokenReplayValidator { get; set; } - public IssuerValidator IssuerValidator { get; set; } - - /* - public TokenValidationParameters() { } - public SignatureValidator SignatureValidator { get; set; } - public SecurityKey TokenDecryptionKey { get; set; } - public TokenDecryptionKeyResolver TokenDecryptionKeyResolver { get; set; } - public IEnumerable TokenDecryptionKeys { get; set; } - public TokenReader TokenReader { get; set; } - public ITokenReplayCache TokenReplayCache { get; set; } - public Func RoleClaimTypeRetriever { get; set; } - public string ValidAudience { get; set; } - public IEnumerable ValidAudiences { get; set; } - public string ValidIssuer { get; set; } - public IEnumerable ValidIssuers { get; set; } - public TokenValidationParameters ActorValidationParameters { get; set; } - public AudienceValidator AudienceValidator { get; set; } - public string AuthenticationType { get; set; } - public CryptoProviderFactory CryptoProviderFactory { get; set; } - public IssuerSigningKeyValidator IssuerSigningKeyValidator { get; set; } - public SecurityKey IssuerSigningKey { get; set; } - public IEnumerable IssuerSigningKeys { get; set; } - public IssuerValidator IssuerValidator { get; set; } - public string NameClaimType { get; set; } - public string RoleClaimType { get; set; } - public Func NameClaimTypeRetriever { get; set; } - public IDictionary PropertyBag { get; set; } - public IssuerSigningKeyResolver IssuerSigningKeyResolver { get; set; } - public IEnumerable ValidTypes { get; set; } - public virtual TokenValidationParameters Clone(); - public virtual string CreateClaimsIdentity(SecurityToken securityToken, string issuer); - */ - } - -} - -namespace Microsoft.IdentityModel.JsonWebTokens -{ - public class JsonWebTokenHandler : Microsoft.IdentityModel.Tokens.TokenHandler - { - public virtual TokenValidationResult ValidateToken(string token, Microsoft.IdentityModel.Tokens.TokenValidationParameters validationParameters) - { - return new TokenValidationResult() { IsValid = true, Exception = null, Issuer = "test" }; - } - } - - public class TokenValidationResult - { - public TokenValidationResult() { } - - public Exception Exception { get; set; } - public string Issuer { get; set; } - public bool IsValid { get; set; } - public Microsoft.IdentityModel.Tokens.SecurityToken SecurityToken { get; set; } - public string ClaimsIdentity { get; set; } - } - - -} diff --git a/csharp/ql/test/experimental/Security Features/Serialization/DefiningDatasetRelatedType.expected b/csharp/ql/test/experimental/Security Features/Serialization/DefiningDatasetRelatedType.expected deleted file mode 100644 index 923d680e3564..000000000000 --- a/csharp/ql/test/experimental/Security Features/Serialization/DefiningDatasetRelatedType.expected +++ /dev/null @@ -1,2 +0,0 @@ -| test0.cs:11:18:11:43 | DerivesFromDeprecatedType1 | Defining a class that inherits or has a property derived from the obsolete DataSet or DataTable types. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details. | -| test0.cs:57:18:57:38 | AttributeSerializer01 | Defining a class that inherits or has a property derived from the obsolete DataSet or DataTable types. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details. | diff --git a/csharp/ql/test/experimental/Security Features/Serialization/DefiningDatasetRelatedType.qlref b/csharp/ql/test/experimental/Security Features/Serialization/DefiningDatasetRelatedType.qlref deleted file mode 100644 index 7283db95daf5..000000000000 --- a/csharp/ql/test/experimental/Security Features/Serialization/DefiningDatasetRelatedType.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/Serialization/DefiningDatasetRelatedType.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/Serialization/DefiningPotentiallyUnsafeXmlSerializer.expected b/csharp/ql/test/experimental/Security Features/Serialization/DefiningPotentiallyUnsafeXmlSerializer.expected deleted file mode 100644 index 03518e4342b7..000000000000 --- a/csharp/ql/test/experimental/Security Features/Serialization/DefiningPotentiallyUnsafeXmlSerializer.expected +++ /dev/null @@ -1,2 +0,0 @@ -| test0.cs:13:24:13:32 | MyDataSet | Defining an serializable class $@ that has member $@ of a type that is derived from DataSet or DataTable types and may lead to a security problem. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details. | test0.cs:11:18:11:43 | DerivesFromDeprecatedType1 | DerivesFromDeprecatedType1 | test0.cs:13:24:13:32 | MyDataSet | MyDataSet | -| test0.cs:59:25:59:33 | MyDataSet | Defining an serializable class $@ that has member $@ of a type that is derived from DataSet or DataTable types and may lead to a security problem. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details. | test0.cs:57:18:57:38 | AttributeSerializer01 | AttributeSerializer01 | test0.cs:59:25:59:33 | MyDataSet | MyDataSet | diff --git a/csharp/ql/test/experimental/Security Features/Serialization/DefiningPotentiallyUnsafeXmlSerializer.qlref b/csharp/ql/test/experimental/Security Features/Serialization/DefiningPotentiallyUnsafeXmlSerializer.qlref deleted file mode 100644 index 8a8632c6ee3b..000000000000 --- a/csharp/ql/test/experimental/Security Features/Serialization/DefiningPotentiallyUnsafeXmlSerializer.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/Serialization/DefiningPotentiallyUnsafeXmlSerializer.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/Serialization/UnsafeTypeUsedDataContractSerializer.expected b/csharp/ql/test/experimental/Security Features/Serialization/UnsafeTypeUsedDataContractSerializer.expected deleted file mode 100644 index 421cae01530c..000000000000 --- a/csharp/ql/test/experimental/Security Features/Serialization/UnsafeTypeUsedDataContractSerializer.expected +++ /dev/null @@ -1,2 +0,0 @@ -| test0.cs:93:49:93:63 | typeof(...) | Unsafe type is used in data contract serializer. Make sure $@ comes from the trusted source. | test0.cs:93:49:93:63 | typeof(...) | typeof(...) | -| test0.cs:94:49:94:77 | typeof(...) | Unsafe type is used in data contract serializer. Make sure $@ comes from the trusted source. | test0.cs:94:49:94:77 | typeof(...) | typeof(...) | diff --git a/csharp/ql/test/experimental/Security Features/Serialization/UnsafeTypeUsedDataContractSerializer.qlref b/csharp/ql/test/experimental/Security Features/Serialization/UnsafeTypeUsedDataContractSerializer.qlref deleted file mode 100644 index 1593497c7932..000000000000 --- a/csharp/ql/test/experimental/Security Features/Serialization/UnsafeTypeUsedDataContractSerializer.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/Serialization/UnsafeTypeUsedDataContractSerializer.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/Serialization/XmlDeserializationWithDataSet.expected b/csharp/ql/test/experimental/Security Features/Serialization/XmlDeserializationWithDataSet.expected deleted file mode 100644 index be451487ad47..000000000000 --- a/csharp/ql/test/experimental/Security Features/Serialization/XmlDeserializationWithDataSet.expected +++ /dev/null @@ -1 +0,0 @@ -| test0.cs:86:17:86:46 | call to method ReadXmlSchema | Making an XML deserialization call with a type derived from DataSet or DataTable types and may lead to a security problem. Please visit https://go.microsoft.com/fwlink/?linkid=2132227 for details. | diff --git a/csharp/ql/test/experimental/Security Features/Serialization/XmlDeserializationWithDataSet.qlref b/csharp/ql/test/experimental/Security Features/Serialization/XmlDeserializationWithDataSet.qlref deleted file mode 100644 index 8054e46f929b..000000000000 --- a/csharp/ql/test/experimental/Security Features/Serialization/XmlDeserializationWithDataSet.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/Serialization/XmlDeserializationWithDataSet.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/Serialization/options b/csharp/ql/test/experimental/Security Features/Serialization/options deleted file mode 100644 index 670ea383c410..000000000000 --- a/csharp/ql/test/experimental/Security Features/Serialization/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: /r:System.Data.Common.dll /r:System.Xml.XmlSerializer.dll /r:System.Runtime.Serialization.Xml.dll /r:System.Runtime.Serialization.Xml.dll /r:System.Collections.dll /r:System.Private.Xml.dll /r:System.Private.DataContractSerialization.dll /r:System.Runtime.Extensions.dll /r:System.ComponentModel.TypeConverter.dll /r:System.Xml.ReaderWriter.dll /r:System.IO.FileSystem.dll diff --git a/csharp/ql/test/experimental/Security Features/Serialization/test0.cs b/csharp/ql/test/experimental/Security Features/Serialization/test0.cs deleted file mode 100644 index d2b2e772245a..000000000000 --- a/csharp/ql/test/experimental/Security Features/Serialization/test0.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Data; -using System.IO; -using System.Xml.Serialization; -using System.Runtime.Serialization; -using System.Xml; -using System.Collections.Generic; - -namespace DataSetSerializationTest -{ - public class DerivesFromDeprecatedType1 : XmlSerializer // warning:DefiningDatasetRelatedType.ql - { - public DataSet MyDataSet { get; set; } // bug:DefiningPotentiallyUnsafeXmlSerializer.ql - - public DerivesFromDeprecatedType1() - { - } - } - - /* - * TODO: I cannot use DataContract on a QL unit test - * - [DataContract(Name = "Customer", Namespace = "http://www.contoso.com")] - public class PatternDataContractSerializer : XmlObjectSerializer - { - [DataMember()] - public DataSet MyDataSet { get; set; } - [DataMember()] - public DataTable MyDataTable { get; set; } - - PatternDataContractSerializer() { } - private ExtensionDataObject extensionData_Value; - public ExtensionDataObject ExtensionData - { - get - { - return extensionData_Value; - } - set - { - extensionData_Value = value; - } - } - - public override void WriteObject(System.IO.Stream stream, object graph) { } - public override void WriteObjectContent(System.Xml.XmlDictionaryWriter writer, object graph) { } - public override bool IsStartObject(System.Xml.XmlDictionaryReader reader) { return false; } - public override void WriteStartObject(System.Xml.XmlDictionaryWriter writer, object graph) { } - public override void WriteEndObject(System.Xml.XmlWriter writer) { } - public override void WriteEndObject(XmlDictionaryWriter writer) { } - public override object ReadObject(System.IO.Stream stream) { return null; } - public override object ReadObject(XmlDictionaryReader reader, bool b) { return null; } - } - */ - - [Serializable()] - public class AttributeSerializer01 // warning:DefiningDatasetRelatedType.ql - { - private DataSet MyDataSet; // bug:DefiningPotentiallyUnsafeXmlSerializer.ql - - AttributeSerializer01() - { - } - } - - class Program - { - static string GetSerializedDataSet(DataSet dataSet) - { - DataTable dataTable = new DataTable("MyTable"); - dataTable.Columns.Add("FirstName", typeof(string)); - dataTable.Columns.Add("LastName", typeof(string)); - dataTable.Columns.Add("Age", typeof(int)); - - StringWriter writer = new StringWriter(); - dataSet.WriteXml(writer, XmlWriteMode.DiffGram); - return writer.ToString(); - } - - static void datatable_readxmlschema_01(string fileName) - { - using (FileStream fs = File.OpenRead(fileName)) - { - DataTable newTable = new DataTable(); - System.Xml.XmlTextReader reader = new System.Xml.XmlTextReader(fs); - newTable.ReadXmlSchema(reader); //bug:XmlDeserializationWithDataSet.ql - } - } - - static void Main(string[] args) - { - - XmlSerializer x = new XmlSerializer(typeof(DataSet)); // bug:UnsafeTypeUsedDataContractSerializer.ql - XmlSerializer y = new XmlSerializer(typeof(AttributeSerializer01)); //bug:UnsafeTypeUsedDataContractSerializer.ql - - Console.WriteLine("Hello World!"); - } - } -} diff --git a/csharp/ql/test/experimental/Security Features/backdoor/DangerousNativeFunctionCall.expected b/csharp/ql/test/experimental/Security Features/backdoor/DangerousNativeFunctionCall.expected deleted file mode 100644 index efbdcb3dd56b..000000000000 --- a/csharp/ql/test/experimental/Security Features/backdoor/DangerousNativeFunctionCall.expected +++ /dev/null @@ -1 +0,0 @@ -| test.cs:32:9:32:74 | call to method InitiateSystemShutdownExW | Call to an external method 'InitiateSystemShutdownExW'. | diff --git a/csharp/ql/test/experimental/Security Features/backdoor/DangerousNativeFunctionCall.qlref b/csharp/ql/test/experimental/Security Features/backdoor/DangerousNativeFunctionCall.qlref deleted file mode 100644 index 1215c001b40c..000000000000 --- a/csharp/ql/test/experimental/Security Features/backdoor/DangerousNativeFunctionCall.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/backdoor/DangerousNativeFunctionCall.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/backdoor/PotentialTimeBomb.expected b/csharp/ql/test/experimental/Security Features/backdoor/PotentialTimeBomb.expected deleted file mode 100644 index 95a491293ddb..000000000000 --- a/csharp/ql/test/experimental/Security Features/backdoor/PotentialTimeBomb.expected +++ /dev/null @@ -1,23 +0,0 @@ -nodes -| test.cs:69:18:69:30 | access to local variable lastWriteTime : DateTime | semmle.label | access to local variable lastWriteTime : DateTime | -| test.cs:69:34:69:76 | call to method GetLastWriteTime : DateTime | semmle.label | call to method GetLastWriteTime : DateTime | -| test.cs:71:13:71:71 | call to method CompareTo | semmle.label | call to method CompareTo | -| test.cs:71:13:71:71 | call to method CompareTo : Int32 | semmle.label | call to method CompareTo : Int32 | -| test.cs:71:13:71:76 | ... >= ... | semmle.label | ... >= ... | -| test.cs:71:36:71:48 | access to local variable lastWriteTime | semmle.label | access to local variable lastWriteTime | -| test.cs:71:36:71:70 | call to method AddHours | semmle.label | call to method AddHours | -subpaths -edges -| test.cs:69:18:69:30 | access to local variable lastWriteTime : DateTime | test.cs:71:36:71:48 | access to local variable lastWriteTime | provenance | | -| test.cs:69:34:69:76 | call to method GetLastWriteTime : DateTime | test.cs:69:18:69:30 | access to local variable lastWriteTime : DateTime | provenance | | -| test.cs:71:13:71:71 | call to method CompareTo : Int32 | test.cs:71:13:71:76 | ... >= ... | provenance | | -| test.cs:71:36:71:48 | access to local variable lastWriteTime | test.cs:71:13:71:71 | call to method CompareTo | provenance | | -| test.cs:71:36:71:48 | access to local variable lastWriteTime | test.cs:71:13:71:71 | call to method CompareTo : Int32 | provenance | | -| test.cs:71:36:71:48 | access to local variable lastWriteTime | test.cs:71:36:71:70 | call to method AddHours | provenance | | -| test.cs:71:36:71:70 | call to method AddHours | test.cs:71:13:71:71 | call to method CompareTo | provenance | | -| test.cs:71:36:71:70 | call to method AddHours | test.cs:71:13:71:71 | call to method CompareTo : Int32 | provenance | | -| test.cs:71:36:71:70 | call to method AddHours | test.cs:71:36:71:70 | call to method AddHours | provenance | | -problems -| test.cs:71:9:74:9 | if (...) ... | test.cs:69:34:69:76 | call to method GetLastWriteTime : DateTime | test.cs:71:13:71:71 | call to method CompareTo | Possible TimeBomb logic triggered by an $@ that takes into account $@ from the $@ as part of the potential trigger. | test.cs:71:13:71:71 | call to method CompareTo | call to method CompareTo | test.cs:71:36:71:70 | call to method AddHours | offset | test.cs:69:34:69:76 | call to method GetLastWriteTime | last modification time of a file | -| test.cs:71:9:74:9 | if (...) ... | test.cs:69:34:69:76 | call to method GetLastWriteTime : DateTime | test.cs:71:13:71:71 | call to method CompareTo : Int32 | Possible TimeBomb logic triggered by an $@ that takes into account $@ from the $@ as part of the potential trigger. | test.cs:71:13:71:71 | call to method CompareTo | call to method CompareTo | test.cs:71:36:71:70 | call to method AddHours | offset | test.cs:69:34:69:76 | call to method GetLastWriteTime | last modification time of a file | -| test.cs:71:9:74:9 | if (...) ... | test.cs:69:34:69:76 | call to method GetLastWriteTime : DateTime | test.cs:71:13:71:76 | ... >= ... | Possible TimeBomb logic triggered by an $@ that takes into account $@ from the $@ as part of the potential trigger. | test.cs:71:13:71:71 | call to method CompareTo | call to method CompareTo | test.cs:71:36:71:70 | call to method AddHours | offset | test.cs:69:34:69:76 | call to method GetLastWriteTime | last modification time of a file | diff --git a/csharp/ql/test/experimental/Security Features/backdoor/PotentialTimeBomb.qlref b/csharp/ql/test/experimental/Security Features/backdoor/PotentialTimeBomb.qlref deleted file mode 100644 index f76817aa089e..000000000000 --- a/csharp/ql/test/experimental/Security Features/backdoor/PotentialTimeBomb.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/backdoor/PotentialTimeBomb.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.expected b/csharp/ql/test/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.expected deleted file mode 100644 index b8074b4fa636..000000000000 --- a/csharp/ql/test/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.expected +++ /dev/null @@ -1,4 +0,0 @@ -edges -nodes -subpaths -problems diff --git a/csharp/ql/test/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.qlref b/csharp/ql/test/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.qlref deleted file mode 100644 index d1d0d520d61e..000000000000 --- a/csharp/ql/test/experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security Features/backdoor/ProcessNameToHashTaintFlow.ql \ No newline at end of file diff --git a/csharp/ql/test/experimental/Security Features/backdoor/test.cs b/csharp/ql/test/experimental/Security Features/backdoor/test.cs deleted file mode 100644 index 1aecc80aa83f..000000000000 --- a/csharp/ql/test/experimental/Security Features/backdoor/test.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Text; - -namespace System.IO -{ - public class File - { - public static DateTime GetLastWriteTime(string s) - { - return new DateTime(DateTime.MaxValue.Ticks); - } - } -} - -namespace System.Diagnostics -{ - public class Process - { - public static string GetCurrentProcess() { return "test"; } - } -} - -class External -{ - [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool InitiateSystemShutdownExW([In] string lpMachineName, [In] string lpMessage, [In] uint dwTimeout, [MarshalAs(UnmanagedType.Bool)][In] bool bForceAppsClosed, [MarshalAs(UnmanagedType.Bool)][In] bool bRebootAfterShutdown, [In] uint dwReason); - - void TestDangerousNativeFunctionCall() - { - InitiateSystemShutdownExW(null, null, 0U, true, true, 2147745794U); // BUG : DangerousNativeFunctionCall - } - - ulong GetFvnHash(string s) - { - ulong num = 14695981039346656037UL; /* FNV base offset */ - try - { - foreach (byte b in Encoding.UTF8.GetBytes(s)) - { - num ^= (ulong)b; - num *= 1099511628211UL; /* FNV prime */ - } - } - catch - { - } - // regular FVN - return num; - } - - void IndirectTestProcessNameToHashTaintFlow(string s) - { - GetFvnHash(s); // BUG : ProcessNameToHashTaintFlow - } - - void TestProcessNameToHashTaintFlow() - { - GetFvnHash(System.Diagnostics.Process.GetCurrentProcess()); // BUG : ProcessNameToHashTaintFlow - - string proc = System.Diagnostics.Process.GetCurrentProcess(); - - IndirectTestProcessNameToHashTaintFlow(proc); - } - - void TestTimeBomb() - { - DateTime lastWriteTime = System.IO.File.GetLastWriteTime("someFile"); - int num = new Random().Next(288, 336); - if (DateTime.Now.CompareTo(lastWriteTime.AddHours((double)num)) >= 0) // BUG : Potential time bomb, currently not detected - { - // Some code here - } - } - -} \ No newline at end of file