From e93f3186fec2c85fdcbcd8781d5d7f0ea0f21fbb Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 9 May 2023 17:36:31 +0100 Subject: [PATCH 001/118] Add missing function level access control query --- ...MissingFunctionLevelAccessControlQuery.qll | 60 +++++++++++++++++++ .../CWE-285/MissingAccessControl.ql | 18 ++++++ 2 files changed, 78 insertions(+) create mode 100644 csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll create mode 100644 csharp/ql/src/Security Features/CWE-285/MissingAccessControl.ql diff --git a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll new file mode 100644 index 00000000000..7cd0f4ef386 --- /dev/null +++ b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll @@ -0,0 +1,60 @@ +/** Definitions for the missing function level access control query */ + +import csharp +import semmle.code.csharp.frameworks.microsoft.AspNetCore +import semmle.code.csharp.frameworks.system.web.UI + +/** Holds if `m` is a method representing an action whose name indicates that it should have some authorization/authentication check. */ +predicate needsAuth(Method m) { + ( + m = any(MicrosoftAspNetCoreMvcController c).getAnActionMethod() + or + m.getDeclaringType().getBaseClass*() instanceof SystemWebUIPageClass and + m.getAParameter().getType().getName().matches("%EventArgs") + ) and + exists(string name | + name = + [ + m.getName(), m.getDeclaringType().getBaseClass*().getName(), + m.getDeclaringType().getFile().getRelativePath() + ] and + name.toLowerCase().regexpMatch(".*(edit|delete|modify|admin|superuser).*") + ) +} + +/** An expression that indicates that some authorization/authentication check is being performed. */ +class AuthExpr extends Expr { + AuthExpr() { + this.(MethodCall) + .getTarget() + .hasQualifiedName("System.Security.Principal", "IPrincipal", "IsInRole") + or + this.(PropertyAccess) + .getTarget() + .hasQualifiedName("System.Security.Principal", "IIdentity", ["IsAuthenticated", "Name"]) + or + this.(MethodCall).getTarget().getName().toLowerCase().matches("%auth%") + or + this.(PropertyAccess).getTarget().getName().toLowerCase().matches("%auth%") + } +} + +/** Holds if `m` is a method that should have an auth check, and does indeed have one. */ +predicate hasAuth(Method m) { + needsAuth(m) and + exists(Method om, Callable caller, AuthExpr auth | + om = m + or + om.getDeclaringType() = m.getDeclaringType() and + om.getName() = "Page_Load" + | + om.calls*(caller) and + auth.getEnclosingCallable() = caller + ) +} + +/** Holds if `m` is a method that should have an auth check, but is missing it. */ +predicate missingAuth(Method m) { + needsAuth(m) and + not hasAuth(m) +} diff --git a/csharp/ql/src/Security Features/CWE-285/MissingAccessControl.ql b/csharp/ql/src/Security Features/CWE-285/MissingAccessControl.ql new file mode 100644 index 00000000000..5eb62d6ca02 --- /dev/null +++ b/csharp/ql/src/Security Features/CWE-285/MissingAccessControl.ql @@ -0,0 +1,18 @@ +/** + * @name Missing function level access control + * @description ... TODO + * @kind problem + * @problem.severity warning + * @security-severity 7.5 + * @precision medium + * @id cs/web/missing-function-level-access-control + * @tags security + * external/cwe/cwe-285 + */ + +import csharp +import semmle.code.csharp.security.auth.MissingFunctionLevelAccessControlQuery + +from Method m +where missingAuth(m) +select m, "This action is missing an authorization check." From 29b5f14283c6d48c999b8fdf8549118ea244e2bd Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 16 May 2023 16:52:58 +0100 Subject: [PATCH 002/118] Add support for auth via xml using the physical path --- ...MissingFunctionLevelAccessControlQuery.qll | 104 +++++++++++++----- 1 file changed, 76 insertions(+), 28 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll index 7cd0f4ef386..c3fb53a38ee 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll @@ -3,23 +3,40 @@ import csharp import semmle.code.csharp.frameworks.microsoft.AspNetCore import semmle.code.csharp.frameworks.system.web.UI +import semmle.code.asp.WebConfig -/** Holds if `m` is a method representing an action whose name indicates that it should have some authorization/authentication check. */ -predicate needsAuth(Method m) { - ( - m = any(MicrosoftAspNetCoreMvcController c).getAnActionMethod() - or - m.getDeclaringType().getBaseClass*() instanceof SystemWebUIPageClass and - m.getAParameter().getType().getName().matches("%EventArgs") - ) and - exists(string name | - name = +abstract class ActionMethod extends Method { + string getADescription() { + result = [ - m.getName(), m.getDeclaringType().getBaseClass*().getName(), - m.getDeclaringType().getFile().getRelativePath() - ] and - name.toLowerCase().regexpMatch(".*(edit|delete|modify|admin|superuser).*") - ) + this.getName(), this.getDeclaringType().getBaseClass*().getName(), + this.getDeclaringType().getFile().getRelativePath() + ] + } + + predicate needsAuth() { + this.getADescription().toLowerCase().regexpMatch(".*(edit|delete|modify|admin|superuser).*") + } + + Callable getAnAuthorizingCallable() { result = this } +} + +private class MvcActionMethod extends ActionMethod { + MvcActionMethod() { this = any(MicrosoftAspNetCoreMvcController c).getAnActionMethod() } +} + +private class WebFormActionMethod extends ActionMethod { + WebFormActionMethod() { + this.getDeclaringType().getBaseClass*() instanceof SystemWebUIPageClass and + this.getAParameter().getType().getName().matches("%EventArgs") + } + + override Callable getAnAuthorizingCallable() { + result = this + or + result.getDeclaringType() = this.getDeclaringType() and + result.getName() = "Page_Load" + } } /** An expression that indicates that some authorization/authentication check is being performed. */ @@ -40,21 +57,52 @@ class AuthExpr extends Expr { } /** Holds if `m` is a method that should have an auth check, and does indeed have one. */ -predicate hasAuth(Method m) { - needsAuth(m) and - exists(Method om, Callable caller, AuthExpr auth | - om = m - or - om.getDeclaringType() = m.getDeclaringType() and - om.getName() = "Page_Load" - | - om.calls*(caller) and +predicate hasAuthViaCode(ActionMethod m) { + m.needsAuth() and + exists(Callable caller, AuthExpr auth | + m.getAnAuthorizingCallable().calls*(caller) and auth.getEnclosingCallable() = caller ) } -/** Holds if `m` is a method that should have an auth check, but is missing it. */ -predicate missingAuth(Method m) { - needsAuth(m) and - not hasAuth(m) +class AuthorizationXmlElement extends XmlElement { + AuthorizationXmlElement() { + this.getParent() instanceof SystemWebXmlElement and + this.getName().toLowerCase() = "authorization" + } + + predicate hasDenyElement() { this.getAChild().getName().toLowerCase() = "deny" } + + string getPhysicalPath() { result = this.getFile().getParentContainer().getRelativePath() } + + string getLocationTagPath() { + exists(LocationXmlElement loc, XmlAttribute path | + loc = this.getParent().(SystemWebXmlElement).getParent() and + path = loc.getAnAttribute() and + path.getName().toLowerCase() = "path" and + result = path.getValue() + ) + } +} + +/** + * Holds if the given action has an xml `authorization` tag that refers to it. + * TODO: Currently only supports physical paths, however virtual paths defined by `AddRoute` can also be used. + */ +predicate hasAuthViaXml(ActionMethod m) { + exists(AuthorizationXmlElement el, string path, string rest | + path = (el.getPhysicalPath() + "/" + el.getLocationTagPath()) + or + not exists(el.getLocationTagPath()) and + path = el.getPhysicalPath() + | + el.hasDenyElement() and + m.getDeclaringType().getFile().getRelativePath() = path + rest + ) +} + +/** Holds if `m` is a method that should have an auth check, but is missing it. */ +predicate missingAuth(ActionMethod m) { + m.needsAuth() and + not hasAuthViaCode(m) } From 63b3e16a545cb81bf5f9e89efa8e7ad7b5c93ab9 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 23 May 2023 14:23:01 +0100 Subject: [PATCH 003/118] Support Authorize attribute --- ...MissingFunctionLevelAccessControlQuery.qll | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll index c3fb53a38ee..766a1d1ec6d 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll @@ -19,10 +19,13 @@ abstract class ActionMethod extends Method { } Callable getAnAuthorizingCallable() { result = this } + + string getARoute() { result = this.getDeclaringType().getFile().getRelativePath() } } private class MvcActionMethod extends ActionMethod { MvcActionMethod() { this = any(MicrosoftAspNetCoreMvcController c).getAnActionMethod() } + // override string getARoute() { none() } } private class WebFormActionMethod extends ActionMethod { @@ -83,6 +86,15 @@ class AuthorizationXmlElement extends XmlElement { result = path.getValue() ) } + + string getARoute() { + result = this.getLocationTagPath() + or + result = this.getPhysicalPath() + "/" + this.getLocationTagPath() + or + not exists(this.getLocationTagPath()) and + result = this.getPhysicalPath() + } } /** @@ -90,19 +102,22 @@ class AuthorizationXmlElement extends XmlElement { * TODO: Currently only supports physical paths, however virtual paths defined by `AddRoute` can also be used. */ predicate hasAuthViaXml(ActionMethod m) { - exists(AuthorizationXmlElement el, string path, string rest | - path = (el.getPhysicalPath() + "/" + el.getLocationTagPath()) - or - not exists(el.getLocationTagPath()) and - path = el.getPhysicalPath() - | + exists(AuthorizationXmlElement el, string rest | el.hasDenyElement() and - m.getDeclaringType().getFile().getRelativePath() = path + rest + m.getARoute() = el.getARoute() + rest ) } +predicate hasAuthViaAttribute(ActionMethod m) { + [m.getAnAttribute(), m.getDeclaringType().getAnAttribute()] + .getType() + .hasQualifiedName("Microsoft.AspNetCore.Authorization", "AuthorizeAttribute") +} + /** Holds if `m` is a method that should have an auth check, but is missing it. */ predicate missingAuth(ActionMethod m) { m.needsAuth() and - not hasAuthViaCode(m) + not hasAuthViaCode(m) and + not hasAuthViaXml(m) and + not hasAuthViaAttribute(m) } From 582c4a7fbc564d63795f758ce78d66645ad789e6 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 23 May 2023 18:00:41 +0100 Subject: [PATCH 004/118] Support virtual route mappings for webforms actions --- ...MissingFunctionLevelAccessControlQuery.qll | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll index 766a1d1ec6d..083ab8029bf 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll @@ -15,7 +15,10 @@ abstract class ActionMethod extends Method { } predicate needsAuth() { - this.getADescription().toLowerCase().regexpMatch(".*(edit|delete|modify|admin|superuser).*") + this.getADescription() + .regexpReplaceAll("([a-z])([A-Z])", "$1_$2") + .toLowerCase() + .regexpMatch(".*(edit|delete|modify|admin|superuser).*") } Callable getAnAuthorizingCallable() { result = this } @@ -40,6 +43,38 @@ private class WebFormActionMethod extends ActionMethod { result.getDeclaringType() = this.getDeclaringType() and result.getName() = "Page_Load" } + + override string getARoute() { + exists(string physicalRoute | physicalRoute = super.getARoute() | + result = physicalRoute + or + exists(string absolutePhysical | + virtualRouteMapping(result, absolutePhysical) and + physicalRouteMatches(absolutePhysical, physicalRoute) + ) + ) + } +} + +private predicate virtualRouteMapping(string virtualRoute, string physicalRoute) { + exists(MethodCall mapPageRouteCall, StringLiteral virtualLit, StringLiteral physicalLit | + mapPageRouteCall + .getTarget() + .hasQualifiedName("System.Web.Routing", "RouteCollection", "MapPageRoute") and + virtualLit = mapPageRouteCall.getArgument(1) and + physicalLit = mapPageRouteCall.getArgument(2) and + virtualLit.getValue() = virtualRoute and + physicalLit.getValue() = physicalRoute + // physicalRouteMatches(physicalLit.getValue(), physicalRoute) + ) +} + +bindingset[route, actual] +private predicate physicalRouteMatches(string route, string actual) { + route = actual + or + route.charAt(0) = "~" and + exists(string dir | actual = dir + route.substring(1, route.length()) + ".cs") } /** An expression that indicates that some authorization/authentication check is being performed. */ From 57b3b2b2e326c26536e599d1974d85739617fb06 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 25 May 2023 17:26:55 +0100 Subject: [PATCH 005/118] Add qldoc + exclude empty methods --- ...MissingFunctionLevelAccessControlQuery.qll | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll index 083ab8029bf..fb2d34f03ee 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll @@ -5,7 +5,12 @@ import semmle.code.csharp.frameworks.microsoft.AspNetCore import semmle.code.csharp.frameworks.system.web.UI import semmle.code.asp.WebConfig +/** A method representing an action for a web endpoint. */ abstract class ActionMethod extends Method { + /** + * Gets a string that can indicate what this method does to determine if it should have an auth check; + * such as its method name, class name, or file path. + */ string getADescription() { result = [ @@ -14,23 +19,31 @@ abstract class ActionMethod extends Method { ] } + /** Holds if this method may need an authorization check. */ predicate needsAuth() { this.getADescription() .regexpReplaceAll("([a-z])([A-Z])", "$1_$2") + // separate camelCase words .toLowerCase() .regexpMatch(".*(edit|delete|modify|admin|superuser).*") } + /** Gets a callable for which if it contains an auth check, this method should be considered authenticated. */ Callable getAnAuthorizingCallable() { result = this } + /** + * Gets a possible url route that could refer to this action, + * which would be covered by `` configurations specifying a prefix of it. + */ string getARoute() { result = this.getDeclaringType().getFile().getRelativePath() } } +/** An action method in the MVC framework. */ private class MvcActionMethod extends ActionMethod { MvcActionMethod() { this = any(MicrosoftAspNetCoreMvcController c).getAnActionMethod() } - // override string getARoute() { none() } } +/** An action method on a subclass of `System.Web.UI.Page`. */ private class WebFormActionMethod extends ActionMethod { WebFormActionMethod() { this.getDeclaringType().getBaseClass*() instanceof SystemWebUIPageClass and @@ -56,6 +69,11 @@ private class WebFormActionMethod extends ActionMethod { } } +/** + * Holds if `virtualRoute` is a URL path + * that can map to the corresponding `physicalRoute` filepath + * through a call to `MapPageRoute` + */ private predicate virtualRouteMapping(string virtualRoute, string physicalRoute) { exists(MethodCall mapPageRouteCall, StringLiteral virtualLit, StringLiteral physicalLit | mapPageRouteCall @@ -69,6 +87,7 @@ private predicate virtualRouteMapping(string virtualRoute, string physicalRoute) ) } +/** Holds if the filepath `route` can refer to `actual` after expanding a '~". */ bindingset[route, actual] private predicate physicalRouteMatches(string route, string actual) { route = actual @@ -103,16 +122,20 @@ predicate hasAuthViaCode(ActionMethod m) { ) } +/** An `` XML element that */ class AuthorizationXmlElement extends XmlElement { AuthorizationXmlElement() { this.getParent() instanceof SystemWebXmlElement and this.getName().toLowerCase() = "authorization" } + /** Holds if this element has a `` element to deny access to a resource. */ predicate hasDenyElement() { this.getAChild().getName().toLowerCase() = "deny" } + /** Gets the physical filepath of this element. */ string getPhysicalPath() { result = this.getFile().getParentContainer().getRelativePath() } + /** Gets the path specified by a `` tag containing this element, if any. */ string getLocationTagPath() { exists(LocationXmlElement loc, XmlAttribute path | loc = this.getParent().(SystemWebXmlElement).getParent() and @@ -122,6 +145,7 @@ class AuthorizationXmlElement extends XmlElement { ) } + /** Gets a route prefix that this configuration can refer to. */ string getARoute() { result = this.getLocationTagPath() or @@ -134,7 +158,6 @@ class AuthorizationXmlElement extends XmlElement { /** * Holds if the given action has an xml `authorization` tag that refers to it. - * TODO: Currently only supports physical paths, however virtual paths defined by `AddRoute` can also be used. */ predicate hasAuthViaXml(ActionMethod m) { exists(AuthorizationXmlElement el, string rest | @@ -143,6 +166,7 @@ predicate hasAuthViaXml(ActionMethod m) { ) } +/** Holds if the given action has an `Authorize` attribute. */ predicate hasAuthViaAttribute(ActionMethod m) { [m.getAnAttribute(), m.getDeclaringType().getAnAttribute()] .getType() @@ -154,5 +178,6 @@ predicate missingAuth(ActionMethod m) { m.needsAuth() and not hasAuthViaCode(m) and not hasAuthViaXml(m) and - not hasAuthViaAttribute(m) + not hasAuthViaAttribute(m) and + exists(m.getBody().getAChildStmt()) // exclude empty methods } From 1b6e7f9140172aae276351feee947aa274ef4a3e Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 6 Jun 2023 13:35:49 +0100 Subject: [PATCH 006/118] Add unit tests for webform case with auth in code --- .../MissingAccessControl.expected | 2 ++ .../MissingAccessControl.qlref | 1 + .../Test1/EditProfile.aspx.cs | 18 +++++++++++++++ .../Test1/ViewProfile.aspx.cs | 23 +++++++++++++++++++ .../CWE-285/MissingAccessControl/options | 1 + 5 files changed, 45 insertions(+) create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MissingAccessControl.expected create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MissingAccessControl.qlref create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test1/EditProfile.aspx.cs create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test1/ViewProfile.aspx.cs create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/options diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MissingAccessControl.expected b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MissingAccessControl.expected new file mode 100644 index 00000000000..65c027df91c --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MissingAccessControl.expected @@ -0,0 +1,2 @@ +| Test1/EditProfile.aspx.cs:9:20:9:29 | btn1_Click | This action is missing an authorization check. | +| Test1/ViewProfile.aspx.cs:14:20:14:36 | btn_delete1_Click | This action is missing an authorization check. | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MissingAccessControl.qlref b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MissingAccessControl.qlref new file mode 100644 index 00000000000..a4173778d9f --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MissingAccessControl.qlref @@ -0,0 +1 @@ +Security Features/CWE-285/MissingAccessControl.ql diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test1/EditProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test1/EditProfile.aspx.cs new file mode 100644 index 00000000000..9ca2efe5bee --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test1/EditProfile.aspx.cs @@ -0,0 +1,18 @@ +using System; +using System.Web.UI; + +class EditProfile : System.Web.UI.Page { + private void doThings() { } + + private bool isAuthorized() { return false; } + + protected void btn1_Click(object sender, EventArgs e) { + doThings(); + } + + protected void btn2_Click(object sender, EventArgs e) { + if (isAuthorized()) { + doThings(); + } + } +} \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test1/ViewProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test1/ViewProfile.aspx.cs new file mode 100644 index 00000000000..9f561a6863c --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test1/ViewProfile.aspx.cs @@ -0,0 +1,23 @@ +using System; +using System.Web.UI; +using System.Web.Security; + +class ViewProfile : System.Web.UI.Page { + private void doThings() { } + + public System.Security.Principal.IPrincipal User { get; } // TODO: this should be in the stubs + + protected void btn_safe_Click(object sender, EventArgs e) { + doThings(); + } + + protected void btn_delete1_Click(object sender, EventArgs e) { + doThings(); + } + + protected void btn_delete2_Click(object sender, EventArgs e) { + if (User.IsInRole("admin")) { + doThings(); + } + } +} \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/options b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/options new file mode 100644 index 00000000000..24ff469252c --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/options @@ -0,0 +1 @@ +semmle-extractor-options: /r:System.Runtime.Extensions.dll /r:System.Collections.Specialized.dll ${testdir}/../../../../resources/stubs/System.Web.cs \ No newline at end of file From 1500089b864b6f8bd00b2abd060b70c1c085ab8c Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 8 Jun 2023 16:51:41 +0100 Subject: [PATCH 007/118] Add test cases for webforms auth via web.config files --- ...MissingFunctionLevelAccessControlQuery.qll | 2 +- .../MissingAccessControl.expected | 3 ++- .../Test1/ViewProfile.aspx.cs | 2 -- .../Test2/EditProfile.aspx.cs | 10 +++++++ .../MissingAccessControl/Test2/Web.config | 12 +++++++++ .../Test3/A/EditProfile.aspx.cs | 10 +++++++ .../Test3/B/EditProfile.aspx.cs | 10 +++++++ .../Test3/C/EditProfile.aspx.cs | 10 +++++++ .../MissingAccessControl/Test3/Global.asax.cs | 26 +++++++++++++++++++ .../MissingAccessControl/Test3/Web.config | 19 ++++++++++++++ csharp/ql/test/resources/stubs/System.Web.cs | 16 ++++++++++++ 11 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test2/EditProfile.aspx.cs create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test2/Web.config create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/A/EditProfile.aspx.cs create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/B/EditProfile.aspx.cs create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/C/EditProfile.aspx.cs create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/Global.asax.cs create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/Web.config diff --git a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll index fb2d34f03ee..35f75c59a28 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll @@ -122,7 +122,7 @@ predicate hasAuthViaCode(ActionMethod m) { ) } -/** An `` XML element that */ +/** An `` XML element. */ class AuthorizationXmlElement extends XmlElement { AuthorizationXmlElement() { this.getParent() instanceof SystemWebXmlElement and diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MissingAccessControl.expected b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MissingAccessControl.expected index 65c027df91c..ccac820134b 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MissingAccessControl.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MissingAccessControl.expected @@ -1,2 +1,3 @@ | Test1/EditProfile.aspx.cs:9:20:9:29 | btn1_Click | This action is missing an authorization check. | -| Test1/ViewProfile.aspx.cs:14:20:14:36 | btn_delete1_Click | This action is missing an authorization check. | +| Test1/ViewProfile.aspx.cs:12:20:12:36 | btn_delete1_Click | This action is missing an authorization check. | +| Test3/B/EditProfile.aspx.cs:7:20:7:29 | btn1_Click | This action is missing an authorization check. | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test1/ViewProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test1/ViewProfile.aspx.cs index 9f561a6863c..fc04d551eec 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test1/ViewProfile.aspx.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test1/ViewProfile.aspx.cs @@ -5,8 +5,6 @@ using System.Web.Security; class ViewProfile : System.Web.UI.Page { private void doThings() { } - public System.Security.Principal.IPrincipal User { get; } // TODO: this should be in the stubs - protected void btn_safe_Click(object sender, EventArgs e) { doThings(); } diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test2/EditProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test2/EditProfile.aspx.cs new file mode 100644 index 00000000000..f14c39078cd --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test2/EditProfile.aspx.cs @@ -0,0 +1,10 @@ +using System; +using System.Web.UI; + +class EditProfile2 : System.Web.UI.Page { + private void doThings() { } + + protected void btn1_Click(object sender, EventArgs e) { + doThings(); + } +} \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test2/Web.config b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test2/Web.config new file mode 100644 index 00000000000..5810b0a0593 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test2/Web.config @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/A/EditProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/A/EditProfile.aspx.cs new file mode 100644 index 00000000000..6f66d66e653 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/A/EditProfile.aspx.cs @@ -0,0 +1,10 @@ +using System; +using System.Web.UI; + +class EditProfile3 : System.Web.UI.Page { + private void doThings() { } + + protected void btn1_Click(object sender, EventArgs e) { + doThings(); + } +} \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/B/EditProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/B/EditProfile.aspx.cs new file mode 100644 index 00000000000..3e1e189d06e --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/B/EditProfile.aspx.cs @@ -0,0 +1,10 @@ +using System; +using System.Web.UI; + +class EditProfile4 : System.Web.UI.Page { + private void doThings() { } + + protected void btn1_Click(object sender, EventArgs e) { + doThings(); + } +} \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/C/EditProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/C/EditProfile.aspx.cs new file mode 100644 index 00000000000..81d2a1f0d8b --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/C/EditProfile.aspx.cs @@ -0,0 +1,10 @@ +using System; +using System.Web.UI; + +class EditProfile5 : System.Web.UI.Page { + private void doThings() { } + + protected void btn1_Click(object sender, EventArgs e) { + doThings(); + } +} \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/Global.asax.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/Global.asax.cs new file mode 100644 index 00000000000..f1bb5aadd8b --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/Global.asax.cs @@ -0,0 +1,26 @@ +using System; +using System.Web; +using System.Web.Routing; + +public class Global : System.Web.HttpApplication { + + void Application_Start(object sender, EventArgs e) { + RegisterRoutes(RouteTable.Routes); + } + + void Application_End(object sender, EventArgs e) { } + + void Application_Error(object sender, EventArgs e) { } + + void Session_Start(object sender, EventArgs e) { } + + void Session_End(object sender, EventArgs e) { } + + static void RegisterRoutes(RouteCollection routes) { + routes.MapPageRoute("VirtualEditProfile", + "Virtual/Edit", + "~/C/EditProfile.aspx", + false + ); + } +} \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/Web.config b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/Web.config new file mode 100644 index 00000000000..fd9409f3042 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/Web.config @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/csharp/ql/test/resources/stubs/System.Web.cs b/csharp/ql/test/resources/stubs/System.Web.cs index 725b672fbe8..a8d3a6ff2bc 100644 --- a/csharp/ql/test/resources/stubs/System.Web.cs +++ b/csharp/ql/test/resources/stubs/System.Web.cs @@ -48,6 +48,8 @@ namespace System.Web public class HttpApplication : IHttpHandler { public HttpServerUtility Server { get; } + + public Routing.RouteTable RouteTable { get; } } } @@ -79,6 +81,7 @@ namespace System.Web.UI public class Page { + public System.Security.Principal.IPrincipal User { get; } } interface IPostBackDataHandler @@ -300,6 +303,19 @@ namespace System.Web.Routing public class RequestContext { } + + public class Route + { + } + + public class RouteTable { + public RouteCollection Routes { get; } + } + + public class RouteCollection + { + public Route MapPageRoute(string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess) { return null; } + } } namespace System.Web.Security From 7eea191005ad2a72b6f3f8eec55fdfc5b233a48d Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 12 Jun 2023 18:36:44 +0100 Subject: [PATCH 008/118] Add tests for MVC cases --- .../MVCTests/MissingAccessControl.expected | 1 + .../{ => MVCTests}/MissingAccessControl.qlref | 0 .../MVCTests/ProfileController.cs | 19 +++++++++++++++++++ .../MissingAccessControl/MVCTests/options | 3 +++ .../MissingAccessControl.expected | 0 .../WebFormsTests/MissingAccessControl.qlref | 1 + .../Test1/EditProfile.aspx.cs | 0 .../Test1/ViewProfile.aspx.cs | 0 .../Test2/EditProfile.aspx.cs | 0 .../{ => WebFormsTests}/Test2/Web.config | 0 .../Test3/A/EditProfile.aspx.cs | 0 .../Test3/B/EditProfile.aspx.cs | 0 .../Test3/C/EditProfile.aspx.cs | 0 .../{ => WebFormsTests}/Test3/Global.asax.cs | 0 .../{ => WebFormsTests}/Test3/Web.config | 0 .../WebFormsTests/options | 1 + .../CWE-285/MissingAccessControl/options | 1 - .../Minimal/MinimalStubsFromSource.expected | 2 +- 18 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/MissingAccessControl.expected rename csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/{ => MVCTests}/MissingAccessControl.qlref (100%) create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/ProfileController.cs create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/options rename csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/{ => WebFormsTests}/MissingAccessControl.expected (100%) create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/MissingAccessControl.qlref rename csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/{ => WebFormsTests}/Test1/EditProfile.aspx.cs (100%) rename csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/{ => WebFormsTests}/Test1/ViewProfile.aspx.cs (100%) rename csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/{ => WebFormsTests}/Test2/EditProfile.aspx.cs (100%) rename csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/{ => WebFormsTests}/Test2/Web.config (100%) rename csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/{ => WebFormsTests}/Test3/A/EditProfile.aspx.cs (100%) rename csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/{ => WebFormsTests}/Test3/B/EditProfile.aspx.cs (100%) rename csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/{ => WebFormsTests}/Test3/C/EditProfile.aspx.cs (100%) rename csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/{ => WebFormsTests}/Test3/Global.asax.cs (100%) rename csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/{ => WebFormsTests}/Test3/Web.config (100%) create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/options delete mode 100644 csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/options diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/MissingAccessControl.expected b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/MissingAccessControl.expected new file mode 100644 index 00000000000..f6d983c8f77 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/MissingAccessControl.expected @@ -0,0 +1 @@ +| ProfileController.cs:7:25:7:31 | Delete1 | This action is missing an authorization check. | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MissingAccessControl.qlref b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/MissingAccessControl.qlref similarity index 100% rename from csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MissingAccessControl.qlref rename to csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/MissingAccessControl.qlref diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/ProfileController.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/ProfileController.cs new file mode 100644 index 00000000000..7ecd6323b97 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/ProfileController.cs @@ -0,0 +1,19 @@ +using Microsoft.AspNetCore.Mvc; + +public class ProfileController : Controller { + private void doThings() { } + private bool isAuthorized() { return false; } + + public ActionResult Delete1(int id) { + doThings(); + return View(); + } + + public ActionResult Delete2(int id) { + if (!isAuthorized()) { + return null; + } + doThings(); + return View(); + } +} \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/options b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/options new file mode 100644 index 00000000000..19bb87e63b5 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/options @@ -0,0 +1,3 @@ +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 \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MissingAccessControl.expected b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/MissingAccessControl.expected similarity index 100% rename from csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MissingAccessControl.expected rename to csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/MissingAccessControl.expected diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/MissingAccessControl.qlref b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/MissingAccessControl.qlref new file mode 100644 index 00000000000..a4173778d9f --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/MissingAccessControl.qlref @@ -0,0 +1 @@ +Security Features/CWE-285/MissingAccessControl.ql diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test1/EditProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test1/EditProfile.aspx.cs similarity index 100% rename from csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test1/EditProfile.aspx.cs rename to csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test1/EditProfile.aspx.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test1/ViewProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test1/ViewProfile.aspx.cs similarity index 100% rename from csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test1/ViewProfile.aspx.cs rename to csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test1/ViewProfile.aspx.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test2/EditProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test2/EditProfile.aspx.cs similarity index 100% rename from csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test2/EditProfile.aspx.cs rename to csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test2/EditProfile.aspx.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test2/Web.config b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test2/Web.config similarity index 100% rename from csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test2/Web.config rename to csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test2/Web.config diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/A/EditProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/A/EditProfile.aspx.cs similarity index 100% rename from csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/A/EditProfile.aspx.cs rename to csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/A/EditProfile.aspx.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/B/EditProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/B/EditProfile.aspx.cs similarity index 100% rename from csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/B/EditProfile.aspx.cs rename to csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/B/EditProfile.aspx.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/C/EditProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/C/EditProfile.aspx.cs similarity index 100% rename from csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/C/EditProfile.aspx.cs rename to csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/C/EditProfile.aspx.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/Global.asax.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/Global.asax.cs similarity index 100% rename from csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/Global.asax.cs rename to csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/Global.asax.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/Web.config b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/Web.config similarity index 100% rename from csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/Test3/Web.config rename to csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/Web.config diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/options b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/options new file mode 100644 index 00000000000..3c76fe5dc58 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/options @@ -0,0 +1 @@ +semmle-extractor-options: /r:System.Runtime.Extensions.dll /r:System.Collections.Specialized.dll ${testdir}/../../../../../resources/stubs/System.Web.cs \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/options b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/options deleted file mode 100644 index 24ff469252c..00000000000 --- a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: /r:System.Runtime.Extensions.dll /r:System.Collections.Specialized.dll ${testdir}/../../../../resources/stubs/System.Web.cs \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Stubs/Minimal/MinimalStubsFromSource.expected b/csharp/ql/test/query-tests/Stubs/Minimal/MinimalStubsFromSource.expected index 629addbb336..dc42176a7cb 100644 --- a/csharp/ql/test/query-tests/Stubs/Minimal/MinimalStubsFromSource.expected +++ b/csharp/ql/test/query-tests/Stubs/Minimal/MinimalStubsFromSource.expected @@ -1 +1 @@ -| // This file contains auto-generated code.\n// Generated from `System.Collections, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Collections\n{\nnamespace Generic\n{\npublic class Stack : System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.ICollection, System.Collections.IEnumerable\n{\n void System.Collections.ICollection.CopyTo(System.Array array, int arrayIndex) => throw null;\n public int Count { get => throw null; }\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n public T Peek() => throw null;\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Collections.NonGeneric, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Collections\n{\npublic class SortedList : System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable, System.ICloneable\n{\n public virtual void Add(object key, object value) => throw null;\n public virtual void Clear() => throw null;\n public virtual object Clone() => throw null;\n public virtual bool Contains(object key) => throw null;\n public virtual void CopyTo(System.Array array, int arrayIndex) => throw null;\n public virtual int Count { get => throw null; }\n public virtual object GetByIndex(int index) => throw null;\n public virtual System.Collections.IDictionaryEnumerator GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public virtual bool IsFixedSize { get => throw null; }\n public virtual bool IsReadOnly { get => throw null; }\n public virtual bool IsSynchronized { get => throw null; }\n public virtual object this[object key] { get => throw null; set => throw null; }\n public virtual System.Collections.ICollection Keys { get => throw null; }\n public virtual void Remove(object key) => throw null;\n public virtual object SyncRoot { get => throw null; }\n public virtual System.Collections.ICollection Values { get => throw null; }\n}\n\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Collections.Specialized, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Collections\n{\nnamespace Specialized\n{\npublic abstract class NameObjectCollectionBase : System.Collections.ICollection, System.Collections.IEnumerable, System.Runtime.Serialization.IDeserializationCallback, System.Runtime.Serialization.ISerializable\n{\n void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;\n public virtual int Count { get => throw null; }\n public virtual System.Collections.IEnumerator GetEnumerator() => throw null;\n public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) => throw null;\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n public virtual void OnDeserialization(object sender) => throw null;\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n}\n\npublic class NameValueCollection : System.Collections.Specialized.NameObjectCollectionBase\n{\n public string this[string name] { get => throw null; set => throw null; }\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.ComponentModel.TypeConverter, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace ComponentModel\n{\npublic class ComponentConverter : System.ComponentModel.ReferenceConverter\n{\n}\n\npublic class DefaultEventAttribute : System.Attribute\n{\n public DefaultEventAttribute(string name) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\npublic class DefaultPropertyAttribute : System.Attribute\n{\n public DefaultPropertyAttribute(string name) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\npublic class ReferenceConverter : System.ComponentModel.TypeConverter\n{\n}\n\npublic class TypeConverter\n{\n}\n\n}\nnamespace Timers\n{\npublic class TimersDescriptionAttribute\n{\n public TimersDescriptionAttribute(string description) => throw null;\n internal TimersDescriptionAttribute(string description, string unused) => throw null;\n}\n\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Linq, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Linq\n{\npublic static class Enumerable\n{\n public static System.Collections.Generic.IEnumerable Select(this System.Collections.Generic.IEnumerable source, System.Func selector) => throw null;\n}\n\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Linq.Expressions, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Linq\n{\npublic interface IQueryable : System.Collections.IEnumerable\n{\n}\n\n}\nnamespace Runtime\n{\nnamespace CompilerServices\n{\npublic class CallSite\n{\n internal CallSite(System.Runtime.CompilerServices.CallSiteBinder binder) => throw null;\n}\n\npublic class CallSite : System.Runtime.CompilerServices.CallSite where T: class\n{\n private CallSite() : base(default(System.Runtime.CompilerServices.CallSiteBinder)) => throw null;\n private CallSite(System.Runtime.CompilerServices.CallSiteBinder binder) : base(default(System.Runtime.CompilerServices.CallSiteBinder)) => throw null;\n}\n\npublic abstract class CallSiteBinder\n{\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Linq.Parallel, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Linq\n{\npublic static class ParallelEnumerable\n{\n public static System.Linq.ParallelQuery AsParallel(this System.Collections.IEnumerable source) => throw null;\n}\n\npublic class ParallelQuery : System.Collections.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n internal ParallelQuery(System.Linq.Parallel.QuerySettings specifiedSettings) => throw null;\n}\n\nnamespace Parallel\n{\ninternal struct QuerySettings\n{\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Linq.Queryable, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Linq\n{\npublic static class Queryable\n{\n public static System.Linq.IQueryable AsQueryable(this System.Collections.IEnumerable source) => throw null;\n}\n\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.ObjectModel, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace ComponentModel\n{\npublic class TypeConverterAttribute : System.Attribute\n{\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n public TypeConverterAttribute() => throw null;\n public TypeConverterAttribute(System.Type type) => throw null;\n public TypeConverterAttribute(string typeName) => throw null;\n}\n\npublic class TypeDescriptionProviderAttribute : System.Attribute\n{\n public TypeDescriptionProviderAttribute(System.Type type) => throw null;\n public TypeDescriptionProviderAttribute(string typeName) => throw null;\n}\n\n}\nnamespace Windows\n{\nnamespace Markup\n{\npublic class ValueSerializerAttribute : System.Attribute\n{\n public ValueSerializerAttribute(System.Type valueSerializerType) => throw null;\n public ValueSerializerAttribute(string valueSerializerTypeName) => throw null;\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Private.Uri, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\npublic class Uri : System.Runtime.Serialization.ISerializable\n{\n public override bool Equals(object comparand) => throw null;\n public override int GetHashCode() => throw null;\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) => throw null;\n public override string ToString() => throw null;\n}\n\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Runtime.Serialization.Primitives, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Runtime\n{\nnamespace Serialization\n{\npublic class DataContractAttribute : System.Attribute\n{\n public DataContractAttribute() => throw null;\n}\n\npublic class DataMemberAttribute : System.Attribute\n{\n public DataMemberAttribute() => throw null;\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Text.RegularExpressions, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Text\n{\nnamespace RegularExpressions\n{\npublic class Capture\n{\n internal Capture(string text, int index, int length) => throw null;\n public override string ToString() => throw null;\n}\n\npublic class GeneratedRegexAttribute : System.Attribute\n{\n public GeneratedRegexAttribute(string pattern) => throw null;\n public GeneratedRegexAttribute(string pattern, System.Text.RegularExpressions.RegexOptions options) => throw null;\n public GeneratedRegexAttribute(string pattern, System.Text.RegularExpressions.RegexOptions options, int matchTimeoutMilliseconds) => throw null;\n public GeneratedRegexAttribute(string pattern, System.Text.RegularExpressions.RegexOptions options, int matchTimeoutMilliseconds, string cultureName) => throw null;\n public GeneratedRegexAttribute(string pattern, System.Text.RegularExpressions.RegexOptions options, string cultureName) => throw null;\n}\n\npublic class Group : System.Text.RegularExpressions.Capture\n{\n internal Group(string text, int[] caps, int capcount, string name) : base(default(string), default(int), default(int)) => throw null;\n}\n\npublic class Match : System.Text.RegularExpressions.Group\n{\n internal Match(System.Text.RegularExpressions.Regex regex, int capcount, string text, int textLength) : base(default(string), default(int[]), default(int), default(string)) => throw null;\n}\n\npublic class Regex : System.Runtime.Serialization.ISerializable\n{\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo si, System.Runtime.Serialization.StreamingContext context) => throw null;\n public System.Text.RegularExpressions.Match Match(string input) => throw null;\n public static System.Text.RegularExpressions.Match Match(string input, string pattern) => throw null;\n public static System.Text.RegularExpressions.Match Match(string input, string pattern, System.Text.RegularExpressions.RegexOptions options, System.TimeSpan matchTimeout) => throw null;\n public Regex(string pattern) => throw null;\n public Regex(string pattern, System.Text.RegularExpressions.RegexOptions options, System.TimeSpan matchTimeout) => throw null;\n public string Replace(string input, string replacement) => throw null;\n public override string ToString() => throw null;\n}\n\n[System.Flags]\npublic enum RegexOptions : int\n{\n IgnoreCase = 1,\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Web, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null`.\n\nnamespace System\n{\nnamespace Web\n{\npublic class HtmlString : System.Web.IHtmlString\n{\n}\n\npublic class HttpContextBase\n{\n public virtual System.Web.HttpRequestBase Request { get => throw null; }\n}\n\npublic class HttpCookie\n{\n}\n\npublic abstract class HttpCookieCollection : System.Collections.Specialized.NameObjectCollectionBase\n{\n}\n\npublic class HttpRequest\n{\n}\n\npublic class HttpRequestBase\n{\n public virtual System.Collections.Specialized.NameValueCollection QueryString { get => throw null; }\n}\n\npublic class HttpResponse\n{\n}\n\npublic class HttpResponseBase\n{\n}\n\npublic class HttpServerUtility\n{\n}\n\npublic interface IHtmlString\n{\n}\n\npublic interface IHttpHandler\n{\n}\n\npublic interface IServiceProvider\n{\n}\n\npublic class UnvalidatedRequestValues\n{\n}\n\npublic class UnvalidatedRequestValuesBase\n{\n}\n\nnamespace Mvc\n{\npublic class ActionMethodSelectorAttribute : System.Attribute\n{\n}\n\npublic class ActionResult\n{\n}\n\npublic class ControllerContext\n{\n}\n\npublic class FilterAttribute : System.Attribute\n{\n}\n\npublic class GlobalFilterCollection\n{\n}\n\ninternal interface IFilterProvider\n{\n}\n\npublic interface IViewDataContainer\n{\n}\n\npublic class ViewContext : System.Web.Mvc.ControllerContext\n{\n}\n\npublic class ViewResult : System.Web.Mvc.ViewResultBase\n{\n}\n\npublic class ViewResultBase : System.Web.Mvc.ActionResult\n{\n}\n\n}\nnamespace Routing\n{\npublic class RequestContext\n{\n}\n\n}\nnamespace Script\n{\nnamespace Serialization\n{\npublic abstract class JavaScriptTypeResolver\n{\n}\n\n}\n}\nnamespace Security\n{\npublic class MembershipUser\n{\n}\n\n}\nnamespace SessionState\n{\npublic class HttpSessionState\n{\n}\n\n}\nnamespace UI\n{\npublic class Control\n{\n}\n\nnamespace WebControls\n{\npublic class WebControl : System.Web.UI.Control\n{\n}\n\n}\n}\n}\n}\n\n\n | +| // This file contains auto-generated code.\n// Generated from `System.Collections, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Collections\n{\nnamespace Generic\n{\npublic class Stack : System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.ICollection, System.Collections.IEnumerable\n{\n void System.Collections.ICollection.CopyTo(System.Array array, int arrayIndex) => throw null;\n public int Count { get => throw null; }\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n public T Peek() => throw null;\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Collections.NonGeneric, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Collections\n{\npublic class SortedList : System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable, System.ICloneable\n{\n public virtual void Add(object key, object value) => throw null;\n public virtual void Clear() => throw null;\n public virtual object Clone() => throw null;\n public virtual bool Contains(object key) => throw null;\n public virtual void CopyTo(System.Array array, int arrayIndex) => throw null;\n public virtual int Count { get => throw null; }\n public virtual object GetByIndex(int index) => throw null;\n public virtual System.Collections.IDictionaryEnumerator GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public virtual bool IsFixedSize { get => throw null; }\n public virtual bool IsReadOnly { get => throw null; }\n public virtual bool IsSynchronized { get => throw null; }\n public virtual object this[object key] { get => throw null; set => throw null; }\n public virtual System.Collections.ICollection Keys { get => throw null; }\n public virtual void Remove(object key) => throw null;\n public virtual object SyncRoot { get => throw null; }\n public virtual System.Collections.ICollection Values { get => throw null; }\n}\n\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Collections.Specialized, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Collections\n{\nnamespace Specialized\n{\npublic abstract class NameObjectCollectionBase : System.Collections.ICollection, System.Collections.IEnumerable, System.Runtime.Serialization.IDeserializationCallback, System.Runtime.Serialization.ISerializable\n{\n void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;\n public virtual int Count { get => throw null; }\n public virtual System.Collections.IEnumerator GetEnumerator() => throw null;\n public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) => throw null;\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n public virtual void OnDeserialization(object sender) => throw null;\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n}\n\npublic class NameValueCollection : System.Collections.Specialized.NameObjectCollectionBase\n{\n public string this[string name] { get => throw null; set => throw null; }\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.ComponentModel.TypeConverter, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace ComponentModel\n{\npublic class ComponentConverter : System.ComponentModel.ReferenceConverter\n{\n}\n\npublic class DefaultEventAttribute : System.Attribute\n{\n public DefaultEventAttribute(string name) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\npublic class DefaultPropertyAttribute : System.Attribute\n{\n public DefaultPropertyAttribute(string name) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\npublic class ReferenceConverter : System.ComponentModel.TypeConverter\n{\n}\n\npublic class TypeConverter\n{\n}\n\n}\nnamespace Timers\n{\npublic class TimersDescriptionAttribute\n{\n public TimersDescriptionAttribute(string description) => throw null;\n internal TimersDescriptionAttribute(string description, string unused) => throw null;\n}\n\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Linq, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Linq\n{\npublic static class Enumerable\n{\n public static System.Collections.Generic.IEnumerable Select(this System.Collections.Generic.IEnumerable source, System.Func selector) => throw null;\n}\n\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Linq.Expressions, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Linq\n{\npublic interface IQueryable : System.Collections.IEnumerable\n{\n}\n\n}\nnamespace Runtime\n{\nnamespace CompilerServices\n{\npublic class CallSite\n{\n internal CallSite(System.Runtime.CompilerServices.CallSiteBinder binder) => throw null;\n}\n\npublic class CallSite : System.Runtime.CompilerServices.CallSite where T: class\n{\n private CallSite() : base(default(System.Runtime.CompilerServices.CallSiteBinder)) => throw null;\n private CallSite(System.Runtime.CompilerServices.CallSiteBinder binder) : base(default(System.Runtime.CompilerServices.CallSiteBinder)) => throw null;\n}\n\npublic abstract class CallSiteBinder\n{\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Linq.Parallel, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Linq\n{\npublic static class ParallelEnumerable\n{\n public static System.Linq.ParallelQuery AsParallel(this System.Collections.IEnumerable source) => throw null;\n}\n\npublic class ParallelQuery : System.Collections.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n internal ParallelQuery(System.Linq.Parallel.QuerySettings specifiedSettings) => throw null;\n}\n\nnamespace Parallel\n{\ninternal struct QuerySettings\n{\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Linq.Queryable, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Linq\n{\npublic static class Queryable\n{\n public static System.Linq.IQueryable AsQueryable(this System.Collections.IEnumerable source) => throw null;\n}\n\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.ObjectModel, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace ComponentModel\n{\npublic class TypeConverterAttribute : System.Attribute\n{\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n public TypeConverterAttribute() => throw null;\n public TypeConverterAttribute(System.Type type) => throw null;\n public TypeConverterAttribute(string typeName) => throw null;\n}\n\npublic class TypeDescriptionProviderAttribute : System.Attribute\n{\n public TypeDescriptionProviderAttribute(System.Type type) => throw null;\n public TypeDescriptionProviderAttribute(string typeName) => throw null;\n}\n\n}\nnamespace Windows\n{\nnamespace Markup\n{\npublic class ValueSerializerAttribute : System.Attribute\n{\n public ValueSerializerAttribute(System.Type valueSerializerType) => throw null;\n public ValueSerializerAttribute(string valueSerializerTypeName) => throw null;\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Private.Uri, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\npublic class Uri : System.Runtime.Serialization.ISerializable\n{\n public override bool Equals(object comparand) => throw null;\n public override int GetHashCode() => throw null;\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) => throw null;\n public override string ToString() => throw null;\n}\n\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Runtime.Serialization.Primitives, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Runtime\n{\nnamespace Serialization\n{\npublic class DataContractAttribute : System.Attribute\n{\n public DataContractAttribute() => throw null;\n}\n\npublic class DataMemberAttribute : System.Attribute\n{\n public DataMemberAttribute() => throw null;\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Text.RegularExpressions, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Text\n{\nnamespace RegularExpressions\n{\npublic class Capture\n{\n internal Capture(string text, int index, int length) => throw null;\n public override string ToString() => throw null;\n}\n\npublic class GeneratedRegexAttribute : System.Attribute\n{\n public GeneratedRegexAttribute(string pattern) => throw null;\n public GeneratedRegexAttribute(string pattern, System.Text.RegularExpressions.RegexOptions options) => throw null;\n public GeneratedRegexAttribute(string pattern, System.Text.RegularExpressions.RegexOptions options, int matchTimeoutMilliseconds) => throw null;\n public GeneratedRegexAttribute(string pattern, System.Text.RegularExpressions.RegexOptions options, int matchTimeoutMilliseconds, string cultureName) => throw null;\n public GeneratedRegexAttribute(string pattern, System.Text.RegularExpressions.RegexOptions options, string cultureName) => throw null;\n}\n\npublic class Group : System.Text.RegularExpressions.Capture\n{\n internal Group(string text, int[] caps, int capcount, string name) : base(default(string), default(int), default(int)) => throw null;\n}\n\npublic class Match : System.Text.RegularExpressions.Group\n{\n internal Match(System.Text.RegularExpressions.Regex regex, int capcount, string text, int textLength) : base(default(string), default(int[]), default(int), default(string)) => throw null;\n}\n\npublic class Regex : System.Runtime.Serialization.ISerializable\n{\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo si, System.Runtime.Serialization.StreamingContext context) => throw null;\n public System.Text.RegularExpressions.Match Match(string input) => throw null;\n public static System.Text.RegularExpressions.Match Match(string input, string pattern) => throw null;\n public static System.Text.RegularExpressions.Match Match(string input, string pattern, System.Text.RegularExpressions.RegexOptions options, System.TimeSpan matchTimeout) => throw null;\n public Regex(string pattern) => throw null;\n public Regex(string pattern, System.Text.RegularExpressions.RegexOptions options, System.TimeSpan matchTimeout) => throw null;\n public string Replace(string input, string replacement) => throw null;\n public override string ToString() => throw null;\n}\n\n[System.Flags]\npublic enum RegexOptions : int\n{\n IgnoreCase = 1,\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Web, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null`.\n\nnamespace System\n{\nnamespace Web\n{\npublic class HtmlString : System.Web.IHtmlString\n{\n}\n\npublic class HttpContextBase\n{\n public virtual System.Web.HttpRequestBase Request { get => throw null; }\n}\n\npublic class HttpCookie\n{\n}\n\npublic abstract class HttpCookieCollection : System.Collections.Specialized.NameObjectCollectionBase\n{\n}\n\npublic class HttpRequest\n{\n}\n\npublic class HttpRequestBase\n{\n public virtual System.Collections.Specialized.NameValueCollection QueryString { get => throw null; }\n}\n\npublic class HttpResponse\n{\n}\n\npublic class HttpResponseBase\n{\n}\n\npublic class HttpServerUtility\n{\n}\n\npublic interface IHtmlString\n{\n}\n\npublic interface IHttpHandler\n{\n}\n\npublic interface IServiceProvider\n{\n}\n\npublic class UnvalidatedRequestValues\n{\n}\n\npublic class UnvalidatedRequestValuesBase\n{\n}\n\nnamespace Mvc\n{\npublic class ActionMethodSelectorAttribute : System.Attribute\n{\n}\n\npublic class ActionResult\n{\n}\n\npublic class ControllerContext\n{\n}\n\npublic class FilterAttribute : System.Attribute\n{\n}\n\npublic class GlobalFilterCollection\n{\n}\n\ninternal interface IFilterProvider\n{\n}\n\npublic interface IViewDataContainer\n{\n}\n\npublic class ViewContext : System.Web.Mvc.ControllerContext\n{\n}\n\npublic class ViewResult : System.Web.Mvc.ViewResultBase\n{\n}\n\npublic class ViewResultBase : System.Web.Mvc.ActionResult\n{\n}\n\n}\nnamespace Routing\n{\npublic class RequestContext\n{\n}\n\npublic class Route\n{\n}\n\npublic class RouteCollection\n{\n}\n\npublic class RouteTable\n{\n}\n\n}\nnamespace Script\n{\nnamespace Serialization\n{\npublic abstract class JavaScriptTypeResolver\n{\n}\n\n}\n}\nnamespace Security\n{\npublic class MembershipUser\n{\n}\n\n}\nnamespace SessionState\n{\npublic class HttpSessionState\n{\n}\n\n}\nnamespace UI\n{\npublic class Control\n{\n}\n\nnamespace WebControls\n{\npublic class WebControl : System.Web.UI.Control\n{\n}\n\n}\n}\n}\n}\n\n\n | From 9b31b61143d2ff0adf525fb6caf7e65a7ce50e1e Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 13 Jun 2023 19:18:42 +0100 Subject: [PATCH 009/118] Broaden the scope of checks for authorization attributes --- .../auth/MissingFunctionLevelAccessControlQuery.qll | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll index 35f75c59a28..c450091c282 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll @@ -166,11 +166,12 @@ predicate hasAuthViaXml(ActionMethod m) { ) } -/** Holds if the given action has an `Authorize` attribute. */ +/** Holds if the given action has an attribute that indications authorization. */ predicate hasAuthViaAttribute(ActionMethod m) { - [m.getAnAttribute(), m.getDeclaringType().getAnAttribute()] - .getType() - .hasQualifiedName("Microsoft.AspNetCore.Authorization", "AuthorizeAttribute") + exists(Attribute attr | attr.getType().getName().toLowerCase().matches("%auth%") | + attr = m.getAnAttribute() or + attr = m.getDeclaringType().getABaseType*().getAnAttribute() + ) } /** Holds if `m` is a method that should have an auth check, but is missing it. */ From 12bb41837520457fd17681e8a1a8c16266a49157 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 14 Jun 2023 16:12:34 +0100 Subject: [PATCH 010/118] Add change note --- .../ql/src/change-notes/2023-06-14-missing-access-control.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 csharp/ql/src/change-notes/2023-06-14-missing-access-control.md diff --git a/csharp/ql/src/change-notes/2023-06-14-missing-access-control.md b/csharp/ql/src/change-notes/2023-06-14-missing-access-control.md new file mode 100644 index 00000000000..6cbb12fceea --- /dev/null +++ b/csharp/ql/src/change-notes/2023-06-14-missing-access-control.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `cs/web/missing-function-level-access-control`, to find instances of missing authorization checks. \ No newline at end of file From 8fdec4f11617ae7e01368e3477d7dca430ab2efc Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 20 Jun 2023 17:18:04 +0100 Subject: [PATCH 011/118] Add documentation --- .../ql/src/Security Features/CWE-285/MVC.cs | 13 +++++ .../CWE-285/MissingAccessControl.qhelp | 54 +++++++++++++++++++ .../CWE-285/MissingAccessControl.ql | 4 +- .../src/Security Features/CWE-285/Web.config | 11 ++++ .../src/Security Features/CWE-285/WebForms.cs | 14 +++++ 5 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 csharp/ql/src/Security Features/CWE-285/MVC.cs create mode 100644 csharp/ql/src/Security Features/CWE-285/MissingAccessControl.qhelp create mode 100644 csharp/ql/src/Security Features/CWE-285/Web.config create mode 100644 csharp/ql/src/Security Features/CWE-285/WebForms.cs diff --git a/csharp/ql/src/Security Features/CWE-285/MVC.cs b/csharp/ql/src/Security Features/CWE-285/MVC.cs new file mode 100644 index 00000000000..58575993482 --- /dev/null +++ b/csharp/ql/src/Security Features/CWE-285/MVC.cs @@ -0,0 +1,13 @@ +public class ProfileController : Controller { + + // BAD: No authorization is used. + public ActionResult Edit(int id) { + ... + } + + // GOOD: The `Authorize` tag is used. + [Authorize] + public ActionResult Delete(int id) { + ... + } +} \ No newline at end of file diff --git a/csharp/ql/src/Security Features/CWE-285/MissingAccessControl.qhelp b/csharp/ql/src/Security Features/CWE-285/MissingAccessControl.qhelp new file mode 100644 index 00000000000..36d3142f85e --- /dev/null +++ b/csharp/ql/src/Security Features/CWE-285/MissingAccessControl.qhelp @@ -0,0 +1,54 @@ + + + + +

+Sensitive actions, such as editing or deleting content, or accessing admin pages, should have authentication checks +to ensure that they cannot be used by arbitrary users. +

+ +
+ + +

+Ensure that proper authorization checks are made for sensitive actions. +For WebForms applications, the authorazation tag in Web.config XML files +can be used to implement access control. The System.Web.UI.Page.User property can also be +used to verify a user's roles. +For MVC applications, the Authorize attribute can be used to require authorization on specific +action methods. +

+ +
+ + +

+In the following WebForms example, the case marked BAD has no authorization checks; whereas the +case marked GOOD uses User.IsInRole to check for the user's role. +

+ + + +

+The following Web.config file uses the authorization tag to deny access to anonymous users, +in a tag to have it apply to a specific path. +

+ + + +

+In the following MVC example, the case marked BAD has no authorization +checks; whereas the case marked GOOD uses the Authorize attribute. +

+ + + +
+ +
  • Page.User Property - Microsoft Learn
  • +
  • Control authorization permissions in an ASP.NET application - Microsoft Learn
  • +
  • Simple authorization in ASP.NET Core - Microsoft Learn
  • +
    +
    diff --git a/csharp/ql/src/Security Features/CWE-285/MissingAccessControl.ql b/csharp/ql/src/Security Features/CWE-285/MissingAccessControl.ql index 5eb62d6ca02..dccb72e01ce 100644 --- a/csharp/ql/src/Security Features/CWE-285/MissingAccessControl.ql +++ b/csharp/ql/src/Security Features/CWE-285/MissingAccessControl.ql @@ -1,6 +1,6 @@ /** * @name Missing function level access control - * @description ... TODO + * @description Sensitive actions should have authorization checks to prevent them from being used by arbitrary users. * @kind problem * @problem.severity warning * @security-severity 7.5 @@ -8,6 +8,8 @@ * @id cs/web/missing-function-level-access-control * @tags security * external/cwe/cwe-285 + * external/cwe/cwe-284 + * external/cwe/cwe-862 */ import csharp diff --git a/csharp/ql/src/Security Features/CWE-285/Web.config b/csharp/ql/src/Security Features/CWE-285/Web.config new file mode 100644 index 00000000000..8e83c8d38e9 --- /dev/null +++ b/csharp/ql/src/Security Features/CWE-285/Web.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/csharp/ql/src/Security Features/CWE-285/WebForms.cs b/csharp/ql/src/Security Features/CWE-285/WebForms.cs new file mode 100644 index 00000000000..49dce6097f1 --- /dev/null +++ b/csharp/ql/src/Security Features/CWE-285/WebForms.cs @@ -0,0 +1,14 @@ +class ProfilePage : System.Web.UI.Page { + // BAD: No authorization is used + protected void btn1_Edit_Click(object sender, EventArgs e) { + ... + } + + // GOOD: `User.IsInRole` checks the current user's role. + protected void btn2_Delete_Click(object sender, EventArgs e) { + if (!User.IsInRole("admin")) { + return; + } + ... + } +} \ No newline at end of file From 6947e99c1545f77b81dd99e539d601b0c72074b7 Mon Sep 17 00:00:00 2001 From: jorgectf Date: Thu, 22 Jun 2023 01:07:33 +0200 Subject: [PATCH 012/118] Add models for `webix` Co-authored-by: Kevin Stubbings --- javascript/ql/lib/javascript.qll | 1 + .../ql/lib/semmle/javascript/Extend.qll | 3 +- .../dataflow/CodeInjectionCustomizations.qll | 24 +++ .../PrototypePollutionCustomizations.qll | 4 + .../CodeInjection/CodeInjection.expected | 165 ++++++++++-------- .../CWE-094/CodeInjection/template-sinks.js | 5 +- .../Security/CWE-094/CodeInjection/webix.js | 3 + .../PrototypePollutingMergeCall.expected | 12 ++ .../PrototypePollutingMergeCall/webix.js | 5 + 9 files changed, 145 insertions(+), 77 deletions(-) create mode 100644 javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/webix.js create mode 100644 javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix.js diff --git a/javascript/ql/lib/javascript.qll b/javascript/ql/lib/javascript.qll index ed38db6550e..07fb759bd65 100644 --- a/javascript/ql/lib/javascript.qll +++ b/javascript/ql/lib/javascript.qll @@ -134,6 +134,7 @@ import semmle.javascript.frameworks.TrustedTypes import semmle.javascript.frameworks.UriLibraries import semmle.javascript.frameworks.Vue import semmle.javascript.frameworks.Vuex +import semmle.javascript.frameworks.Webix import semmle.javascript.frameworks.WebSocket import semmle.javascript.frameworks.XmlParsers import semmle.javascript.frameworks.xUnit diff --git a/javascript/ql/lib/semmle/javascript/Extend.qll b/javascript/ql/lib/semmle/javascript/Extend.qll index 3b389691434..1b3204914ef 100644 --- a/javascript/ql/lib/semmle/javascript/Extend.qll +++ b/javascript/ql/lib/semmle/javascript/Extend.qll @@ -96,7 +96,8 @@ private class ExtendCallDeep extends ExtendCall { callee = LodashUnderscore::member("merge") or callee = LodashUnderscore::member("mergeWith") or callee = LodashUnderscore::member("defaultsDeep") or - callee = AngularJS::angular().getAPropertyRead("merge") + callee = AngularJS::angular().getAPropertyRead("merge") or + callee = DataFlow::moduleImport("webix").getAPropertyRead("extend") ) } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll index 5d658b23b59..5d1a9bc2896 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll @@ -312,6 +312,13 @@ module CodeInjection { } } + /** + * A value interpreted as code by the `webix` library. + */ + class WebixExec extends Sink { + WebixExec() { this = DataFlow::moduleImport("webix").getAMemberCall("exec").getArgument(0) } + } + /** A sink for code injection via template injection. */ abstract private class TemplateSink extends Sink { deprecated override string getMessageSuffix() { @@ -419,6 +426,23 @@ module CodeInjection { } } + /** + * A value interpreted as a template by the `webix` library. + */ + class WebixTemplateSink extends TemplateSink { + WebixTemplateSink() { + this = DataFlow::moduleImport("webix").getAMemberCall("ui").getOptionArgument(0, "template") + or + this.asExpr() = + DataFlow::moduleImport("webix") + .getAMemberCall("ui") + .getOptionArgument(0, "template") + .asExpr() + .(Function) + .getAReturnedExpr() + } + } + /** * A call to JSON.stringify() seen as a sanitizer. */ diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutionCustomizations.qll index bd233e33ae1..cc82792abf4 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutionCustomizations.qll @@ -171,5 +171,9 @@ module PrototypePollution { call.isDeep() and call = AngularJS::angular().getAMemberCall("merge") and id = "angular" + or + call.isDeep() and + call = DataFlow::moduleImport("webix").getAMemberCall("extend") and + id = "webix" } } diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected index d866329402a..cc3175a3645 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected @@ -112,37 +112,41 @@ nodes | react.js:10:56:10:77 | documen ... on.hash | | react.js:10:56:10:77 | documen ... on.hash | | react.js:10:56:10:77 | documen ... on.hash | -| template-sinks.js:17:9:17:31 | tainted | -| template-sinks.js:17:19:17:31 | req.query.foo | -| template-sinks.js:17:19:17:31 | req.query.foo | -| template-sinks.js:19:17:19:23 | tainted | -| template-sinks.js:19:17:19:23 | tainted | -| template-sinks.js:20:16:20:22 | tainted | -| template-sinks.js:20:16:20:22 | tainted | -| template-sinks.js:21:18:21:24 | tainted | -| template-sinks.js:21:18:21:24 | tainted | -| template-sinks.js:22:17:22:23 | tainted | -| template-sinks.js:22:17:22:23 | tainted | -| template-sinks.js:23:18:23:24 | tainted | -| template-sinks.js:23:18:23:24 | tainted | -| template-sinks.js:24:16:24:22 | tainted | -| template-sinks.js:24:16:24:22 | tainted | -| template-sinks.js:25:27:25:33 | tainted | -| template-sinks.js:25:27:25:33 | tainted | -| template-sinks.js:26:21:26:27 | tainted | -| template-sinks.js:26:21:26:27 | tainted | -| template-sinks.js:27:17:27:23 | tainted | -| template-sinks.js:27:17:27:23 | tainted | -| template-sinks.js:28:24:28:30 | tainted | -| template-sinks.js:28:24:28:30 | tainted | -| template-sinks.js:29:21:29:27 | tainted | -| template-sinks.js:29:21:29:27 | tainted | -| template-sinks.js:30:19:30:25 | tainted | -| template-sinks.js:30:19:30:25 | tainted | -| template-sinks.js:31:16:31:22 | tainted | -| template-sinks.js:31:16:31:22 | tainted | -| template-sinks.js:32:17:32:23 | tainted | -| template-sinks.js:32:17:32:23 | tainted | +| template-sinks.js:18:9:18:31 | tainted | +| template-sinks.js:18:19:18:31 | req.query.foo | +| template-sinks.js:18:19:18:31 | req.query.foo | +| template-sinks.js:20:17:20:23 | tainted | +| template-sinks.js:20:17:20:23 | tainted | +| template-sinks.js:21:16:21:22 | tainted | +| template-sinks.js:21:16:21:22 | tainted | +| template-sinks.js:22:18:22:24 | tainted | +| template-sinks.js:22:18:22:24 | tainted | +| template-sinks.js:23:17:23:23 | tainted | +| template-sinks.js:23:17:23:23 | tainted | +| template-sinks.js:24:18:24:24 | tainted | +| template-sinks.js:24:18:24:24 | tainted | +| template-sinks.js:25:16:25:22 | tainted | +| template-sinks.js:25:16:25:22 | tainted | +| template-sinks.js:26:27:26:33 | tainted | +| template-sinks.js:26:27:26:33 | tainted | +| template-sinks.js:27:21:27:27 | tainted | +| template-sinks.js:27:21:27:27 | tainted | +| template-sinks.js:28:17:28:23 | tainted | +| template-sinks.js:28:17:28:23 | tainted | +| template-sinks.js:29:24:29:30 | tainted | +| template-sinks.js:29:24:29:30 | tainted | +| template-sinks.js:30:21:30:27 | tainted | +| template-sinks.js:30:21:30:27 | tainted | +| template-sinks.js:31:19:31:25 | tainted | +| template-sinks.js:31:19:31:25 | tainted | +| template-sinks.js:32:16:32:22 | tainted | +| template-sinks.js:32:16:32:22 | tainted | +| template-sinks.js:33:17:33:23 | tainted | +| template-sinks.js:33:17:33:23 | tainted | +| template-sinks.js:34:26:34:32 | tainted | +| template-sinks.js:34:26:34:32 | tainted | +| template-sinks.js:35:47:35:53 | tainted | +| template-sinks.js:35:47:35:53 | tainted | | tst.js:2:6:2:27 | documen ... on.href | | tst.js:2:6:2:27 | documen ... on.href | | tst.js:2:6:2:83 | documen ... t=")+8) | @@ -181,6 +185,9 @@ nodes | tst.js:35:28:35:33 | source | | tst.js:37:33:37:38 | source | | tst.js:37:33:37:38 | source | +| webix.js:3:12:3:33 | documen ... on.hash | +| webix.js:3:12:3:33 | documen ... on.hash | +| webix.js:3:12:3:33 | documen ... on.hash | edges | NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | | NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | @@ -246,36 +253,40 @@ edges | react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | | react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | | react.js:10:56:10:77 | documen ... on.hash | react.js:10:56:10:77 | documen ... on.hash | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:19:17:19:23 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:19:17:19:23 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:20:16:20:22 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:20:16:20:22 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:21:18:21:24 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:21:18:21:24 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:22:17:22:23 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:22:17:22:23 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:23:18:23:24 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:23:18:23:24 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:24:16:24:22 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:24:16:24:22 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:25:27:25:33 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:25:27:25:33 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:26:21:26:27 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:26:21:26:27 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:27:17:27:23 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:27:17:27:23 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:28:24:28:30 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:28:24:28:30 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:29:21:29:27 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:29:21:29:27 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:30:19:30:25 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:30:19:30:25 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:31:16:31:22 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:31:16:31:22 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:32:17:32:23 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:32:17:32:23 | tainted | -| template-sinks.js:17:19:17:31 | req.query.foo | template-sinks.js:17:9:17:31 | tainted | -| template-sinks.js:17:19:17:31 | req.query.foo | template-sinks.js:17:9:17:31 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:20:17:20:23 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:20:17:20:23 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:21:16:21:22 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:21:16:21:22 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:22:18:22:24 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:22:18:22:24 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:23:17:23:23 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:23:17:23:23 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:24:18:24:24 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:24:18:24:24 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:25:16:25:22 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:25:16:25:22 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:26:27:26:33 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:26:27:26:33 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:27:21:27:27 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:27:21:27:27 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:28:17:28:23 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:28:17:28:23 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:29:24:29:30 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:29:24:29:30 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:30:21:30:27 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:30:21:30:27 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:31:19:31:25 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:31:19:31:25 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:32:16:32:22 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:32:16:32:22 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:33:17:33:23 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:33:17:33:23 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:34:26:34:32 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:34:26:34:32 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:35:47:35:53 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:35:47:35:53 | tainted | +| template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:18:9:18:31 | tainted | +| template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:18:9:18:31 | tainted | | tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | | tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | | tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | @@ -306,6 +317,7 @@ edges | tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") | | tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") | | tst.js:29:18:29:82 | documen ... , "$1") | tst.js:29:9:29:82 | source | +| webix.js:3:12:3:33 | documen ... on.hash | webix.js:3:12:3:33 | documen ... on.hash | #select | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | This code execution depends on a $@. | NoSQLCodeInjection.js:18:24:18:31 | req.body | user-provided value | | NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | NoSQLCodeInjection.js:19:36:19:43 | req.body | NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | This code execution depends on a $@. | NoSQLCodeInjection.js:19:36:19:43 | req.body | user-provided value | @@ -340,20 +352,22 @@ edges | react-native.js:8:32:8:38 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:8:32:8:38 | tainted | This code execution depends on a $@. | react-native.js:7:17:7:33 | req.param("code") | user-provided value | | react-native.js:10:23:10:29 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:10:23:10:29 | tainted | This code execution depends on a $@. | react-native.js:7:17:7:33 | req.param("code") | user-provided value | | react.js:10:56:10:77 | documen ... on.hash | react.js:10:56:10:77 | documen ... on.hash | react.js:10:56:10:77 | documen ... on.hash | This code execution depends on a $@. | react.js:10:56:10:77 | documen ... on.hash | user-provided value | -| template-sinks.js:19:17:19:23 | tainted | template-sinks.js:17:19:17:31 | req.query.foo | template-sinks.js:19:17:19:23 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:17:19:17:31 | req.query.foo | user-provided value | -| template-sinks.js:20:16:20:22 | tainted | template-sinks.js:17:19:17:31 | req.query.foo | template-sinks.js:20:16:20:22 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:17:19:17:31 | req.query.foo | user-provided value | -| template-sinks.js:21:18:21:24 | tainted | template-sinks.js:17:19:17:31 | req.query.foo | template-sinks.js:21:18:21:24 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:17:19:17:31 | req.query.foo | user-provided value | -| template-sinks.js:22:17:22:23 | tainted | template-sinks.js:17:19:17:31 | req.query.foo | template-sinks.js:22:17:22:23 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:17:19:17:31 | req.query.foo | user-provided value | -| template-sinks.js:23:18:23:24 | tainted | template-sinks.js:17:19:17:31 | req.query.foo | template-sinks.js:23:18:23:24 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:17:19:17:31 | req.query.foo | user-provided value | -| template-sinks.js:24:16:24:22 | tainted | template-sinks.js:17:19:17:31 | req.query.foo | template-sinks.js:24:16:24:22 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:17:19:17:31 | req.query.foo | user-provided value | -| template-sinks.js:25:27:25:33 | tainted | template-sinks.js:17:19:17:31 | req.query.foo | template-sinks.js:25:27:25:33 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:17:19:17:31 | req.query.foo | user-provided value | -| template-sinks.js:26:21:26:27 | tainted | template-sinks.js:17:19:17:31 | req.query.foo | template-sinks.js:26:21:26:27 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:17:19:17:31 | req.query.foo | user-provided value | -| template-sinks.js:27:17:27:23 | tainted | template-sinks.js:17:19:17:31 | req.query.foo | template-sinks.js:27:17:27:23 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:17:19:17:31 | req.query.foo | user-provided value | -| template-sinks.js:28:24:28:30 | tainted | template-sinks.js:17:19:17:31 | req.query.foo | template-sinks.js:28:24:28:30 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:17:19:17:31 | req.query.foo | user-provided value | -| template-sinks.js:29:21:29:27 | tainted | template-sinks.js:17:19:17:31 | req.query.foo | template-sinks.js:29:21:29:27 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:17:19:17:31 | req.query.foo | user-provided value | -| template-sinks.js:30:19:30:25 | tainted | template-sinks.js:17:19:17:31 | req.query.foo | template-sinks.js:30:19:30:25 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:17:19:17:31 | req.query.foo | user-provided value | -| template-sinks.js:31:16:31:22 | tainted | template-sinks.js:17:19:17:31 | req.query.foo | template-sinks.js:31:16:31:22 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:17:19:17:31 | req.query.foo | user-provided value | -| template-sinks.js:32:17:32:23 | tainted | template-sinks.js:17:19:17:31 | req.query.foo | template-sinks.js:32:17:32:23 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:17:19:17:31 | req.query.foo | user-provided value | +| template-sinks.js:20:17:20:23 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:20:17:20:23 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | +| template-sinks.js:21:16:21:22 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:21:16:21:22 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | +| template-sinks.js:22:18:22:24 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:22:18:22:24 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | +| template-sinks.js:23:17:23:23 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:23:17:23:23 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | +| template-sinks.js:24:18:24:24 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:24:18:24:24 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | +| template-sinks.js:25:16:25:22 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:25:16:25:22 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | +| template-sinks.js:26:27:26:33 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:26:27:26:33 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | +| template-sinks.js:27:21:27:27 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:27:21:27:27 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | +| template-sinks.js:28:17:28:23 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:28:17:28:23 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | +| template-sinks.js:29:24:29:30 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:29:24:29:30 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | +| template-sinks.js:30:21:30:27 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:30:21:30:27 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | +| template-sinks.js:31:19:31:25 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:31:19:31:25 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | +| template-sinks.js:32:16:32:22 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:32:16:32:22 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | +| template-sinks.js:33:17:33:23 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:33:17:33:23 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | +| template-sinks.js:34:26:34:32 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:34:26:34:32 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | +| template-sinks.js:35:47:35:53 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:35:47:35:53 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | | tst.js:2:6:2:83 | documen ... t=")+8) | tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | This code execution depends on a $@. | tst.js:2:6:2:27 | documen ... on.href | user-provided value | | tst.js:5:12:5:33 | documen ... on.hash | tst.js:5:12:5:33 | documen ... on.hash | tst.js:5:12:5:33 | documen ... on.hash | This code execution depends on a $@. | tst.js:5:12:5:33 | documen ... on.hash | user-provided value | | tst.js:14:10:14:74 | documen ... , "$1") | tst.js:14:10:14:33 | documen ... .search | tst.js:14:10:14:74 | documen ... , "$1") | This code execution depends on a $@. | tst.js:14:10:14:33 | documen ... .search | user-provided value | @@ -365,3 +379,4 @@ edges | tst.js:33:14:33:19 | source | tst.js:29:18:29:41 | documen ... .search | tst.js:33:14:33:19 | source | This code execution depends on a $@. | tst.js:29:18:29:41 | documen ... .search | user-provided value | | tst.js:35:28:35:33 | source | tst.js:29:18:29:41 | documen ... .search | tst.js:35:28:35:33 | source | This code execution depends on a $@. | tst.js:29:18:29:41 | documen ... .search | user-provided value | | tst.js:37:33:37:38 | source | tst.js:29:18:29:41 | documen ... .search | tst.js:37:33:37:38 | source | This code execution depends on a $@. | tst.js:29:18:29:41 | documen ... .search | user-provided value | +| webix.js:3:12:3:33 | documen ... on.hash | webix.js:3:12:3:33 | documen ... on.hash | webix.js:3:12:3:33 | documen ... on.hash | This code execution depends on a $@. | webix.js:3:12:3:33 | documen ... on.hash | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/template-sinks.js b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/template-sinks.js index f2cc7a400f6..7c8e310cd1f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/template-sinks.js +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/template-sinks.js @@ -10,10 +10,11 @@ import * as mustache from 'mustache'; const Hogan = require("hogan.js"); import * as Eta from 'eta'; import * as Sqrl from 'squirrelly' +import * as webix from "webix"; var app = express(); -app.get('/some/path', function(req, res) { +app.get('/some/path', function (req, res) { let tainted = req.query.foo; pug.compile(tainted); // NOT OK @@ -30,4 +31,6 @@ app.get('/some/path', function(req, res) { Hogan.compile(tainted); // NOT OK Eta.render(tainted); // NOT OK Sqrl.render(tainted); // NOT OK + webix.ui({ template: tainted }); // NOT OK + webix.ui({ template: function () { return tainted } }) // NOT OK }); diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/webix.js b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/webix.js new file mode 100644 index 00000000000..289bffe22b4 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/webix.js @@ -0,0 +1,3 @@ +import * as webix from 'webix'; + +webix.exec(document.location.hash); // NOT OK \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected index f7b8f8df1d3..4664d64a742 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected @@ -17,6 +17,12 @@ nodes | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | +| webix.js:3:30:3:34 | event | +| webix.js:3:30:3:34 | event | +| webix.js:4:22:4:43 | JSON.pa ... t.data) | +| webix.js:4:22:4:43 | JSON.pa ... t.data) | +| webix.js:4:33:4:37 | event | +| webix.js:4:33:4:42 | event.data | edges | angularmerge.js:1:30:1:34 | event | angularmerge.js:2:32:2:36 | event | | angularmerge.js:1:30:1:34 | event | angularmerge.js:2:32:2:36 | event | @@ -32,8 +38,14 @@ edges | src-vulnerable-lodash/tst.js:15:14:15:28 | req.query.value | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | +| webix.js:3:30:3:34 | event | webix.js:4:33:4:37 | event | +| webix.js:3:30:3:34 | event | webix.js:4:33:4:37 | event | +| webix.js:4:33:4:37 | event | webix.js:4:33:4:42 | event.data | +| webix.js:4:33:4:42 | event.data | webix.js:4:22:4:43 | JSON.pa ... t.data) | +| webix.js:4:33:4:42 | event.data | webix.js:4:22:4:43 | JSON.pa ... t.data) | #select | angularmerge.js:2:21:2:42 | JSON.pa ... t.data) | angularmerge.js:1:30:1:34 | event | angularmerge.js:2:21:2:42 | JSON.pa ... t.data) | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | angularmerge.js:1:30:1:34 | event | user-controlled value | angularmerge.js:2:3:2:43 | angular ... .data)) | angular | | src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | user-controlled value | src-vulnerable-lodash/package.json:3:19:3:26 | "4.17.4" | lodash | | src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } | src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | user-controlled value | src-vulnerable-lodash/package.json:3:19:3:26 | "4.17.4" | lodash | | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | src-vulnerable-lodash/tst.js:15:14:15:28 | req.query.value | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | src-vulnerable-lodash/tst.js:15:14:15:28 | req.query.value | user-controlled value | src-vulnerable-lodash/package.json:3:19:3:26 | "4.17.4" | lodash | +| webix.js:4:22:4:43 | JSON.pa ... t.data) | webix.js:3:30:3:34 | event | webix.js:4:22:4:43 | JSON.pa ... t.data) | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | webix.js:3:30:3:34 | event | user-controlled value | webix.js:4:5:4:44 | webix.e ... .data)) | webix | diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix.js b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix.js new file mode 100644 index 00000000000..85983bb0af7 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix.js @@ -0,0 +1,5 @@ +import * as webix from "webix"; + +addEventListener("message", (event) => { + webix.extend({}, JSON.parse(event.data)); // NOT OK +}); From 868129c7e7f1981360724c56cc33bd6af411f324 Mon Sep 17 00:00:00 2001 From: jorgectf Date: Thu, 22 Jun 2023 01:14:06 +0200 Subject: [PATCH 013/118] Add change note --- javascript/ql/lib/change-notes/2023-06-22-webix.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 javascript/ql/lib/change-notes/2023-06-22-webix.md diff --git a/javascript/ql/lib/change-notes/2023-06-22-webix.md b/javascript/ql/lib/change-notes/2023-06-22-webix.md new file mode 100644 index 00000000000..9daa1b1a5dc --- /dev/null +++ b/javascript/ql/lib/change-notes/2023-06-22-webix.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added models for the Webix Framework. \ No newline at end of file From 7e7e2aaac70adf8b33389d7aeb1c46d2801e0075 Mon Sep 17 00:00:00 2001 From: jorgectf Date: Thu, 22 Jun 2023 01:15:08 +0200 Subject: [PATCH 014/118] Remove non-existing import --- javascript/ql/lib/javascript.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/javascript/ql/lib/javascript.qll b/javascript/ql/lib/javascript.qll index 07fb759bd65..ed38db6550e 100644 --- a/javascript/ql/lib/javascript.qll +++ b/javascript/ql/lib/javascript.qll @@ -134,7 +134,6 @@ import semmle.javascript.frameworks.TrustedTypes import semmle.javascript.frameworks.UriLibraries import semmle.javascript.frameworks.Vue import semmle.javascript.frameworks.Vuex -import semmle.javascript.frameworks.Webix import semmle.javascript.frameworks.WebSocket import semmle.javascript.frameworks.XmlParsers import semmle.javascript.frameworks.xUnit From 270bcc37400f3351993c8a0f53bcd2ad5739aa35 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 22 Jun 2023 11:20:58 +0100 Subject: [PATCH 015/118] fix qhelp and remove commented out code --- .../security/auth/MissingFunctionLevelAccessControlQuery.qll | 1 - .../ql/src/Security Features/CWE-285/MissingAccessControl.qhelp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll index c450091c282..982afd63f4b 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll @@ -83,7 +83,6 @@ private predicate virtualRouteMapping(string virtualRoute, string physicalRoute) physicalLit = mapPageRouteCall.getArgument(2) and virtualLit.getValue() = virtualRoute and physicalLit.getValue() = physicalRoute - // physicalRouteMatches(physicalLit.getValue(), physicalRoute) ) } diff --git a/csharp/ql/src/Security Features/CWE-285/MissingAccessControl.qhelp b/csharp/ql/src/Security Features/CWE-285/MissingAccessControl.qhelp index 36d3142f85e..a81e71a8da9 100644 --- a/csharp/ql/src/Security Features/CWE-285/MissingAccessControl.qhelp +++ b/csharp/ql/src/Security Features/CWE-285/MissingAccessControl.qhelp @@ -33,7 +33,7 @@ case marked GOOD uses User.IsInRole to check for the user's role.

    The following Web.config file uses the authorization tag to deny access to anonymous users, -in a tag to have it apply to a specific path. +in a location> tag to have it apply to a specific path.

    From bdaeeeadeeac90a454aa89771109cfc7d8da7ac6 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 22 Jun 2023 11:21:30 +0100 Subject: [PATCH 016/118] Add good/bad indicators to tests --- .../MVCTests/MissingAccessControl.expected | 2 +- .../MissingAccessControl/MVCTests/ProfileController.cs | 2 ++ .../WebFormsTests/MissingAccessControl.expected | 6 +++--- .../WebFormsTests/Test1/EditProfile.aspx.cs | 2 ++ .../WebFormsTests/Test1/ViewProfile.aspx.cs | 3 +++ .../WebFormsTests/Test2/EditProfile.aspx.cs | 1 + .../WebFormsTests/Test3/A/EditProfile.aspx.cs | 1 + .../WebFormsTests/Test3/B/EditProfile.aspx.cs | 1 + .../WebFormsTests/Test3/C/EditProfile.aspx.cs | 1 + 9 files changed, 15 insertions(+), 4 deletions(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/MissingAccessControl.expected b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/MissingAccessControl.expected index f6d983c8f77..1ad8d1cdeb5 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/MissingAccessControl.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/MissingAccessControl.expected @@ -1 +1 @@ -| ProfileController.cs:7:25:7:31 | Delete1 | This action is missing an authorization check. | +| ProfileController.cs:8:25:8:31 | Delete1 | This action is missing an authorization check. | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/ProfileController.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/ProfileController.cs index 7ecd6323b97..d2ed864f4c7 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/ProfileController.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/ProfileController.cs @@ -4,11 +4,13 @@ public class ProfileController : Controller { private void doThings() { } private bool isAuthorized() { return false; } + // BAD: This is a Delete method, but no auth is specified. public ActionResult Delete1(int id) { doThings(); return View(); } + // GOOD: isAuthorized is checked. public ActionResult Delete2(int id) { if (!isAuthorized()) { return null; diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/MissingAccessControl.expected b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/MissingAccessControl.expected index ccac820134b..5c0df701d81 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/MissingAccessControl.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/MissingAccessControl.expected @@ -1,3 +1,3 @@ -| Test1/EditProfile.aspx.cs:9:20:9:29 | btn1_Click | This action is missing an authorization check. | -| Test1/ViewProfile.aspx.cs:12:20:12:36 | btn_delete1_Click | This action is missing an authorization check. | -| Test3/B/EditProfile.aspx.cs:7:20:7:29 | btn1_Click | This action is missing an authorization check. | +| Test1/EditProfile.aspx.cs:10:20:10:29 | btn1_Click | This action is missing an authorization check. | +| Test1/ViewProfile.aspx.cs:14:20:14:36 | btn_delete1_Click | This action is missing an authorization check. | +| Test3/B/EditProfile.aspx.cs:8:20:8:29 | btn1_Click | This action is missing an authorization check. | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test1/EditProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test1/EditProfile.aspx.cs index 9ca2efe5bee..b023dc11e80 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test1/EditProfile.aspx.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test1/EditProfile.aspx.cs @@ -6,10 +6,12 @@ class EditProfile : System.Web.UI.Page { private bool isAuthorized() { return false; } + // BAD: The class name indicates that this may be an Edit method, but there is no auth check protected void btn1_Click(object sender, EventArgs e) { doThings(); } + // GOOD: There is a call to isAuthorized protected void btn2_Click(object sender, EventArgs e) { if (isAuthorized()) { doThings(); diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test1/ViewProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test1/ViewProfile.aspx.cs index fc04d551eec..f9d7316d50b 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test1/ViewProfile.aspx.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test1/ViewProfile.aspx.cs @@ -5,14 +5,17 @@ using System.Web.Security; class ViewProfile : System.Web.UI.Page { private void doThings() { } + // GOOD: This method and class name do not indicate a sensitive method. protected void btn_safe_Click(object sender, EventArgs e) { doThings(); } + // BAD: The name indicates a Delete method, but no auth is present. protected void btn_delete1_Click(object sender, EventArgs e) { doThings(); } + // GOOD: User.IsInRole is checked. protected void btn_delete2_Click(object sender, EventArgs e) { if (User.IsInRole("admin")) { doThings(); diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test2/EditProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test2/EditProfile.aspx.cs index f14c39078cd..0d0b2b7b864 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test2/EditProfile.aspx.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test2/EditProfile.aspx.cs @@ -4,6 +4,7 @@ using System.Web.UI; class EditProfile2 : System.Web.UI.Page { private void doThings() { } + // GOOD: The Web.config file specifies auth for this path. protected void btn1_Click(object sender, EventArgs e) { doThings(); } diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/A/EditProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/A/EditProfile.aspx.cs index 6f66d66e653..4f5025a4a51 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/A/EditProfile.aspx.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/A/EditProfile.aspx.cs @@ -4,6 +4,7 @@ using System.Web.UI; class EditProfile3 : System.Web.UI.Page { private void doThings() { } + // GOOD: This is covered by the Web.config's location tag referring to A protected void btn1_Click(object sender, EventArgs e) { doThings(); } diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/B/EditProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/B/EditProfile.aspx.cs index 3e1e189d06e..4b7697f0f88 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/B/EditProfile.aspx.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/B/EditProfile.aspx.cs @@ -4,6 +4,7 @@ using System.Web.UI; class EditProfile4 : System.Web.UI.Page { private void doThings() { } + // BAD: The Web.config file does not specify auth for this path. protected void btn1_Click(object sender, EventArgs e) { doThings(); } diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/C/EditProfile.aspx.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/C/EditProfile.aspx.cs index 81d2a1f0d8b..a8ad0654689 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/C/EditProfile.aspx.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/Test3/C/EditProfile.aspx.cs @@ -4,6 +4,7 @@ using System.Web.UI; class EditProfile5 : System.Web.UI.Page { private void doThings() { } + // GOOD: The Web.config file specifies auth for the path Virtual, which is mapped to C in Global.asax protected void btn1_Click(object sender, EventArgs e) { doThings(); } From 52841e9005af1725d9afb83a4ddb8ecbda538f5b Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 22 Jun 2023 11:30:58 +0100 Subject: [PATCH 017/118] Apply review suggestions - minor fixes --- .../security/auth/MissingFunctionLevelAccessControlQuery.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll index 982afd63f4b..e8ce588c364 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll @@ -46,12 +46,12 @@ private class MvcActionMethod extends ActionMethod { /** An action method on a subclass of `System.Web.UI.Page`. */ private class WebFormActionMethod extends ActionMethod { WebFormActionMethod() { - this.getDeclaringType().getBaseClass*() instanceof SystemWebUIPageClass and + this.getDeclaringType().getBaseClass+() instanceof SystemWebUIPageClass and this.getAParameter().getType().getName().matches("%EventArgs") } override Callable getAnAuthorizingCallable() { - result = this + result = super.getAnAuthorizingCallable() or result.getDeclaringType() = this.getDeclaringType() and result.getName() = "Page_Load" From 7a3b6f107b46bc8f827811b2394eb29e458e9449 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Tue, 13 Jun 2023 11:38:23 +0100 Subject: [PATCH 018/118] Ruby: add predicates to DataFlow::ModuleNode to get singleton methods --- .../ruby/dataflow/internal/DataFlowPublic.qll | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll index a98238e85d9..0ae9bb691e9 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll @@ -1010,6 +1010,23 @@ class ModuleNode instanceof Module { */ MethodNode getAnInstanceMethod() { result = this.getInstanceMethod(_) } + /** + * Gets the singleton method named `name` available in this module, including methods inherited from ancestors. + * + * Overridden methods are not included. + */ + MethodNode getSingletonMethod(string name) { + result.asCallableAstNode() = super.getAnOwnSingletonMethod() and + result.getMethodName() = name + } + + /** + * Gets a singleton method available in this module, including methods inherited from ancestors. + * + * Overridden methods are not included. + */ + MethodNode getASingletonMethod() { result = this.getSingletonMethod(_) } + /** * Gets the enclosing module, as it appears in the qualified name of this module. * From 521e65c5bd1f9434f86f22d9cd05787e3b8cce74 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Tue, 13 Jun 2023 11:39:12 +0100 Subject: [PATCH 019/118] Ruby: rack - extend rack applications to include instance methods, lambdas, and procs --- .../actiondispatch/internal/Request.qll | 2 +- .../ruby/frameworks/rack/internal/App.qll | 93 +++++++++++++++++-- .../frameworks/rack/internal/Response.qll | 5 +- 3 files changed, 90 insertions(+), 10 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Request.qll b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Request.qll index 8c6a11b455b..e0f392fdb07 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Request.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Request.qll @@ -128,7 +128,7 @@ module Request { private import codeql.ruby.frameworks.Rack private class RackEnv extends Env { - RackEnv() { this = any(Rack::App::AppCandidate app).getEnv().getALocalUse() } + RackEnv() { this = any(Rack::App::App app).getEnv().getALocalUse() } } /** diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll index bfdd988ac19..cc268aafa94 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll @@ -7,19 +7,40 @@ private import codeql.ruby.DataFlow private import codeql.ruby.typetracking.TypeTracker private import Response::Private as RP -/** A method node for a method named `call`. */ -private class CallMethodNode extends DataFlow::MethodNode { - CallMethodNode() { this.getMethodName() = "call" } +/** + * A callable node that takes a single argument and, if it has a method name, + * is called "call". + */ +private class PotentialCallNode extends DataFlow::CallableNode { + PotentialCallNode() { + this.getNumberOfParameters() = 1 and + ( + this.(DataFlow::MethodNode).getMethodName() = "call" or + not this instanceof DataFlow::MethodNode + ) + } } -private DataFlow::LocalSourceNode trackRackResponse(TypeBackTracker t, CallMethodNode call) { +/** + * A callable node that looks like it implements the rack specification. + */ +private class CallNode extends PotentialCallNode { + private RP::PotentialResponseNode resp; + + CallNode() { resp = trackRackResponse(this) } + + /** Gets the response returned from a request to this application. */ + RP::PotentialResponseNode getResponse() { result = resp } +} + +private DataFlow::LocalSourceNode trackRackResponse(TypeBackTracker t, DataFlow::CallableNode call) { t.start() and result = call.getAReturnNode().getALocalSource() or exists(TypeBackTracker t2 | result = trackRackResponse(t2, call).backtrack(t2, t)) } -private RP::PotentialResponseNode trackRackResponse(CallMethodNode call) { +private RP::PotentialResponseNode trackRackResponse(DataFlow::CallableNode call) { result = trackRackResponse(TypeBackTracker::end(), call) } @@ -28,12 +49,13 @@ private RP::PotentialResponseNode trackRackResponse(CallMethodNode call) { */ module App { /** + * DEPRECATED: Use `App` instead. * A class that may be a rack application. * This is a class that has a `call` method that takes a single argument * (traditionally called `env`) and returns a rack-compatible response. */ - class AppCandidate extends DataFlow::ClassNode { - private CallMethodNode call; + deprecated class AppCandidate extends DataFlow::ClassNode { + private CallNode call; private RP::PotentialResponseNode resp; AppCandidate() { @@ -50,4 +72,61 @@ module App { /** Gets the response returned from a request to this application. */ RP::PotentialResponseNode getResponse() { result = resp } } + + private newtype TApp = + TClassApp(DataFlow::ClassNode cn, CallNode call) or + TAnonymousApp(CallNode call) + + /** + * A rack application. This is either some object that responds to `call` + * taking a single argument and returns a rack response, or a lambda or + * proc that takes a single `env` argument and returns a rack response. + */ + abstract class App extends TApp { + string toString() { result = "Rack application" } + + abstract CallNode getCall(); + + RP::PotentialResponseNode getResponse() { result = this.getCall().getResponse() } + + DataFlow::ParameterNode getEnv() { result = this.getCall().getParameter(0) } + } + + /** + * A rack application using a `DataFlow::ClassNode`. The class has either + * an instance method or a singleton method named "call" which takes a + * single `env` argument and returns a rack response. + */ + private class ClassApp extends TApp, App { + private DataFlow::ClassNode cn; + private CallNode call; + + ClassApp() { + this = TClassApp(cn, call) and + call = [cn.getInstanceMethod("call"), cn.getSingletonMethod("call")] + } + + override string toString() { result = "Rack application: " + cn.toString() } + + override CallNode getCall() { result = call } + } + + /** + * A rack application that is either a lambda or a proc, which takes a + * single `env` argument and returns a rack response. + */ + private class AnonymousApp extends TApp, App { + private CallNode call; + + AnonymousApp() { + this = TAnonymousApp(call) and + not exists(DataFlow::ClassNode cn | + call = [cn.getInstanceMethod(_), cn.getSingletonMethod(_)] + ) + } + + override string toString() { result = "Rack application: " + call.toString() } + + override CallNode getCall() { result = call } + } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll index 9d998c780ae..14bd45fe58d 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll @@ -58,8 +58,9 @@ module Public { } /** A `DataFlow::Node` returned from a rack request. */ - class ResponseNode extends Private::PotentialResponseNode, Http::Server::HttpResponse::Range { - ResponseNode() { this = any(A::App::AppCandidate app).getResponse() } + class ResponseNode extends Private::PotentialResponseNode, Http::Server::HttpResponse::Range + { + ResponseNode() { this = any(A::App::App app).getResponse() } override DataFlow::Node getBody() { result = this.getElement(2) } From 4d59181571bf3ad414462527f2bd72c56e0d7ecb Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Tue, 13 Jun 2023 11:45:02 +0100 Subject: [PATCH 020/118] Ruby: rack - Rack::Response#finish constructs a valid rack response --- .../frameworks/rack/internal/Response.qll | 49 ++++++++++++++++--- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll index 14bd45fe58d..53ba52648f0 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll @@ -13,15 +13,39 @@ private import App as A /** Contains implementation details for modeling `Rack::Response`. */ module Private { /** A `DataFlow::Node` that may be a rack response. This is detected heuristically, if something "looks like" a rack response syntactically then we consider it to be a potential response node. */ - class PotentialResponseNode extends DataFlow::ArrayLiteralNode { - // [status, headers, body] - PotentialResponseNode() { this.getNumberOfArguments() = 3 } - + abstract class PotentialResponseNode extends DataFlow::Node { /** Gets the headers returned with this response. */ - DataFlow::Node getHeaders() { result = this.getElement(1) } + abstract DataFlow::Node getHeaders(); /** Gets the body of this response. */ - DataFlow::Node getBody() { result = this.getElement(2) } + abstract DataFlow::Node getBody(); + } + + /** A rack response constructed directly using an array literal. */ + private class PotentialArrayResponse extends PotentialResponseNode, DataFlow::ArrayLiteralNode { + // [status, headers, body] + PotentialArrayResponse() { this.getNumberOfArguments() = 3 } + + override DataFlow::Node getHeaders() { result = this.getElement(1) } + + override DataFlow::Node getBody() { result = this.getElement(2) } + } + + /** A rack response constructed by calling `finish` on an instance of `Rack::Response`. */ + private class RackResponseConstruction extends PotentialResponseNode, DataFlow::CallNode { + private DataFlow::CallNode responseConstruction; + + // (body, status, headers) + RackResponseConstruction() { + responseConstruction = + API::getTopLevelMember("Rack").getMember("Response").getAnInstantiation() and + this = responseConstruction.getAMethodCall() and + this.getMethodName() = "finish" + } + + override DataFlow::Node getHeaders() { result = responseConstruction.getArgument(2) } + + override DataFlow::Node getBody() { result = responseConstruction.getArgument(0) } } } @@ -54,20 +78,29 @@ module Public { v.getStringlikeValue().toLowerCase() = headerName.toLowerCase() )) ) + or + // pair in a `Rack::Response.new` constructor + exists(DataFlow::PairNode headerPair | headerPair = headers | + headerPair.getKey().getConstantValue().getStringlikeValue().toLowerCase() = + headerName.toLowerCase() and + result = headerPair.getValue() + ) ) } /** A `DataFlow::Node` returned from a rack request. */ - class ResponseNode extends Private::PotentialResponseNode, Http::Server::HttpResponse::Range + class ResponseNode extends Http::Server::HttpResponse::Range instanceof Private::PotentialResponseNode { ResponseNode() { this = any(A::App::App app).getResponse() } - override DataFlow::Node getBody() { result = this.getElement(2) } + override DataFlow::Node getBody() { result = this.(Private::PotentialResponseNode).getBody() } override DataFlow::Node getMimetypeOrContentTypeArg() { result = getHeaderValue(this, "content-type") } + DataFlow::Node getHeaders() { result = this.(Private::PotentialResponseNode).getHeaders() } + // TODO: is there a sensible value for this? override string getMimetypeDefault() { none() } } From e8079727ee5548e48f05ab208dba4191b98201e2 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Tue, 13 Jun 2023 11:46:59 +0100 Subject: [PATCH 021/118] Ruby: rack - extend rack tests --- .../frameworks/rack/Rack.expected | 2 ++ .../library-tests/frameworks/rack/rack.rb | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.expected b/ruby/ql/test/library-tests/frameworks/rack/Rack.expected index c55afeb7801..82f2d4cc82e 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.expected +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.expected @@ -4,8 +4,10 @@ rackApps | rack.rb:24:1:37:3 | Logger | rack.rb:30:12:30:14 | env | | rack.rb:39:1:45:3 | Redirector | rack.rb:40:12:40:14 | env | | rack.rb:59:1:75:3 | Baz | rack.rb:60:12:60:14 | env | +| rack.rb:77:1:95:3 | Qux | rack.rb:79:17:79:19 | env | rackResponseContentTypes | rack.rb:8:5:8:38 | call to [] | rack.rb:7:34:7:45 | "text/plain" | | rack.rb:20:5:20:27 | call to [] | rack.rb:19:28:19:38 | "text/html" | redirectResponses | rack.rb:43:5:43:45 | call to [] | rack.rb:42:30:42:40 | "/foo.html" | +| rack.rb:93:5:93:78 | call to finish | rack.rb:93:60:93:70 | redirect_to | diff --git a/ruby/ql/test/library-tests/frameworks/rack/rack.rb b/ruby/ql/test/library-tests/frameworks/rack/rack.rb index 9f743496ad2..109016f018d 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/rack.rb +++ b/ruby/ql/test/library-tests/frameworks/rack/rack.rb @@ -73,3 +73,23 @@ class Baz [400, {}, "nope"] end end + +class Qux + attr_reader :env + def self.call(env) + new(env).call + end + + def initialize(env) + @env = env + end + + def call + do_redirect + end + + def do_redirect + redirect_to = env['redirect_to'] + Rack::Response.new(['redirecting'], 302, 'Location' => redirect_to).finish + end +end From b8f537a437d78bb0d4d3175390acfdabfa3bb74a Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Thu, 15 Jun 2023 13:23:09 +0100 Subject: [PATCH 022/118] Ruby: update rack tests --- .../frameworks/rack/Rack.expected | 16 +++++++---- .../library-tests/frameworks/rack/Rack.ql | 4 +-- .../frameworks/rack/rack_apps.rb | 28 +++++++++++++++++++ 3 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 ruby/ql/test/library-tests/frameworks/rack/rack_apps.rb diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.expected b/ruby/ql/test/library-tests/frameworks/rack/Rack.expected index 82f2d4cc82e..c268b463090 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.expected +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.expected @@ -1,10 +1,14 @@ rackApps -| rack.rb:1:1:10:3 | HelloWorld | rack.rb:2:12:2:14 | env | -| rack.rb:12:1:22:3 | Proxy | rack.rb:17:12:17:18 | the_env | -| rack.rb:24:1:37:3 | Logger | rack.rb:30:12:30:14 | env | -| rack.rb:39:1:45:3 | Redirector | rack.rb:40:12:40:14 | env | -| rack.rb:59:1:75:3 | Baz | rack.rb:60:12:60:14 | env | -| rack.rb:77:1:95:3 | Qux | rack.rb:79:17:79:19 | env | +| Rack application: -> { ... } | rack_apps.rb:21:17:21:19 | env | +| Rack application: Baz | rack.rb:60:12:60:14 | env | +| Rack application: ClassApp | rack_apps.rb:16:17:16:19 | env | +| Rack application: HelloWorld | rack.rb:2:12:2:14 | env | +| Rack application: InstanceApp | rack_apps.rb:6:12:6:14 | env | +| Rack application: Logger | rack.rb:30:12:30:14 | env | +| Rack application: Proxy | rack.rb:17:12:17:18 | the_env | +| Rack application: Qux | rack.rb:79:17:79:19 | env | +| Rack application: Redirector | rack.rb:40:12:40:14 | env | +| Rack application: { ... } | rack_apps.rb:23:24:23:26 | env | rackResponseContentTypes | rack.rb:8:5:8:38 | call to [] | rack.rb:7:34:7:45 | "text/plain" | | rack.rb:20:5:20:27 | call to [] | rack.rb:19:28:19:38 | "text/html" | diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql index 9b5d0629a9f..9e731ea2b4b 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql @@ -2,9 +2,7 @@ private import codeql.ruby.AST private import codeql.ruby.frameworks.Rack private import codeql.ruby.DataFlow -query predicate rackApps(Rack::App::AppCandidate c, DataFlow::ParameterNode env) { - env = c.getEnv() -} +query predicate rackApps(Rack::App::App app, DataFlow::ParameterNode env) { env = app.getEnv() } query predicate rackResponseContentTypes( Rack::Response::ResponseNode resp, DataFlow::Node contentType diff --git a/ruby/ql/test/library-tests/frameworks/rack/rack_apps.rb b/ruby/ql/test/library-tests/frameworks/rack/rack_apps.rb new file mode 100644 index 00000000000..716c33a3d28 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/rack/rack_apps.rb @@ -0,0 +1,28 @@ +require 'rack' +require 'rack/handler/puma' +handler = Rack::Handler::Puma + +class InstanceApp + def call(env) + status = 200 + headers = {} + body = ["instance app"] + resp = [status, headers, body] + resp + end +end + +class ClassApp + def self.call(env) + [200, {}, ["class app"]] + end +end + +lambda_app = ->(env) { [200, {}, ["lambda app"]] } + +proc_app = Proc.new { |env| [200, {}, ["proc app"]] } + +handler.run InstanceApp.new +handler.run ClassApp +handler.run lambda_app +handler.run proc_app From f8140bcad39b4b29db365f1d7d21f713ff87de2b Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Fri, 16 Jun 2023 17:06:29 +0100 Subject: [PATCH 023/118] Ruby: rack - improve performance of trackRackResponse --- .../ruby/frameworks/rack/internal/App.qll | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll index cc268aafa94..b8a7bb6520c 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll @@ -2,6 +2,7 @@ * Provides modeling for Rack applications. */ +private import codeql.ruby.AST private import codeql.ruby.ApiGraphs private import codeql.ruby.DataFlow private import codeql.ruby.typetracking.TypeTracker @@ -15,8 +16,18 @@ private class PotentialCallNode extends DataFlow::CallableNode { PotentialCallNode() { this.getNumberOfParameters() = 1 and ( - this.(DataFlow::MethodNode).getMethodName() = "call" or - not this instanceof DataFlow::MethodNode + this.(DataFlow::MethodNode).getMethodName() = "call" + or + not this instanceof DataFlow::MethodNode and + exists(DataFlow::CallNode cn | cn.getMethodName() = "run" | + this.(DataFlow::LocalSourceNode).flowsTo(cn.getArgument(0)) + or + // TODO: `Proc.new` should automatically propagate flow from its block argument + any(DataFlow::CallNode proc | + proc = API::getTopLevelMember("Proc").getAnInstantiation() and + proc.getBlock() = this + ).(DataFlow::LocalSourceNode).flowsTo(cn.getArgument(0)) + ) ) } } @@ -33,14 +44,14 @@ private class CallNode extends PotentialCallNode { RP::PotentialResponseNode getResponse() { result = resp } } -private DataFlow::LocalSourceNode trackRackResponse(TypeBackTracker t, DataFlow::CallableNode call) { +private DataFlow::LocalSourceNode trackRackResponse(TypeBackTracker t, PotentialCallNode call) { t.start() and result = call.getAReturnNode().getALocalSource() or exists(TypeBackTracker t2 | result = trackRackResponse(t2, call).backtrack(t2, t)) } -private RP::PotentialResponseNode trackRackResponse(DataFlow::CallableNode call) { +private RP::PotentialResponseNode trackRackResponse(PotentialCallNode call) { result = trackRackResponse(TypeBackTracker::end(), call) } From 3605269e13bc572651e4223c698c96b91dd23c54 Mon Sep 17 00:00:00 2001 From: Kevin Stubbings Date: Thu, 22 Jun 2023 22:16:28 -0700 Subject: [PATCH 024/118] Add webix copy function --- javascript/ql/lib/semmle/javascript/Extend.qll | 2 +- .../dataflow/PrototypePollutionCustomizations.qll | 2 +- .../PrototypePollutingMergeCall.expected | 10 ++++++++++ .../CWE-915/PrototypePollutingMergeCall/webix.js | 1 + 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/Extend.qll b/javascript/ql/lib/semmle/javascript/Extend.qll index 1b3204914ef..93f59e70c6a 100644 --- a/javascript/ql/lib/semmle/javascript/Extend.qll +++ b/javascript/ql/lib/semmle/javascript/Extend.qll @@ -97,7 +97,7 @@ private class ExtendCallDeep extends ExtendCall { callee = LodashUnderscore::member("mergeWith") or callee = LodashUnderscore::member("defaultsDeep") or callee = AngularJS::angular().getAPropertyRead("merge") or - callee = DataFlow::moduleImport("webix").getAPropertyRead("extend") + callee = DataFlow::moduleImport("webix").getAPropertyRead(["extend", "copy"]) ) } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutionCustomizations.qll index cc82792abf4..e3cce57add6 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutionCustomizations.qll @@ -173,7 +173,7 @@ module PrototypePollution { id = "angular" or call.isDeep() and - call = DataFlow::moduleImport("webix").getAMemberCall("extend") and + call = DataFlow::moduleImport("webix").getAMemberCall(["extend", "copy"]) and id = "webix" } } diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected index 4664d64a742..0699ba81815 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected @@ -23,6 +23,10 @@ nodes | webix.js:4:22:4:43 | JSON.pa ... t.data) | | webix.js:4:33:4:37 | event | | webix.js:4:33:4:42 | event.data | +| webix.js:5:19:5:40 | JSON.pa ... t.data) | +| webix.js:5:19:5:40 | JSON.pa ... t.data) | +| webix.js:5:30:5:34 | event | +| webix.js:5:30:5:39 | event.data | edges | angularmerge.js:1:30:1:34 | event | angularmerge.js:2:32:2:36 | event | | angularmerge.js:1:30:1:34 | event | angularmerge.js:2:32:2:36 | event | @@ -40,12 +44,18 @@ edges | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | | webix.js:3:30:3:34 | event | webix.js:4:33:4:37 | event | | webix.js:3:30:3:34 | event | webix.js:4:33:4:37 | event | +| webix.js:3:30:3:34 | event | webix.js:5:30:5:34 | event | +| webix.js:3:30:3:34 | event | webix.js:5:30:5:34 | event | | webix.js:4:33:4:37 | event | webix.js:4:33:4:42 | event.data | | webix.js:4:33:4:42 | event.data | webix.js:4:22:4:43 | JSON.pa ... t.data) | | webix.js:4:33:4:42 | event.data | webix.js:4:22:4:43 | JSON.pa ... t.data) | +| webix.js:5:30:5:34 | event | webix.js:5:30:5:39 | event.data | +| webix.js:5:30:5:39 | event.data | webix.js:5:19:5:40 | JSON.pa ... t.data) | +| webix.js:5:30:5:39 | event.data | webix.js:5:19:5:40 | JSON.pa ... t.data) | #select | angularmerge.js:2:21:2:42 | JSON.pa ... t.data) | angularmerge.js:1:30:1:34 | event | angularmerge.js:2:21:2:42 | JSON.pa ... t.data) | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | angularmerge.js:1:30:1:34 | event | user-controlled value | angularmerge.js:2:3:2:43 | angular ... .data)) | angular | | src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | user-controlled value | src-vulnerable-lodash/package.json:3:19:3:26 | "4.17.4" | lodash | | src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } | src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | user-controlled value | src-vulnerable-lodash/package.json:3:19:3:26 | "4.17.4" | lodash | | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | src-vulnerable-lodash/tst.js:15:14:15:28 | req.query.value | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | src-vulnerable-lodash/tst.js:15:14:15:28 | req.query.value | user-controlled value | src-vulnerable-lodash/package.json:3:19:3:26 | "4.17.4" | lodash | | webix.js:4:22:4:43 | JSON.pa ... t.data) | webix.js:3:30:3:34 | event | webix.js:4:22:4:43 | JSON.pa ... t.data) | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | webix.js:3:30:3:34 | event | user-controlled value | webix.js:4:5:4:44 | webix.e ... .data)) | webix | +| webix.js:5:19:5:40 | JSON.pa ... t.data) | webix.js:3:30:3:34 | event | webix.js:5:19:5:40 | JSON.pa ... t.data) | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | webix.js:3:30:3:34 | event | user-controlled value | webix.js:5:5:5:41 | webix.c ... .data)) | webix | diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix.js b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix.js index 85983bb0af7..2116b7d95c8 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix.js +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix.js @@ -2,4 +2,5 @@ import * as webix from "webix"; addEventListener("message", (event) => { webix.extend({}, JSON.parse(event.data)); // NOT OK + webix.copy({},JSON.parse(event.data)); // NOT OK }); From 4f9f41acd57ec93eb6fb21865f83077d8b28bfe4 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Fri, 23 Jun 2023 13:11:00 +0100 Subject: [PATCH 025/118] Ruby: rack - fix qldoc --- ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll | 4 ++++ ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll | 1 + 2 files changed, 5 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll index b8a7bb6520c..2cbd8b68d09 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll @@ -94,12 +94,16 @@ module App { * proc that takes a single `env` argument and returns a rack response. */ abstract class App extends TApp { + /** Gets a textual representation of this element. */ string toString() { result = "Rack application" } + /** Gets the `DataFlow::CallableNode` that will handle requests to this app. */ abstract CallNode getCall(); + /** Gets the response returned from a request to this app. */ RP::PotentialResponseNode getResponse() { result = this.getCall().getResponse() } + /** Gets the `env` parameter passed to this app when it handles a request. */ DataFlow::ParameterNode getEnv() { result = this.getCall().getParameter(0) } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll index 53ba52648f0..f6a67f3b73c 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll @@ -99,6 +99,7 @@ module Public { result = getHeaderValue(this, "content-type") } + /** Gets the headers returned with this response. */ DataFlow::Node getHeaders() { result = this.(Private::PotentialResponseNode).getHeaders() } // TODO: is there a sensible value for this? From 4b3d99529adc0e86e174b3c6d4dd7e6975519bae Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Fri, 23 Jun 2023 13:12:48 +0100 Subject: [PATCH 026/118] Ruby: rack - rename getResponse as getAResponse --- .../lib/codeql/ruby/frameworks/rack/internal/App.qll | 10 +++++----- .../codeql/ruby/frameworks/rack/internal/Response.qll | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll index 2cbd8b68d09..71a32883113 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll @@ -40,8 +40,8 @@ private class CallNode extends PotentialCallNode { CallNode() { resp = trackRackResponse(this) } - /** Gets the response returned from a request to this application. */ - RP::PotentialResponseNode getResponse() { result = resp } + /** Gets a response returned from a request to this application. */ + RP::PotentialResponseNode getAResponse() { result = resp } } private DataFlow::LocalSourceNode trackRackResponse(TypeBackTracker t, PotentialCallNode call) { @@ -82,7 +82,7 @@ module App { /** Gets the response returned from a request to this application. */ RP::PotentialResponseNode getResponse() { result = resp } - } +} private newtype TApp = TClassApp(DataFlow::ClassNode cn, CallNode call) or @@ -100,8 +100,8 @@ module App { /** Gets the `DataFlow::CallableNode` that will handle requests to this app. */ abstract CallNode getCall(); - /** Gets the response returned from a request to this app. */ - RP::PotentialResponseNode getResponse() { result = this.getCall().getResponse() } + /** Gets a response returned from a request to this app. */ + RP::PotentialResponseNode getAResponse() { result = this.getCall().getAResponse() } /** Gets the `env` parameter passed to this app when it handles a request. */ DataFlow::ParameterNode getEnv() { result = this.getCall().getParameter(0) } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll index f6a67f3b73c..f1c0ebfc317 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll @@ -91,7 +91,7 @@ module Public { /** A `DataFlow::Node` returned from a rack request. */ class ResponseNode extends Http::Server::HttpResponse::Range instanceof Private::PotentialResponseNode { - ResponseNode() { this = any(A::App::App app).getResponse() } + ResponseNode() { this = any(A::App::App app).getAResponse() } override DataFlow::Node getBody() { result = this.(Private::PotentialResponseNode).getBody() } From 29844e61e4eff378cd1fb24a0bb7bb7e85e55072 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Fri, 23 Jun 2023 13:16:04 +0100 Subject: [PATCH 027/118] Ruby: rack - test for response tracking --- .../frameworks/rack/Rack.expected | 21 ++++++++++--------- .../library-tests/frameworks/rack/Rack.ql | 6 +++++- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.expected b/ruby/ql/test/library-tests/frameworks/rack/Rack.expected index c268b463090..e18a7e30147 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.expected +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.expected @@ -1,14 +1,15 @@ rackApps -| Rack application: -> { ... } | rack_apps.rb:21:17:21:19 | env | -| Rack application: Baz | rack.rb:60:12:60:14 | env | -| Rack application: ClassApp | rack_apps.rb:16:17:16:19 | env | -| Rack application: HelloWorld | rack.rb:2:12:2:14 | env | -| Rack application: InstanceApp | rack_apps.rb:6:12:6:14 | env | -| Rack application: Logger | rack.rb:30:12:30:14 | env | -| Rack application: Proxy | rack.rb:17:12:17:18 | the_env | -| Rack application: Qux | rack.rb:79:17:79:19 | env | -| Rack application: Redirector | rack.rb:40:12:40:14 | env | -| Rack application: { ... } | rack_apps.rb:23:24:23:26 | env | +| Rack application: -> { ... } | rack_apps.rb:21:17:21:19 | env | rack_apps.rb:21:24:21:48 | call to [] | +| Rack application: Baz | rack.rb:60:12:60:14 | env | rack.rb:66:7:66:22 | call to [] | +| Rack application: Baz | rack.rb:60:12:60:14 | env | rack.rb:73:5:73:21 | call to [] | +| Rack application: ClassApp | rack_apps.rb:16:17:16:19 | env | rack_apps.rb:17:5:17:28 | call to [] | +| Rack application: HelloWorld | rack.rb:2:12:2:14 | env | rack.rb:8:5:8:38 | call to [] | +| Rack application: InstanceApp | rack_apps.rb:6:12:6:14 | env | rack_apps.rb:10:12:10:34 | call to [] | +| Rack application: Logger | rack.rb:30:12:30:14 | env | rack.rb:35:5:35:26 | call to [] | +| Rack application: Proxy | rack.rb:17:12:17:18 | the_env | rack.rb:20:5:20:27 | call to [] | +| Rack application: Qux | rack.rb:79:17:79:19 | env | rack.rb:93:5:93:78 | call to finish | +| Rack application: Redirector | rack.rb:40:12:40:14 | env | rack.rb:43:5:43:45 | call to [] | +| Rack application: { ... } | rack_apps.rb:23:24:23:26 | env | rack_apps.rb:23:29:23:51 | call to [] | rackResponseContentTypes | rack.rb:8:5:8:38 | call to [] | rack.rb:7:34:7:45 | "text/plain" | | rack.rb:20:5:20:27 | call to [] | rack.rb:19:28:19:38 | "text/html" | diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql index 9e731ea2b4b..26dd8e7063c 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql @@ -2,7 +2,11 @@ private import codeql.ruby.AST private import codeql.ruby.frameworks.Rack private import codeql.ruby.DataFlow -query predicate rackApps(Rack::App::App app, DataFlow::ParameterNode env) { env = app.getEnv() } +query predicate rackApps( + Rack::App::App app, DataFlow::ParameterNode env, Rack::Response::ResponseNode resp +) { + env = app.getEnv() and resp = app.getAResponse() +} query predicate rackResponseContentTypes( Rack::Response::ResponseNode resp, DataFlow::Node contentType From de6547341f6185d388a07d1c2648008487280986 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Fri, 23 Jun 2023 13:36:39 +0100 Subject: [PATCH 028/118] qlformat --- ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll index 71a32883113..8148befeb69 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll @@ -82,7 +82,7 @@ module App { /** Gets the response returned from a request to this application. */ RP::PotentialResponseNode getResponse() { result = resp } -} + } private newtype TApp = TClassApp(DataFlow::ClassNode cn, CallNode call) or From b67b80ca2a5d88a3ff993c1e27eb6f72b04221fb Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Fri, 23 Jun 2023 16:12:23 +0100 Subject: [PATCH 029/118] Ruby: rack - rename App as RackApplication --- .../frameworks/actiondispatch/internal/Request.qll | 2 +- .../lib/codeql/ruby/frameworks/rack/internal/App.qll | 10 +++++----- .../codeql/ruby/frameworks/rack/internal/Response.qll | 2 +- ruby/ql/test/library-tests/frameworks/rack/Rack.ql | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Request.qll b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Request.qll index e0f392fdb07..5a797092d97 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Request.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Request.qll @@ -128,7 +128,7 @@ module Request { private import codeql.ruby.frameworks.Rack private class RackEnv extends Env { - RackEnv() { this = any(Rack::App::App app).getEnv().getALocalUse() } + RackEnv() { this = any(Rack::App::RackApplication app).getEnv().getALocalUse() } } /** diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll index 8148befeb69..9516521d6c2 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll @@ -93,7 +93,7 @@ module App { * taking a single argument and returns a rack response, or a lambda or * proc that takes a single `env` argument and returns a rack response. */ - abstract class App extends TApp { + abstract class RackApplication extends TApp { /** Gets a textual representation of this element. */ string toString() { result = "Rack application" } @@ -112,11 +112,11 @@ module App { * an instance method or a singleton method named "call" which takes a * single `env` argument and returns a rack response. */ - private class ClassApp extends TApp, App { + private class ClassRackApplication extends TApp, RackApplication { private DataFlow::ClassNode cn; private CallNode call; - ClassApp() { + ClassRackApplication() { this = TClassApp(cn, call) and call = [cn.getInstanceMethod("call"), cn.getSingletonMethod("call")] } @@ -130,10 +130,10 @@ module App { * A rack application that is either a lambda or a proc, which takes a * single `env` argument and returns a rack response. */ - private class AnonymousApp extends TApp, App { + private class AnonymousRackApplication extends TApp, RackApplication { private CallNode call; - AnonymousApp() { + AnonymousRackApplication() { this = TAnonymousApp(call) and not exists(DataFlow::ClassNode cn | call = [cn.getInstanceMethod(_), cn.getSingletonMethod(_)] diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll index f1c0ebfc317..102897afd9b 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll @@ -91,7 +91,7 @@ module Public { /** A `DataFlow::Node` returned from a rack request. */ class ResponseNode extends Http::Server::HttpResponse::Range instanceof Private::PotentialResponseNode { - ResponseNode() { this = any(A::App::App app).getAResponse() } + ResponseNode() { this = any(A::App::RackApplication app).getAResponse() } override DataFlow::Node getBody() { result = this.(Private::PotentialResponseNode).getBody() } diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql index 26dd8e7063c..05df40fcd61 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql @@ -3,7 +3,7 @@ private import codeql.ruby.frameworks.Rack private import codeql.ruby.DataFlow query predicate rackApps( - Rack::App::App app, DataFlow::ParameterNode env, Rack::Response::ResponseNode resp + Rack::App::RackApplication app, DataFlow::ParameterNode env, Rack::Response::ResponseNode resp ) { env = app.getEnv() and resp = app.getAResponse() } From 6008c7bee4e263a483385a6e4eff293306ed5e3d Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Fri, 23 Jun 2023 16:16:15 +0100 Subject: [PATCH 030/118] Ruby: rack - change note for response and app recognition improvements --- ruby/ql/lib/change-notes/2023-06-23-rack-response.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 ruby/ql/lib/change-notes/2023-06-23-rack-response.md diff --git a/ruby/ql/lib/change-notes/2023-06-23-rack-response.md b/ruby/ql/lib/change-notes/2023-06-23-rack-response.md new file mode 100644 index 00000000000..d4bc2ca7419 --- /dev/null +++ b/ruby/ql/lib/change-notes/2023-06-23-rack-response.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* More kinds of rack applications are now recognized. +* Rack::Response instances are now recognized as potential responses from rack applications. From b2d54842a6cedd7b96c0aa88a895233638a581f7 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 23 Jun 2023 17:00:52 +0100 Subject: [PATCH 031/118] Apply review suggestion Co-authored-by: Michael Nebel --- .../security/auth/MissingFunctionLevelAccessControlQuery.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll index e8ce588c364..7623cb6b9f7 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/auth/MissingFunctionLevelAccessControlQuery.qll @@ -92,7 +92,7 @@ private predicate physicalRouteMatches(string route, string actual) { route = actual or route.charAt(0) = "~" and - exists(string dir | actual = dir + route.substring(1, route.length()) + ".cs") + exists(string dir | actual = dir + route.suffix(1) + ".cs") } /** An expression that indicates that some authorization/authentication check is being performed. */ From 3c980db93aacab64084d77b2aa742482f04d44bf Mon Sep 17 00:00:00 2001 From: Jorge <46056498+jorgectf@users.noreply.github.com> Date: Fri, 23 Jun 2023 18:08:01 +0200 Subject: [PATCH 032/118] Format `webix.js` --- .../Security/CWE-915/PrototypePollutingMergeCall/webix.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix.js b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix.js index 2116b7d95c8..acbfa2acbb4 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix.js +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix.js @@ -2,5 +2,5 @@ import * as webix from "webix"; addEventListener("message", (event) => { webix.extend({}, JSON.parse(event.data)); // NOT OK - webix.copy({},JSON.parse(event.data)); // NOT OK + webix.copy({}, JSON.parse(event.data)); // NOT OK }); From 08b9a5e2b20f32d24fea22f03469a7dc047d5914 Mon Sep 17 00:00:00 2001 From: Jorge <46056498+jorgectf@users.noreply.github.com> Date: Fri, 23 Jun 2023 23:10:06 +0200 Subject: [PATCH 033/118] Add missing `;` --- .../Security/CWE-094/CodeInjection/template-sinks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/template-sinks.js b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/template-sinks.js index 7c8e310cd1f..5b786cdeee4 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/template-sinks.js +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/template-sinks.js @@ -32,5 +32,5 @@ app.get('/some/path', function (req, res) { Eta.render(tainted); // NOT OK Sqrl.render(tainted); // NOT OK webix.ui({ template: tainted }); // NOT OK - webix.ui({ template: function () { return tainted } }) // NOT OK + webix.ui({ template: function () { return tainted } }); // NOT OK }); From 5bd044211ebcc76c7040ffbaa27be3ffcf3e9b20 Mon Sep 17 00:00:00 2001 From: Jorge <46056498+jorgectf@users.noreply.github.com> Date: Mon, 26 Jun 2023 13:27:23 +0200 Subject: [PATCH 034/118] Apply suggestions from code review Co-authored-by: Asger F --- .../dataflow/CodeInjectionCustomizations.qll | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll index 5d1a9bc2896..d4e62dba635 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll @@ -316,7 +316,7 @@ module CodeInjection { * A value interpreted as code by the `webix` library. */ class WebixExec extends Sink { - WebixExec() { this = DataFlow::moduleImport("webix").getAMemberCall("exec").getArgument(0) } + WebixExec() { this = API::moduleImport("webix").getMember("exec").getParameter(0).asSink() } } /** A sink for code injection via template injection. */ @@ -431,15 +431,15 @@ module CodeInjection { */ class WebixTemplateSink extends TemplateSink { WebixTemplateSink() { - this = DataFlow::moduleImport("webix").getAMemberCall("ui").getOptionArgument(0, "template") + this = API::moduleImport("webix").getMember("ui").getParameter(0).getMember("template").asSink() or this.asExpr() = - DataFlow::moduleImport("webix") - .getAMemberCall("ui") - .getOptionArgument(0, "template") - .asExpr() - .(Function) - .getAReturnedExpr() + API::moduleImport("webix") + .getMember("ui") + .getParameter(0) + .getMember("template") + .getReturn() + .asSink() } } From bb67a9000ef672573c30d40db425e77ff03bcfc1 Mon Sep 17 00:00:00 2001 From: jorgectf Date: Mon, 26 Jun 2023 13:32:00 +0200 Subject: [PATCH 035/118] Fix `WebixTemplateSink` --- .../security/dataflow/CodeInjectionCustomizations.qll | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll index d4e62dba635..fcaabbeaf42 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll @@ -431,9 +431,10 @@ module CodeInjection { */ class WebixTemplateSink extends TemplateSink { WebixTemplateSink() { - this = API::moduleImport("webix").getMember("ui").getParameter(0).getMember("template").asSink() + this = + API::moduleImport("webix").getMember("ui").getParameter(0).getMember("template").asSink() or - this.asExpr() = + this = API::moduleImport("webix") .getMember("ui") .getParameter(0) From 1e663b88895570eb513eefc685378c1abbda8e5e Mon Sep 17 00:00:00 2001 From: jorgectf Date: Mon, 26 Jun 2023 13:32:20 +0200 Subject: [PATCH 036/118] Update `HeuristicSourceCodeInjection.expected` --- .../HeuristicSourceCodeInjection.expected | 134 ++++++++++-------- 1 file changed, 73 insertions(+), 61 deletions(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected index be221820c07..729d3001937 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected @@ -116,37 +116,41 @@ nodes | react.js:10:56:10:77 | documen ... on.hash | | react.js:10:56:10:77 | documen ... on.hash | | react.js:10:56:10:77 | documen ... on.hash | -| template-sinks.js:17:9:17:31 | tainted | -| template-sinks.js:17:19:17:31 | req.query.foo | -| template-sinks.js:17:19:17:31 | req.query.foo | -| template-sinks.js:19:17:19:23 | tainted | -| template-sinks.js:19:17:19:23 | tainted | -| template-sinks.js:20:16:20:22 | tainted | -| template-sinks.js:20:16:20:22 | tainted | -| template-sinks.js:21:18:21:24 | tainted | -| template-sinks.js:21:18:21:24 | tainted | -| template-sinks.js:22:17:22:23 | tainted | -| template-sinks.js:22:17:22:23 | tainted | -| template-sinks.js:23:18:23:24 | tainted | -| template-sinks.js:23:18:23:24 | tainted | -| template-sinks.js:24:16:24:22 | tainted | -| template-sinks.js:24:16:24:22 | tainted | -| template-sinks.js:25:27:25:33 | tainted | -| template-sinks.js:25:27:25:33 | tainted | -| template-sinks.js:26:21:26:27 | tainted | -| template-sinks.js:26:21:26:27 | tainted | -| template-sinks.js:27:17:27:23 | tainted | -| template-sinks.js:27:17:27:23 | tainted | -| template-sinks.js:28:24:28:30 | tainted | -| template-sinks.js:28:24:28:30 | tainted | -| template-sinks.js:29:21:29:27 | tainted | -| template-sinks.js:29:21:29:27 | tainted | -| template-sinks.js:30:19:30:25 | tainted | -| template-sinks.js:30:19:30:25 | tainted | -| template-sinks.js:31:16:31:22 | tainted | -| template-sinks.js:31:16:31:22 | tainted | -| template-sinks.js:32:17:32:23 | tainted | -| template-sinks.js:32:17:32:23 | tainted | +| template-sinks.js:18:9:18:31 | tainted | +| template-sinks.js:18:19:18:31 | req.query.foo | +| template-sinks.js:18:19:18:31 | req.query.foo | +| template-sinks.js:20:17:20:23 | tainted | +| template-sinks.js:20:17:20:23 | tainted | +| template-sinks.js:21:16:21:22 | tainted | +| template-sinks.js:21:16:21:22 | tainted | +| template-sinks.js:22:18:22:24 | tainted | +| template-sinks.js:22:18:22:24 | tainted | +| template-sinks.js:23:17:23:23 | tainted | +| template-sinks.js:23:17:23:23 | tainted | +| template-sinks.js:24:18:24:24 | tainted | +| template-sinks.js:24:18:24:24 | tainted | +| template-sinks.js:25:16:25:22 | tainted | +| template-sinks.js:25:16:25:22 | tainted | +| template-sinks.js:26:27:26:33 | tainted | +| template-sinks.js:26:27:26:33 | tainted | +| template-sinks.js:27:21:27:27 | tainted | +| template-sinks.js:27:21:27:27 | tainted | +| template-sinks.js:28:17:28:23 | tainted | +| template-sinks.js:28:17:28:23 | tainted | +| template-sinks.js:29:24:29:30 | tainted | +| template-sinks.js:29:24:29:30 | tainted | +| template-sinks.js:30:21:30:27 | tainted | +| template-sinks.js:30:21:30:27 | tainted | +| template-sinks.js:31:19:31:25 | tainted | +| template-sinks.js:31:19:31:25 | tainted | +| template-sinks.js:32:16:32:22 | tainted | +| template-sinks.js:32:16:32:22 | tainted | +| template-sinks.js:33:17:33:23 | tainted | +| template-sinks.js:33:17:33:23 | tainted | +| template-sinks.js:34:26:34:32 | tainted | +| template-sinks.js:34:26:34:32 | tainted | +| template-sinks.js:35:47:35:53 | tainted | +| template-sinks.js:35:47:35:53 | tainted | | tst.js:2:6:2:27 | documen ... on.href | | tst.js:2:6:2:27 | documen ... on.href | | tst.js:2:6:2:83 | documen ... t=")+8) | @@ -185,6 +189,9 @@ nodes | tst.js:35:28:35:33 | source | | tst.js:37:33:37:38 | source | | tst.js:37:33:37:38 | source | +| webix.js:3:12:3:33 | documen ... on.hash | +| webix.js:3:12:3:33 | documen ... on.hash | +| webix.js:3:12:3:33 | documen ... on.hash | edges | NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | | NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | @@ -254,36 +261,40 @@ edges | react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | | react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | | react.js:10:56:10:77 | documen ... on.hash | react.js:10:56:10:77 | documen ... on.hash | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:19:17:19:23 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:19:17:19:23 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:20:16:20:22 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:20:16:20:22 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:21:18:21:24 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:21:18:21:24 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:22:17:22:23 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:22:17:22:23 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:23:18:23:24 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:23:18:23:24 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:24:16:24:22 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:24:16:24:22 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:25:27:25:33 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:25:27:25:33 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:26:21:26:27 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:26:21:26:27 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:27:17:27:23 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:27:17:27:23 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:28:24:28:30 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:28:24:28:30 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:29:21:29:27 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:29:21:29:27 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:30:19:30:25 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:30:19:30:25 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:31:16:31:22 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:31:16:31:22 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:32:17:32:23 | tainted | -| template-sinks.js:17:9:17:31 | tainted | template-sinks.js:32:17:32:23 | tainted | -| template-sinks.js:17:19:17:31 | req.query.foo | template-sinks.js:17:9:17:31 | tainted | -| template-sinks.js:17:19:17:31 | req.query.foo | template-sinks.js:17:9:17:31 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:20:17:20:23 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:20:17:20:23 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:21:16:21:22 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:21:16:21:22 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:22:18:22:24 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:22:18:22:24 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:23:17:23:23 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:23:17:23:23 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:24:18:24:24 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:24:18:24:24 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:25:16:25:22 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:25:16:25:22 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:26:27:26:33 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:26:27:26:33 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:27:21:27:27 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:27:21:27:27 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:28:17:28:23 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:28:17:28:23 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:29:24:29:30 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:29:24:29:30 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:30:21:30:27 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:30:21:30:27 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:31:19:31:25 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:31:19:31:25 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:32:16:32:22 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:32:16:32:22 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:33:17:33:23 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:33:17:33:23 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:34:26:34:32 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:34:26:34:32 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:35:47:35:53 | tainted | +| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:35:47:35:53 | tainted | +| template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:18:9:18:31 | tainted | +| template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:18:9:18:31 | tainted | | tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | | tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | | tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | @@ -314,5 +325,6 @@ edges | tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") | | tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") | | tst.js:29:18:29:82 | documen ... , "$1") | tst.js:29:9:29:82 | source | +| webix.js:3:12:3:33 | documen ... on.hash | webix.js:3:12:3:33 | documen ... on.hash | #select | eslint-escope-build.js:21:16:21:16 | c | eslint-escope-build.js:20:22:20:22 | c | eslint-escope-build.js:21:16:21:16 | c | $@ flows to here and is interpreted as code. | eslint-escope-build.js:20:22:20:22 | c | User-provided value | From 8fdc48753c9dfd1b1418c4b98f6838a2e5bd3655 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Mon, 26 Jun 2023 14:49:32 +0100 Subject: [PATCH 037/118] Ruby: rack - replace RackApplication with just the rack RequestHandler --- .../ruby/dataflow/internal/DataFlowPublic.qll | 17 ---- .../actiondispatch/internal/Request.qll | 2 +- .../ruby/frameworks/rack/internal/App.qll | 84 +++---------------- .../frameworks/rack/internal/Response.qll | 2 +- .../frameworks/rack/Rack.expected | 24 +++--- .../library-tests/frameworks/rack/Rack.ql | 6 +- 6 files changed, 30 insertions(+), 105 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll index 0ae9bb691e9..a98238e85d9 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll @@ -1010,23 +1010,6 @@ class ModuleNode instanceof Module { */ MethodNode getAnInstanceMethod() { result = this.getInstanceMethod(_) } - /** - * Gets the singleton method named `name` available in this module, including methods inherited from ancestors. - * - * Overridden methods are not included. - */ - MethodNode getSingletonMethod(string name) { - result.asCallableAstNode() = super.getAnOwnSingletonMethod() and - result.getMethodName() = name - } - - /** - * Gets a singleton method available in this module, including methods inherited from ancestors. - * - * Overridden methods are not included. - */ - MethodNode getASingletonMethod() { result = this.getSingletonMethod(_) } - /** * Gets the enclosing module, as it appears in the qualified name of this module. * diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Request.qll b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Request.qll index 5a797092d97..b24301b676d 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Request.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Request.qll @@ -128,7 +128,7 @@ module Request { private import codeql.ruby.frameworks.Rack private class RackEnv extends Env { - RackEnv() { this = any(Rack::App::RackApplication app).getEnv().getALocalUse() } + RackEnv() { this = any(Rack::App::RequestHandler handler).getEnv().getALocalUse() } } /** diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll index 9516521d6c2..e685e568357 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll @@ -12,8 +12,8 @@ private import Response::Private as RP * A callable node that takes a single argument and, if it has a method name, * is called "call". */ -private class PotentialCallNode extends DataFlow::CallableNode { - PotentialCallNode() { +private class PotentialRequestHandler extends DataFlow::CallableNode { + PotentialRequestHandler() { this.getNumberOfParameters() = 1 and ( this.(DataFlow::MethodNode).getMethodName() = "call" @@ -32,26 +32,14 @@ private class PotentialCallNode extends DataFlow::CallableNode { } } -/** - * A callable node that looks like it implements the rack specification. - */ -private class CallNode extends PotentialCallNode { - private RP::PotentialResponseNode resp; - - CallNode() { resp = trackRackResponse(this) } - - /** Gets a response returned from a request to this application. */ - RP::PotentialResponseNode getAResponse() { result = resp } -} - -private DataFlow::LocalSourceNode trackRackResponse(TypeBackTracker t, PotentialCallNode call) { +private DataFlow::LocalSourceNode trackRackResponse(TypeBackTracker t, PotentialRequestHandler call) { t.start() and result = call.getAReturnNode().getALocalSource() or exists(TypeBackTracker t2 | result = trackRackResponse(t2, call).backtrack(t2, t)) } -private RP::PotentialResponseNode trackRackResponse(PotentialCallNode call) { +private RP::PotentialResponseNode trackRackResponse(PotentialRequestHandler call) { result = trackRackResponse(TypeBackTracker::end(), call) } @@ -66,7 +54,7 @@ module App { * (traditionally called `env`) and returns a rack-compatible response. */ deprecated class AppCandidate extends DataFlow::ClassNode { - private CallNode call; + private RequestHandler call; private RP::PotentialResponseNode resp; AppCandidate() { @@ -84,64 +72,18 @@ module App { RP::PotentialResponseNode getResponse() { result = resp } } - private newtype TApp = - TClassApp(DataFlow::ClassNode cn, CallNode call) or - TAnonymousApp(CallNode call) - /** - * A rack application. This is either some object that responds to `call` - * taking a single argument and returns a rack response, or a lambda or - * proc that takes a single `env` argument and returns a rack response. + * A callable node that looks like it implements the rack specification. */ - abstract class RackApplication extends TApp { - /** Gets a textual representation of this element. */ - string toString() { result = "Rack application" } + class RequestHandler extends PotentialRequestHandler { + private RP::PotentialResponseNode resp; - /** Gets the `DataFlow::CallableNode` that will handle requests to this app. */ - abstract CallNode getCall(); + RequestHandler() { resp = trackRackResponse(this) } - /** Gets a response returned from a request to this app. */ - RP::PotentialResponseNode getAResponse() { result = this.getCall().getAResponse() } + /** Gets the `env` parameter passed to this request handler. */ + DataFlow::ParameterNode getEnv() { result = this.getParameter(0) } - /** Gets the `env` parameter passed to this app when it handles a request. */ - DataFlow::ParameterNode getEnv() { result = this.getCall().getParameter(0) } - } - - /** - * A rack application using a `DataFlow::ClassNode`. The class has either - * an instance method or a singleton method named "call" which takes a - * single `env` argument and returns a rack response. - */ - private class ClassRackApplication extends TApp, RackApplication { - private DataFlow::ClassNode cn; - private CallNode call; - - ClassRackApplication() { - this = TClassApp(cn, call) and - call = [cn.getInstanceMethod("call"), cn.getSingletonMethod("call")] - } - - override string toString() { result = "Rack application: " + cn.toString() } - - override CallNode getCall() { result = call } - } - - /** - * A rack application that is either a lambda or a proc, which takes a - * single `env` argument and returns a rack response. - */ - private class AnonymousRackApplication extends TApp, RackApplication { - private CallNode call; - - AnonymousRackApplication() { - this = TAnonymousApp(call) and - not exists(DataFlow::ClassNode cn | - call = [cn.getInstanceMethod(_), cn.getSingletonMethod(_)] - ) - } - - override string toString() { result = "Rack application: " + call.toString() } - - override CallNode getCall() { result = call } + /** Gets a response returned from this request handler. */ + RP::PotentialResponseNode getAResponse() { result = resp } } } diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll index 102897afd9b..5f5b1601453 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll @@ -91,7 +91,7 @@ module Public { /** A `DataFlow::Node` returned from a rack request. */ class ResponseNode extends Http::Server::HttpResponse::Range instanceof Private::PotentialResponseNode { - ResponseNode() { this = any(A::App::RackApplication app).getAResponse() } + ResponseNode() { this = any(A::App::RequestHandler handler).getAResponse() } override DataFlow::Node getBody() { result = this.(Private::PotentialResponseNode).getBody() } diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.expected b/ruby/ql/test/library-tests/frameworks/rack/Rack.expected index e18a7e30147..01892a08dec 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.expected +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.expected @@ -1,15 +1,15 @@ -rackApps -| Rack application: -> { ... } | rack_apps.rb:21:17:21:19 | env | rack_apps.rb:21:24:21:48 | call to [] | -| Rack application: Baz | rack.rb:60:12:60:14 | env | rack.rb:66:7:66:22 | call to [] | -| Rack application: Baz | rack.rb:60:12:60:14 | env | rack.rb:73:5:73:21 | call to [] | -| Rack application: ClassApp | rack_apps.rb:16:17:16:19 | env | rack_apps.rb:17:5:17:28 | call to [] | -| Rack application: HelloWorld | rack.rb:2:12:2:14 | env | rack.rb:8:5:8:38 | call to [] | -| Rack application: InstanceApp | rack_apps.rb:6:12:6:14 | env | rack_apps.rb:10:12:10:34 | call to [] | -| Rack application: Logger | rack.rb:30:12:30:14 | env | rack.rb:35:5:35:26 | call to [] | -| Rack application: Proxy | rack.rb:17:12:17:18 | the_env | rack.rb:20:5:20:27 | call to [] | -| Rack application: Qux | rack.rb:79:17:79:19 | env | rack.rb:93:5:93:78 | call to finish | -| Rack application: Redirector | rack.rb:40:12:40:14 | env | rack.rb:43:5:43:45 | call to [] | -| Rack application: { ... } | rack_apps.rb:23:24:23:26 | env | rack_apps.rb:23:29:23:51 | call to [] | +rackRequestHandlers +| rack.rb:2:3:9:5 | call | rack.rb:2:12:2:14 | env | rack.rb:8:5:8:38 | call to [] | +| rack.rb:17:3:21:5 | call | rack.rb:17:12:17:18 | the_env | rack.rb:20:5:20:27 | call to [] | +| rack.rb:30:3:36:5 | call | rack.rb:30:12:30:14 | env | rack.rb:35:5:35:26 | call to [] | +| rack.rb:40:3:44:5 | call | rack.rb:40:12:40:14 | env | rack.rb:43:5:43:45 | call to [] | +| rack.rb:60:3:62:5 | call | rack.rb:60:12:60:14 | env | rack.rb:66:7:66:22 | call to [] | +| rack.rb:60:3:62:5 | call | rack.rb:60:12:60:14 | env | rack.rb:73:5:73:21 | call to [] | +| rack.rb:79:3:81:5 | call | rack.rb:79:17:79:19 | env | rack.rb:93:5:93:78 | call to finish | +| rack_apps.rb:6:3:12:5 | call | rack_apps.rb:6:12:6:14 | env | rack_apps.rb:10:12:10:34 | call to [] | +| rack_apps.rb:16:3:18:5 | call | rack_apps.rb:16:17:16:19 | env | rack_apps.rb:17:5:17:28 | call to [] | +| rack_apps.rb:21:14:21:50 | -> { ... } | rack_apps.rb:21:17:21:19 | env | rack_apps.rb:21:24:21:48 | call to [] | +| rack_apps.rb:23:21:23:53 | { ... } | rack_apps.rb:23:24:23:26 | env | rack_apps.rb:23:29:23:51 | call to [] | rackResponseContentTypes | rack.rb:8:5:8:38 | call to [] | rack.rb:7:34:7:45 | "text/plain" | | rack.rb:20:5:20:27 | call to [] | rack.rb:19:28:19:38 | "text/html" | diff --git a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql index 05df40fcd61..29b73b327fb 100644 --- a/ruby/ql/test/library-tests/frameworks/rack/Rack.ql +++ b/ruby/ql/test/library-tests/frameworks/rack/Rack.ql @@ -2,10 +2,10 @@ private import codeql.ruby.AST private import codeql.ruby.frameworks.Rack private import codeql.ruby.DataFlow -query predicate rackApps( - Rack::App::RackApplication app, DataFlow::ParameterNode env, Rack::Response::ResponseNode resp +query predicate rackRequestHandlers( + Rack::App::RequestHandler handler, DataFlow::ParameterNode env, Rack::Response::ResponseNode resp ) { - env = app.getEnv() and resp = app.getAResponse() + env = handler.getEnv() and resp = handler.getAResponse() } query predicate rackResponseContentTypes( From 9cf165ac55f377a4ddeceec46349b556da37a667 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Mon, 26 Jun 2023 15:37:34 +0100 Subject: [PATCH 038/118] Ruby: rack - update a deprecation notice --- ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll index e685e568357..748291f55bd 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll @@ -48,7 +48,7 @@ private RP::PotentialResponseNode trackRackResponse(PotentialRequestHandler call */ module App { /** - * DEPRECATED: Use `App` instead. + * DEPRECATED: Use `RequestHandler` instead. * A class that may be a rack application. * This is a class that has a `call` method that takes a single argument * (traditionally called `env`) and returns a rack-compatible response. From 938a9963223723910d09e423150d4b12d70b82cb Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 26 Jun 2023 15:57:57 +0100 Subject: [PATCH 039/118] Add test case for Authorize attribute --- .../MissingAccessControl/MVCTests/ProfileController.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/ProfileController.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/ProfileController.cs index d2ed864f4c7..e0d1d43ca48 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/ProfileController.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/ProfileController.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Authorization; public class ProfileController : Controller { private void doThings() { } @@ -18,4 +19,12 @@ public class ProfileController : Controller { doThings(); return View(); } + + // GOOD: The Authorize attribute is used. + [Authorize] + public ActionResult Delete3(int id) { + doThings() + return View(); + } + } \ No newline at end of file From 1d64d1297c32aabe6d043d0e810422bdd8ab7673 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 26 Jun 2023 16:51:07 +0100 Subject: [PATCH 040/118] Update tests to use stubs --- .../CWE-285/MissingAccessControl/WebFormsTests/options | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/options b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/options index 3c76fe5dc58..fb93d69d6b4 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/options +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/WebFormsTests/options @@ -1 +1,3 @@ -semmle-extractor-options: /r:System.Runtime.Extensions.dll /r:System.Collections.Specialized.dll ${testdir}/../../../../../resources/stubs/System.Web.cs \ No newline at end of file +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 From c419e8d24a608a853a627acb3c097b2468d1d193 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 26 Jun 2023 18:05:11 +0100 Subject: [PATCH 041/118] Fix test --- .../MissingAccessControl/MVCTests/MissingAccessControl.expected | 2 +- .../CWE-285/MissingAccessControl/MVCTests/ProfileController.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/MissingAccessControl.expected b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/MissingAccessControl.expected index 1ad8d1cdeb5..87fc29167be 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/MissingAccessControl.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/MissingAccessControl.expected @@ -1 +1 @@ -| ProfileController.cs:8:25:8:31 | Delete1 | This action is missing an authorization check. | +| ProfileController.cs:9:25:9:31 | Delete1 | This action is missing an authorization check. | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/ProfileController.cs b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/ProfileController.cs index e0d1d43ca48..39943dd4ce4 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/ProfileController.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-285/MissingAccessControl/MVCTests/ProfileController.cs @@ -23,7 +23,7 @@ public class ProfileController : Controller { // GOOD: The Authorize attribute is used. [Authorize] public ActionResult Delete3(int id) { - doThings() + doThings(); return View(); } From 2ac334bf15399f119a22d5fb5491a11b23ae21b1 Mon Sep 17 00:00:00 2001 From: jorgectf Date: Wed, 28 Jun 2023 15:26:30 +0200 Subject: [PATCH 042/118] Adapt `Webix` modeling to support HTML use-cases --- javascript/ql/lib/javascript.qll | 1 + .../ql/lib/semmle/javascript/Extend.qll | 4 +- .../semmle/javascript/frameworks/Webix.qll | 24 +++++++ .../dataflow/CodeInjectionCustomizations.qll | 12 +--- .../PrototypePollutionCustomizations.qll | 2 +- .../CodeInjection/CodeInjection.expected | 45 ++++++++----- .../HeuristicSourceCodeInjection.expected | 36 ++++++---- .../CWE-094/CodeInjection/template-sinks.js | 2 - .../Security/CWE-094/CodeInjection/webix.js | 3 - .../CWE-094/CodeInjection/webix/webix.html | 6 ++ .../CWE-094/CodeInjection/webix/webix.js | 5 ++ .../PrototypePollutingMergeCall.expected | 66 ++++++++++++------- .../webix/webix.html | 7 ++ .../{ => webix}/webix.js | 0 14 files changed, 148 insertions(+), 65 deletions(-) create mode 100644 javascript/ql/lib/semmle/javascript/frameworks/Webix.qll delete mode 100644 javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/webix.js create mode 100644 javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/webix/webix.html create mode 100644 javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/webix/webix.js create mode 100644 javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix/webix.html rename javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/{ => webix}/webix.js (100%) diff --git a/javascript/ql/lib/javascript.qll b/javascript/ql/lib/javascript.qll index ed38db6550e..07fb759bd65 100644 --- a/javascript/ql/lib/javascript.qll +++ b/javascript/ql/lib/javascript.qll @@ -134,6 +134,7 @@ import semmle.javascript.frameworks.TrustedTypes import semmle.javascript.frameworks.UriLibraries import semmle.javascript.frameworks.Vue import semmle.javascript.frameworks.Vuex +import semmle.javascript.frameworks.Webix import semmle.javascript.frameworks.WebSocket import semmle.javascript.frameworks.XmlParsers import semmle.javascript.frameworks.xUnit diff --git a/javascript/ql/lib/semmle/javascript/Extend.qll b/javascript/ql/lib/semmle/javascript/Extend.qll index 93f59e70c6a..d0eeade5892 100644 --- a/javascript/ql/lib/semmle/javascript/Extend.qll +++ b/javascript/ql/lib/semmle/javascript/Extend.qll @@ -97,7 +97,9 @@ private class ExtendCallDeep extends ExtendCall { callee = LodashUnderscore::member("mergeWith") or callee = LodashUnderscore::member("defaultsDeep") or callee = AngularJS::angular().getAPropertyRead("merge") or - callee = DataFlow::moduleImport("webix").getAPropertyRead(["extend", "copy"]) + callee = + [DataFlow::moduleImport("webix"), DataFlow::globalVarRef("webix")] + .getAPropertyRead(["extend", "copy"]) ) } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Webix.qll b/javascript/ql/lib/semmle/javascript/frameworks/Webix.qll new file mode 100644 index 00000000000..7dc36675ed0 --- /dev/null +++ b/javascript/ql/lib/semmle/javascript/frameworks/Webix.qll @@ -0,0 +1,24 @@ +/** + * Provides classes and predicates for working with the `webix` library. + */ + +private import javascript + +/** + * Provides classes and predicates for working with the `webix` library. + */ +module Webix { + /** The global variable `webix` as an entry point for API graphs. */ + private class WebixGlobalEntry extends API::EntryPoint { + WebixGlobalEntry() { this = "WebixGlobalEntry" } + + override DataFlow::SourceNode getASource() { result = DataFlow::globalVarRef("webix") } + } + + /** Gets a reference to the Webix package. */ + API::Node webix() { + result = API::moduleImport("webix") or + result.asSource() = DataFlow::moduleImport("webix") or + result = any(WebixGlobalEntry w).getANode() + } +} diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll index fcaabbeaf42..ce05747ec3f 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll @@ -316,7 +316,7 @@ module CodeInjection { * A value interpreted as code by the `webix` library. */ class WebixExec extends Sink { - WebixExec() { this = API::moduleImport("webix").getMember("exec").getParameter(0).asSink() } + WebixExec() { this = Webix::webix().getMember("exec").getParameter(0).asSink() } } /** A sink for code injection via template injection. */ @@ -431,16 +431,10 @@ module CodeInjection { */ class WebixTemplateSink extends TemplateSink { WebixTemplateSink() { - this = - API::moduleImport("webix").getMember("ui").getParameter(0).getMember("template").asSink() + this = Webix::webix().getMember("ui").getParameter(0).getMember("template").asSink() or this = - API::moduleImport("webix") - .getMember("ui") - .getParameter(0) - .getMember("template") - .getReturn() - .asSink() + Webix::webix().getMember("ui").getParameter(0).getMember("template").getReturn().asSink() } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutionCustomizations.qll index e3cce57add6..fdd1b5c1c88 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutionCustomizations.qll @@ -173,7 +173,7 @@ module PrototypePollution { id = "angular" or call.isDeep() and - call = DataFlow::moduleImport("webix").getAMemberCall(["extend", "copy"]) and + call = Webix::webix().getMember(["extend", "copy"]).getACall() and id = "webix" } } diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected index cc3175a3645..1193c5e33bc 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected @@ -143,10 +143,6 @@ nodes | template-sinks.js:32:16:32:22 | tainted | | template-sinks.js:33:17:33:23 | tainted | | template-sinks.js:33:17:33:23 | tainted | -| template-sinks.js:34:26:34:32 | tainted | -| template-sinks.js:34:26:34:32 | tainted | -| template-sinks.js:35:47:35:53 | tainted | -| template-sinks.js:35:47:35:53 | tainted | | tst.js:2:6:2:27 | documen ... on.href | | tst.js:2:6:2:27 | documen ... on.href | | tst.js:2:6:2:83 | documen ... t=")+8) | @@ -185,9 +181,24 @@ nodes | tst.js:35:28:35:33 | source | | tst.js:37:33:37:38 | source | | tst.js:37:33:37:38 | source | -| webix.js:3:12:3:33 | documen ... on.hash | -| webix.js:3:12:3:33 | documen ... on.hash | -| webix.js:3:12:3:33 | documen ... on.hash | +| webix/webix.html:3:16:3:37 | documen ... on.hash | +| webix/webix.html:3:16:3:37 | documen ... on.hash | +| webix/webix.html:3:16:3:37 | documen ... on.hash | +| webix/webix.html:4:26:4:47 | documen ... on.hash | +| webix/webix.html:4:26:4:47 | documen ... on.hash | +| webix/webix.html:4:26:4:47 | documen ... on.hash | +| webix/webix.html:5:47:5:68 | documen ... on.hash | +| webix/webix.html:5:47:5:68 | documen ... on.hash | +| webix/webix.html:5:47:5:68 | documen ... on.hash | +| webix/webix.js:3:12:3:33 | documen ... on.hash | +| webix/webix.js:3:12:3:33 | documen ... on.hash | +| webix/webix.js:3:12:3:33 | documen ... on.hash | +| webix/webix.js:4:22:4:43 | documen ... on.hash | +| webix/webix.js:4:22:4:43 | documen ... on.hash | +| webix/webix.js:4:22:4:43 | documen ... on.hash | +| webix/webix.js:5:43:5:64 | documen ... on.hash | +| webix/webix.js:5:43:5:64 | documen ... on.hash | +| webix/webix.js:5:43:5:64 | documen ... on.hash | edges | NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | | NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | @@ -281,10 +292,6 @@ edges | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:32:16:32:22 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:33:17:33:23 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:33:17:33:23 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:34:26:34:32 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:34:26:34:32 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:35:47:35:53 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:35:47:35:53 | tainted | | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:18:9:18:31 | tainted | | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:18:9:18:31 | tainted | | tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | @@ -317,7 +324,12 @@ edges | tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") | | tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") | | tst.js:29:18:29:82 | documen ... , "$1") | tst.js:29:9:29:82 | source | -| webix.js:3:12:3:33 | documen ... on.hash | webix.js:3:12:3:33 | documen ... on.hash | +| webix/webix.html:3:16:3:37 | documen ... on.hash | webix/webix.html:3:16:3:37 | documen ... on.hash | +| webix/webix.html:4:26:4:47 | documen ... on.hash | webix/webix.html:4:26:4:47 | documen ... on.hash | +| webix/webix.html:5:47:5:68 | documen ... on.hash | webix/webix.html:5:47:5:68 | documen ... on.hash | +| webix/webix.js:3:12:3:33 | documen ... on.hash | webix/webix.js:3:12:3:33 | documen ... on.hash | +| webix/webix.js:4:22:4:43 | documen ... on.hash | webix/webix.js:4:22:4:43 | documen ... on.hash | +| webix/webix.js:5:43:5:64 | documen ... on.hash | webix/webix.js:5:43:5:64 | documen ... on.hash | #select | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | This code execution depends on a $@. | NoSQLCodeInjection.js:18:24:18:31 | req.body | user-provided value | | NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | NoSQLCodeInjection.js:19:36:19:43 | req.body | NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | This code execution depends on a $@. | NoSQLCodeInjection.js:19:36:19:43 | req.body | user-provided value | @@ -366,8 +378,6 @@ edges | template-sinks.js:31:19:31:25 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:31:19:31:25 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | | template-sinks.js:32:16:32:22 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:32:16:32:22 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | | template-sinks.js:33:17:33:23 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:33:17:33:23 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | -| template-sinks.js:34:26:34:32 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:34:26:34:32 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | -| template-sinks.js:35:47:35:53 | tainted | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:35:47:35:53 | tainted | Template, which may contain code, depends on a $@. | template-sinks.js:18:19:18:31 | req.query.foo | user-provided value | | tst.js:2:6:2:83 | documen ... t=")+8) | tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | This code execution depends on a $@. | tst.js:2:6:2:27 | documen ... on.href | user-provided value | | tst.js:5:12:5:33 | documen ... on.hash | tst.js:5:12:5:33 | documen ... on.hash | tst.js:5:12:5:33 | documen ... on.hash | This code execution depends on a $@. | tst.js:5:12:5:33 | documen ... on.hash | user-provided value | | tst.js:14:10:14:74 | documen ... , "$1") | tst.js:14:10:14:33 | documen ... .search | tst.js:14:10:14:74 | documen ... , "$1") | This code execution depends on a $@. | tst.js:14:10:14:33 | documen ... .search | user-provided value | @@ -379,4 +389,9 @@ edges | tst.js:33:14:33:19 | source | tst.js:29:18:29:41 | documen ... .search | tst.js:33:14:33:19 | source | This code execution depends on a $@. | tst.js:29:18:29:41 | documen ... .search | user-provided value | | tst.js:35:28:35:33 | source | tst.js:29:18:29:41 | documen ... .search | tst.js:35:28:35:33 | source | This code execution depends on a $@. | tst.js:29:18:29:41 | documen ... .search | user-provided value | | tst.js:37:33:37:38 | source | tst.js:29:18:29:41 | documen ... .search | tst.js:37:33:37:38 | source | This code execution depends on a $@. | tst.js:29:18:29:41 | documen ... .search | user-provided value | -| webix.js:3:12:3:33 | documen ... on.hash | webix.js:3:12:3:33 | documen ... on.hash | webix.js:3:12:3:33 | documen ... on.hash | This code execution depends on a $@. | webix.js:3:12:3:33 | documen ... on.hash | user-provided value | +| webix/webix.html:3:16:3:37 | documen ... on.hash | webix/webix.html:3:16:3:37 | documen ... on.hash | webix/webix.html:3:16:3:37 | documen ... on.hash | This code execution depends on a $@. | webix/webix.html:3:16:3:37 | documen ... on.hash | user-provided value | +| webix/webix.html:4:26:4:47 | documen ... on.hash | webix/webix.html:4:26:4:47 | documen ... on.hash | webix/webix.html:4:26:4:47 | documen ... on.hash | Template, which may contain code, depends on a $@. | webix/webix.html:4:26:4:47 | documen ... on.hash | user-provided value | +| webix/webix.html:5:47:5:68 | documen ... on.hash | webix/webix.html:5:47:5:68 | documen ... on.hash | webix/webix.html:5:47:5:68 | documen ... on.hash | Template, which may contain code, depends on a $@. | webix/webix.html:5:47:5:68 | documen ... on.hash | user-provided value | +| webix/webix.js:3:12:3:33 | documen ... on.hash | webix/webix.js:3:12:3:33 | documen ... on.hash | webix/webix.js:3:12:3:33 | documen ... on.hash | This code execution depends on a $@. | webix/webix.js:3:12:3:33 | documen ... on.hash | user-provided value | +| webix/webix.js:4:22:4:43 | documen ... on.hash | webix/webix.js:4:22:4:43 | documen ... on.hash | webix/webix.js:4:22:4:43 | documen ... on.hash | Template, which may contain code, depends on a $@. | webix/webix.js:4:22:4:43 | documen ... on.hash | user-provided value | +| webix/webix.js:5:43:5:64 | documen ... on.hash | webix/webix.js:5:43:5:64 | documen ... on.hash | webix/webix.js:5:43:5:64 | documen ... on.hash | Template, which may contain code, depends on a $@. | webix/webix.js:5:43:5:64 | documen ... on.hash | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected index 729d3001937..7e4bd305955 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected @@ -147,10 +147,6 @@ nodes | template-sinks.js:32:16:32:22 | tainted | | template-sinks.js:33:17:33:23 | tainted | | template-sinks.js:33:17:33:23 | tainted | -| template-sinks.js:34:26:34:32 | tainted | -| template-sinks.js:34:26:34:32 | tainted | -| template-sinks.js:35:47:35:53 | tainted | -| template-sinks.js:35:47:35:53 | tainted | | tst.js:2:6:2:27 | documen ... on.href | | tst.js:2:6:2:27 | documen ... on.href | | tst.js:2:6:2:83 | documen ... t=")+8) | @@ -189,9 +185,24 @@ nodes | tst.js:35:28:35:33 | source | | tst.js:37:33:37:38 | source | | tst.js:37:33:37:38 | source | -| webix.js:3:12:3:33 | documen ... on.hash | -| webix.js:3:12:3:33 | documen ... on.hash | -| webix.js:3:12:3:33 | documen ... on.hash | +| webix/webix.html:3:16:3:37 | documen ... on.hash | +| webix/webix.html:3:16:3:37 | documen ... on.hash | +| webix/webix.html:3:16:3:37 | documen ... on.hash | +| webix/webix.html:4:26:4:47 | documen ... on.hash | +| webix/webix.html:4:26:4:47 | documen ... on.hash | +| webix/webix.html:4:26:4:47 | documen ... on.hash | +| webix/webix.html:5:47:5:68 | documen ... on.hash | +| webix/webix.html:5:47:5:68 | documen ... on.hash | +| webix/webix.html:5:47:5:68 | documen ... on.hash | +| webix/webix.js:3:12:3:33 | documen ... on.hash | +| webix/webix.js:3:12:3:33 | documen ... on.hash | +| webix/webix.js:3:12:3:33 | documen ... on.hash | +| webix/webix.js:4:22:4:43 | documen ... on.hash | +| webix/webix.js:4:22:4:43 | documen ... on.hash | +| webix/webix.js:4:22:4:43 | documen ... on.hash | +| webix/webix.js:5:43:5:64 | documen ... on.hash | +| webix/webix.js:5:43:5:64 | documen ... on.hash | +| webix/webix.js:5:43:5:64 | documen ... on.hash | edges | NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | | NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | @@ -289,10 +300,6 @@ edges | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:32:16:32:22 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:33:17:33:23 | tainted | | template-sinks.js:18:9:18:31 | tainted | template-sinks.js:33:17:33:23 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:34:26:34:32 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:34:26:34:32 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:35:47:35:53 | tainted | -| template-sinks.js:18:9:18:31 | tainted | template-sinks.js:35:47:35:53 | tainted | | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:18:9:18:31 | tainted | | template-sinks.js:18:19:18:31 | req.query.foo | template-sinks.js:18:9:18:31 | tainted | | tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | @@ -325,6 +332,11 @@ edges | tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") | | tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") | | tst.js:29:18:29:82 | documen ... , "$1") | tst.js:29:9:29:82 | source | -| webix.js:3:12:3:33 | documen ... on.hash | webix.js:3:12:3:33 | documen ... on.hash | +| webix/webix.html:3:16:3:37 | documen ... on.hash | webix/webix.html:3:16:3:37 | documen ... on.hash | +| webix/webix.html:4:26:4:47 | documen ... on.hash | webix/webix.html:4:26:4:47 | documen ... on.hash | +| webix/webix.html:5:47:5:68 | documen ... on.hash | webix/webix.html:5:47:5:68 | documen ... on.hash | +| webix/webix.js:3:12:3:33 | documen ... on.hash | webix/webix.js:3:12:3:33 | documen ... on.hash | +| webix/webix.js:4:22:4:43 | documen ... on.hash | webix/webix.js:4:22:4:43 | documen ... on.hash | +| webix/webix.js:5:43:5:64 | documen ... on.hash | webix/webix.js:5:43:5:64 | documen ... on.hash | #select | eslint-escope-build.js:21:16:21:16 | c | eslint-escope-build.js:20:22:20:22 | c | eslint-escope-build.js:21:16:21:16 | c | $@ flows to here and is interpreted as code. | eslint-escope-build.js:20:22:20:22 | c | User-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/template-sinks.js b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/template-sinks.js index 5b786cdeee4..51554663e4e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/template-sinks.js +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/template-sinks.js @@ -31,6 +31,4 @@ app.get('/some/path', function (req, res) { Hogan.compile(tainted); // NOT OK Eta.render(tainted); // NOT OK Sqrl.render(tainted); // NOT OK - webix.ui({ template: tainted }); // NOT OK - webix.ui({ template: function () { return tainted } }); // NOT OK }); diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/webix.js b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/webix.js deleted file mode 100644 index 289bffe22b4..00000000000 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/webix.js +++ /dev/null @@ -1,3 +0,0 @@ -import * as webix from 'webix'; - -webix.exec(document.location.hash); // NOT OK \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/webix/webix.html b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/webix/webix.html new file mode 100644 index 00000000000..3f62fd32621 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/webix/webix.html @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/webix/webix.js b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/webix/webix.js new file mode 100644 index 00000000000..00fb98af967 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/webix/webix.js @@ -0,0 +1,5 @@ +import * as webix from 'webix'; + +webix.exec(document.location.hash); // NOT OK +webix.ui({ template: document.location.hash }); // NOT OK +webix.ui({ template: function () { return document.location.hash } }); // NOT OK \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected index 0699ba81815..a697bd24760 100644 --- a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/PrototypePollutingMergeCall.expected @@ -17,16 +17,26 @@ nodes | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | -| webix.js:3:30:3:34 | event | -| webix.js:3:30:3:34 | event | -| webix.js:4:22:4:43 | JSON.pa ... t.data) | -| webix.js:4:22:4:43 | JSON.pa ... t.data) | -| webix.js:4:33:4:37 | event | -| webix.js:4:33:4:42 | event.data | -| webix.js:5:19:5:40 | JSON.pa ... t.data) | -| webix.js:5:19:5:40 | JSON.pa ... t.data) | -| webix.js:5:30:5:34 | event | -| webix.js:5:30:5:39 | event.data | +| webix/webix.html:3:34:3:38 | event | +| webix/webix.html:3:34:3:38 | event | +| webix/webix.html:4:26:4:47 | JSON.pa ... t.data) | +| webix/webix.html:4:26:4:47 | JSON.pa ... t.data) | +| webix/webix.html:4:37:4:41 | event | +| webix/webix.html:4:37:4:46 | event.data | +| webix/webix.html:5:24:5:45 | JSON.pa ... t.data) | +| webix/webix.html:5:24:5:45 | JSON.pa ... t.data) | +| webix/webix.html:5:35:5:39 | event | +| webix/webix.html:5:35:5:44 | event.data | +| webix/webix.js:3:30:3:34 | event | +| webix/webix.js:3:30:3:34 | event | +| webix/webix.js:4:22:4:43 | JSON.pa ... t.data) | +| webix/webix.js:4:22:4:43 | JSON.pa ... t.data) | +| webix/webix.js:4:33:4:37 | event | +| webix/webix.js:4:33:4:42 | event.data | +| webix/webix.js:5:20:5:41 | JSON.pa ... t.data) | +| webix/webix.js:5:20:5:41 | JSON.pa ... t.data) | +| webix/webix.js:5:31:5:35 | event | +| webix/webix.js:5:31:5:40 | event.data | edges | angularmerge.js:1:30:1:34 | event | angularmerge.js:2:32:2:36 | event | | angularmerge.js:1:30:1:34 | event | angularmerge.js:2:32:2:36 | event | @@ -42,20 +52,32 @@ edges | src-vulnerable-lodash/tst.js:15:14:15:28 | req.query.value | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | -| webix.js:3:30:3:34 | event | webix.js:4:33:4:37 | event | -| webix.js:3:30:3:34 | event | webix.js:4:33:4:37 | event | -| webix.js:3:30:3:34 | event | webix.js:5:30:5:34 | event | -| webix.js:3:30:3:34 | event | webix.js:5:30:5:34 | event | -| webix.js:4:33:4:37 | event | webix.js:4:33:4:42 | event.data | -| webix.js:4:33:4:42 | event.data | webix.js:4:22:4:43 | JSON.pa ... t.data) | -| webix.js:4:33:4:42 | event.data | webix.js:4:22:4:43 | JSON.pa ... t.data) | -| webix.js:5:30:5:34 | event | webix.js:5:30:5:39 | event.data | -| webix.js:5:30:5:39 | event.data | webix.js:5:19:5:40 | JSON.pa ... t.data) | -| webix.js:5:30:5:39 | event.data | webix.js:5:19:5:40 | JSON.pa ... t.data) | +| webix/webix.html:3:34:3:38 | event | webix/webix.html:4:37:4:41 | event | +| webix/webix.html:3:34:3:38 | event | webix/webix.html:4:37:4:41 | event | +| webix/webix.html:3:34:3:38 | event | webix/webix.html:5:35:5:39 | event | +| webix/webix.html:3:34:3:38 | event | webix/webix.html:5:35:5:39 | event | +| webix/webix.html:4:37:4:41 | event | webix/webix.html:4:37:4:46 | event.data | +| webix/webix.html:4:37:4:46 | event.data | webix/webix.html:4:26:4:47 | JSON.pa ... t.data) | +| webix/webix.html:4:37:4:46 | event.data | webix/webix.html:4:26:4:47 | JSON.pa ... t.data) | +| webix/webix.html:5:35:5:39 | event | webix/webix.html:5:35:5:44 | event.data | +| webix/webix.html:5:35:5:44 | event.data | webix/webix.html:5:24:5:45 | JSON.pa ... t.data) | +| webix/webix.html:5:35:5:44 | event.data | webix/webix.html:5:24:5:45 | JSON.pa ... t.data) | +| webix/webix.js:3:30:3:34 | event | webix/webix.js:4:33:4:37 | event | +| webix/webix.js:3:30:3:34 | event | webix/webix.js:4:33:4:37 | event | +| webix/webix.js:3:30:3:34 | event | webix/webix.js:5:31:5:35 | event | +| webix/webix.js:3:30:3:34 | event | webix/webix.js:5:31:5:35 | event | +| webix/webix.js:4:33:4:37 | event | webix/webix.js:4:33:4:42 | event.data | +| webix/webix.js:4:33:4:42 | event.data | webix/webix.js:4:22:4:43 | JSON.pa ... t.data) | +| webix/webix.js:4:33:4:42 | event.data | webix/webix.js:4:22:4:43 | JSON.pa ... t.data) | +| webix/webix.js:5:31:5:35 | event | webix/webix.js:5:31:5:40 | event.data | +| webix/webix.js:5:31:5:40 | event.data | webix/webix.js:5:20:5:41 | JSON.pa ... t.data) | +| webix/webix.js:5:31:5:40 | event.data | webix/webix.js:5:20:5:41 | JSON.pa ... t.data) | #select | angularmerge.js:2:21:2:42 | JSON.pa ... t.data) | angularmerge.js:1:30:1:34 | event | angularmerge.js:2:21:2:42 | JSON.pa ... t.data) | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | angularmerge.js:1:30:1:34 | event | user-controlled value | angularmerge.js:2:3:2:43 | angular ... .data)) | angular | | src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | user-controlled value | src-vulnerable-lodash/package.json:3:19:3:26 | "4.17.4" | lodash | | src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } | src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | user-controlled value | src-vulnerable-lodash/package.json:3:19:3:26 | "4.17.4" | lodash | | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | src-vulnerable-lodash/tst.js:15:14:15:28 | req.query.value | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | src-vulnerable-lodash/tst.js:15:14:15:28 | req.query.value | user-controlled value | src-vulnerable-lodash/package.json:3:19:3:26 | "4.17.4" | lodash | -| webix.js:4:22:4:43 | JSON.pa ... t.data) | webix.js:3:30:3:34 | event | webix.js:4:22:4:43 | JSON.pa ... t.data) | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | webix.js:3:30:3:34 | event | user-controlled value | webix.js:4:5:4:44 | webix.e ... .data)) | webix | -| webix.js:5:19:5:40 | JSON.pa ... t.data) | webix.js:3:30:3:34 | event | webix.js:5:19:5:40 | JSON.pa ... t.data) | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | webix.js:3:30:3:34 | event | user-controlled value | webix.js:5:5:5:41 | webix.c ... .data)) | webix | +| webix/webix.html:4:26:4:47 | JSON.pa ... t.data) | webix/webix.html:3:34:3:38 | event | webix/webix.html:4:26:4:47 | JSON.pa ... t.data) | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | webix/webix.html:3:34:3:38 | event | user-controlled value | webix/webix.html:4:9:4:48 | webix.e ... .data)) | webix | +| webix/webix.html:5:24:5:45 | JSON.pa ... t.data) | webix/webix.html:3:34:3:38 | event | webix/webix.html:5:24:5:45 | JSON.pa ... t.data) | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | webix/webix.html:3:34:3:38 | event | user-controlled value | webix/webix.html:5:9:5:46 | webix.c ... .data)) | webix | +| webix/webix.js:4:22:4:43 | JSON.pa ... t.data) | webix/webix.js:3:30:3:34 | event | webix/webix.js:4:22:4:43 | JSON.pa ... t.data) | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | webix/webix.js:3:30:3:34 | event | user-controlled value | webix/webix.js:4:5:4:44 | webix.e ... .data)) | webix | +| webix/webix.js:5:20:5:41 | JSON.pa ... t.data) | webix/webix.js:3:30:3:34 | event | webix/webix.js:5:20:5:41 | JSON.pa ... t.data) | Prototype pollution caused by merging a $@ using a vulnerable version of $@. | webix/webix.js:3:30:3:34 | event | user-controlled value | webix/webix.js:5:5:5:42 | webix.c ... .data)) | webix | diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix/webix.html b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix/webix.html new file mode 100644 index 00000000000..02d6d086d54 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix/webix.html @@ -0,0 +1,7 @@ + + \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix.js b/javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix/webix.js similarity index 100% rename from javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix.js rename to javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingMergeCall/webix/webix.js From 285112f4cd419bf5a1e65710e0c27a8c7ff1db58 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 27 Jun 2023 09:16:05 +0100 Subject: [PATCH 043/118] C++: Move 'cpp/overrun-write' back to medium precision. --- cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.ql b/cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.ql index a9af2d08f51..0d8648aac0a 100644 --- a/cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.ql +++ b/cpp/ql/src/Security/CWE/CWE-119/OverrunWriteProductFlow.ql @@ -5,7 +5,7 @@ * @kind path-problem * @problem.severity error * @security-severity 9.3 - * @precision low + * @precision medium * @id cpp/overrun-write * @tags reliability * security From 9d7987f82222c96dae1975874dd81d60a4861a1e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 29 Jun 2023 09:26:18 +0000 Subject: [PATCH 044/118] Release preparation for version 2.13.5 --- cpp/ql/lib/CHANGELOG.md | 4 ++++ cpp/ql/lib/change-notes/released/0.7.4.md | 3 +++ cpp/ql/lib/codeql-pack.release.yml | 2 +- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/CHANGELOG.md | 4 ++++ cpp/ql/src/change-notes/released/0.6.4.md | 3 +++ cpp/ql/src/codeql-pack.release.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md | 4 ++++ .../campaigns/Solorigate/lib/change-notes/released/1.5.4.md | 3 +++ csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/CHANGELOG.md | 4 ++++ .../campaigns/Solorigate/src/change-notes/released/1.5.4.md | 3 +++ csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/CHANGELOG.md | 4 ++++ csharp/ql/lib/change-notes/released/0.6.4.md | 3 +++ csharp/ql/lib/codeql-pack.release.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/CHANGELOG.md | 4 ++++ csharp/ql/src/change-notes/released/0.6.4.md | 3 +++ csharp/ql/src/codeql-pack.release.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/lib/CHANGELOG.md | 4 ++++ go/ql/lib/change-notes/released/0.5.4.md | 3 +++ go/ql/lib/codeql-pack.release.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/CHANGELOG.md | 4 ++++ go/ql/src/change-notes/released/0.5.4.md | 3 +++ go/ql/src/codeql-pack.release.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/CHANGELOG.md | 4 ++++ java/ql/lib/change-notes/released/0.6.4.md | 3 +++ java/ql/lib/codeql-pack.release.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/CHANGELOG.md | 4 ++++ java/ql/src/change-notes/released/0.6.4.md | 3 +++ java/ql/src/codeql-pack.release.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/CHANGELOG.md | 4 ++++ javascript/ql/lib/change-notes/released/0.6.4.md | 3 +++ javascript/ql/lib/codeql-pack.release.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/CHANGELOG.md | 4 ++++ javascript/ql/src/change-notes/released/0.6.4.md | 3 +++ javascript/ql/src/codeql-pack.release.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/CHANGELOG.md | 4 ++++ misc/suite-helpers/change-notes/released/0.5.4.md | 3 +++ misc/suite-helpers/codeql-pack.release.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/CHANGELOG.md | 4 ++++ python/ql/lib/change-notes/released/0.9.4.md | 3 +++ python/ql/lib/codeql-pack.release.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/CHANGELOG.md | 4 ++++ python/ql/src/change-notes/released/0.7.4.md | 3 +++ python/ql/src/codeql-pack.release.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/CHANGELOG.md | 4 ++++ ruby/ql/lib/change-notes/released/0.6.4.md | 3 +++ ruby/ql/lib/codeql-pack.release.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/CHANGELOG.md | 4 ++++ ruby/ql/src/change-notes/released/0.6.4.md | 3 +++ ruby/ql/src/codeql-pack.release.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- shared/regex/CHANGELOG.md | 4 ++++ shared/regex/change-notes/released/0.0.15.md | 3 +++ shared/regex/codeql-pack.release.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/CHANGELOG.md | 4 ++++ shared/ssa/change-notes/released/0.0.19.md | 3 +++ shared/ssa/codeql-pack.release.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/tutorial/CHANGELOG.md | 4 ++++ shared/tutorial/change-notes/released/0.0.12.md | 3 +++ shared/tutorial/codeql-pack.release.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typetracking/CHANGELOG.md | 4 ++++ shared/typetracking/change-notes/released/0.0.12.md | 3 +++ shared/typetracking/codeql-pack.release.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/CHANGELOG.md | 4 ++++ shared/typos/change-notes/released/0.0.19.md | 3 +++ shared/typos/codeql-pack.release.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/CHANGELOG.md | 4 ++++ shared/util/change-notes/released/0.0.12.md | 3 +++ shared/util/codeql-pack.release.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/yaml/CHANGELOG.md | 4 ++++ shared/yaml/change-notes/released/0.0.4.md | 3 +++ shared/yaml/codeql-pack.release.yml | 2 +- shared/yaml/qlpack.yml | 2 +- swift/ql/lib/CHANGELOG.md | 4 ++++ swift/ql/lib/change-notes/released/0.1.2.md | 3 +++ swift/ql/lib/codeql-pack.release.yml | 2 +- swift/ql/lib/qlpack.yml | 2 +- swift/ql/src/CHANGELOG.md | 4 ++++ swift/ql/src/change-notes/released/0.1.2.md | 3 +++ swift/ql/src/codeql-pack.release.yml | 2 +- swift/ql/src/qlpack.yml | 2 +- 104 files changed, 234 insertions(+), 52 deletions(-) create mode 100644 cpp/ql/lib/change-notes/released/0.7.4.md create mode 100644 cpp/ql/src/change-notes/released/0.6.4.md create mode 100644 csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.5.4.md create mode 100644 csharp/ql/campaigns/Solorigate/src/change-notes/released/1.5.4.md create mode 100644 csharp/ql/lib/change-notes/released/0.6.4.md create mode 100644 csharp/ql/src/change-notes/released/0.6.4.md create mode 100644 go/ql/lib/change-notes/released/0.5.4.md create mode 100644 go/ql/src/change-notes/released/0.5.4.md create mode 100644 java/ql/lib/change-notes/released/0.6.4.md create mode 100644 java/ql/src/change-notes/released/0.6.4.md create mode 100644 javascript/ql/lib/change-notes/released/0.6.4.md create mode 100644 javascript/ql/src/change-notes/released/0.6.4.md create mode 100644 misc/suite-helpers/change-notes/released/0.5.4.md create mode 100644 python/ql/lib/change-notes/released/0.9.4.md create mode 100644 python/ql/src/change-notes/released/0.7.4.md create mode 100644 ruby/ql/lib/change-notes/released/0.6.4.md create mode 100644 ruby/ql/src/change-notes/released/0.6.4.md create mode 100644 shared/regex/change-notes/released/0.0.15.md create mode 100644 shared/ssa/change-notes/released/0.0.19.md create mode 100644 shared/tutorial/change-notes/released/0.0.12.md create mode 100644 shared/typetracking/change-notes/released/0.0.12.md create mode 100644 shared/typos/change-notes/released/0.0.19.md create mode 100644 shared/util/change-notes/released/0.0.12.md create mode 100644 shared/yaml/change-notes/released/0.0.4.md create mode 100644 swift/ql/lib/change-notes/released/0.1.2.md create mode 100644 swift/ql/src/change-notes/released/0.1.2.md diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index e990e830005..615ceab066f 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.4 + +No user-facing changes. + ## 0.7.3 ### Minor Analysis Improvements diff --git a/cpp/ql/lib/change-notes/released/0.7.4.md b/cpp/ql/lib/change-notes/released/0.7.4.md new file mode 100644 index 00000000000..1b33df9cb1e --- /dev/null +++ b/cpp/ql/lib/change-notes/released/0.7.4.md @@ -0,0 +1,3 @@ +## 0.7.4 + +No user-facing changes. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index a4ea9c8de17..e388f34b4ec 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.3 +lastReleaseVersion: 0.7.4 diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 0065372f811..338a44230ad 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.7.4-dev +version: 0.7.4 groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index ca314dcd6d7..2f64242b90c 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.4 + +No user-facing changes. + ## 0.6.3 ### New Queries diff --git a/cpp/ql/src/change-notes/released/0.6.4.md b/cpp/ql/src/change-notes/released/0.6.4.md new file mode 100644 index 00000000000..7e98b0159fc --- /dev/null +++ b/cpp/ql/src/change-notes/released/0.6.4.md @@ -0,0 +1,3 @@ +## 0.6.4 + +No user-facing changes. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index b7dafe32c5d..ced8cf94614 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.3 +lastReleaseVersion: 0.6.4 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 077b34194fb..9fe8de41610 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.6.4-dev +version: 0.6.4 groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index b466881d9d7..1acc1f679bf 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.5.4 + +No user-facing changes. + ## 1.5.3 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.5.4.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.5.4.md new file mode 100644 index 00000000000..5ff5ac8ebb7 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.5.4.md @@ -0,0 +1,3 @@ +## 1.5.4 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index 232224b0e26..c216828ee1c 100644 --- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.5.3 +lastReleaseVersion: 1.5.4 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 5f8c63b8ea3..a3c749c973c 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.5.4-dev +version: 1.5.4 groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index b466881d9d7..1acc1f679bf 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.5.4 + +No user-facing changes. + ## 1.5.3 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.5.4.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.5.4.md new file mode 100644 index 00000000000..5ff5ac8ebb7 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.5.4.md @@ -0,0 +1,3 @@ +## 1.5.4 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index 232224b0e26..c216828ee1c 100644 --- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.5.3 +lastReleaseVersion: 1.5.4 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 65153d150f7..de3883ef605 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.5.4-dev +version: 1.5.4 groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index 8fc9f20a131..551d7ee2b8b 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.4 + +No user-facing changes. + ## 0.6.3 ### Major Analysis Improvements diff --git a/csharp/ql/lib/change-notes/released/0.6.4.md b/csharp/ql/lib/change-notes/released/0.6.4.md new file mode 100644 index 00000000000..7e98b0159fc --- /dev/null +++ b/csharp/ql/lib/change-notes/released/0.6.4.md @@ -0,0 +1,3 @@ +## 0.6.4 + +No user-facing changes. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index b7dafe32c5d..ced8cf94614 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.3 +lastReleaseVersion: 0.6.4 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 9ead1290662..6cc981f3901 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.6.4-dev +version: 0.6.4 groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index 8e82ab07313..ba01a4cd7d5 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.4 + +No user-facing changes. + ## 0.6.3 No user-facing changes. diff --git a/csharp/ql/src/change-notes/released/0.6.4.md b/csharp/ql/src/change-notes/released/0.6.4.md new file mode 100644 index 00000000000..7e98b0159fc --- /dev/null +++ b/csharp/ql/src/change-notes/released/0.6.4.md @@ -0,0 +1,3 @@ +## 0.6.4 + +No user-facing changes. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index b7dafe32c5d..ced8cf94614 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.3 +lastReleaseVersion: 0.6.4 diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 91cba09b8ac..6ee46bb7a94 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.6.4-dev +version: 0.6.4 groups: - csharp - queries diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index 0e0d00161e1..0e1ac53f289 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.4 + +No user-facing changes. + ## 0.5.3 No user-facing changes. diff --git a/go/ql/lib/change-notes/released/0.5.4.md b/go/ql/lib/change-notes/released/0.5.4.md new file mode 100644 index 00000000000..1686ab4354d --- /dev/null +++ b/go/ql/lib/change-notes/released/0.5.4.md @@ -0,0 +1,3 @@ +## 0.5.4 + +No user-facing changes. diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index 2164e038a5d..cd3f72e2513 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.5.3 +lastReleaseVersion: 0.5.4 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 0fe9af73882..5fd797f6176 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.5.4-dev +version: 0.5.4 groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index 61712c5e790..5acce410dbd 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.4 + +No user-facing changes. + ## 0.5.3 No user-facing changes. diff --git a/go/ql/src/change-notes/released/0.5.4.md b/go/ql/src/change-notes/released/0.5.4.md new file mode 100644 index 00000000000..1686ab4354d --- /dev/null +++ b/go/ql/src/change-notes/released/0.5.4.md @@ -0,0 +1,3 @@ +## 0.5.4 + +No user-facing changes. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index 2164e038a5d..cd3f72e2513 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.5.3 +lastReleaseVersion: 0.5.4 diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index ad8b0d5db16..e8b06b3fabf 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.5.4-dev +version: 0.5.4 groups: - go - queries diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 1056cefb86a..8c5b6fdcd9e 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.4 + +No user-facing changes. + ## 0.6.3 ### New Features diff --git a/java/ql/lib/change-notes/released/0.6.4.md b/java/ql/lib/change-notes/released/0.6.4.md new file mode 100644 index 00000000000..7e98b0159fc --- /dev/null +++ b/java/ql/lib/change-notes/released/0.6.4.md @@ -0,0 +1,3 @@ +## 0.6.4 + +No user-facing changes. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index b7dafe32c5d..ced8cf94614 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.3 +lastReleaseVersion: 0.6.4 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 81392376fd1..f7c9a607d33 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.6.4-dev +version: 0.6.4 groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 4852323b9b8..9107f8c044f 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.4 + +No user-facing changes. + ## 0.6.3 ### Minor Analysis Improvements diff --git a/java/ql/src/change-notes/released/0.6.4.md b/java/ql/src/change-notes/released/0.6.4.md new file mode 100644 index 00000000000..7e98b0159fc --- /dev/null +++ b/java/ql/src/change-notes/released/0.6.4.md @@ -0,0 +1,3 @@ +## 0.6.4 + +No user-facing changes. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index b7dafe32c5d..ced8cf94614 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.3 +lastReleaseVersion: 0.6.4 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index b75aea1c0a0..416e1007534 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.6.4-dev +version: 0.6.4 groups: - java - queries diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index 47c4130c3af..97c9fe20787 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.4 + +No user-facing changes. + ## 0.6.3 ### Major Analysis Improvements diff --git a/javascript/ql/lib/change-notes/released/0.6.4.md b/javascript/ql/lib/change-notes/released/0.6.4.md new file mode 100644 index 00000000000..7e98b0159fc --- /dev/null +++ b/javascript/ql/lib/change-notes/released/0.6.4.md @@ -0,0 +1,3 @@ +## 0.6.4 + +No user-facing changes. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index b7dafe32c5d..ced8cf94614 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.3 +lastReleaseVersion: 0.6.4 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 021a8719e54..95fcaa3e9e5 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.6.4-dev +version: 0.6.4 groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index 0194f6f1c4a..475c9ed092c 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.4 + +No user-facing changes. + ## 0.6.3 ### Minor Analysis Improvements diff --git a/javascript/ql/src/change-notes/released/0.6.4.md b/javascript/ql/src/change-notes/released/0.6.4.md new file mode 100644 index 00000000000..7e98b0159fc --- /dev/null +++ b/javascript/ql/src/change-notes/released/0.6.4.md @@ -0,0 +1,3 @@ +## 0.6.4 + +No user-facing changes. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index b7dafe32c5d..ced8cf94614 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.3 +lastReleaseVersion: 0.6.4 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index a1a1ed2b4f2..a39c1967877 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.6.4-dev +version: 0.6.4 groups: - javascript - queries diff --git a/misc/suite-helpers/CHANGELOG.md b/misc/suite-helpers/CHANGELOG.md index 9571c393549..78cd5a4e222 100644 --- a/misc/suite-helpers/CHANGELOG.md +++ b/misc/suite-helpers/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.4 + +No user-facing changes. + ## 0.5.3 No user-facing changes. diff --git a/misc/suite-helpers/change-notes/released/0.5.4.md b/misc/suite-helpers/change-notes/released/0.5.4.md new file mode 100644 index 00000000000..1686ab4354d --- /dev/null +++ b/misc/suite-helpers/change-notes/released/0.5.4.md @@ -0,0 +1,3 @@ +## 0.5.4 + +No user-facing changes. diff --git a/misc/suite-helpers/codeql-pack.release.yml b/misc/suite-helpers/codeql-pack.release.yml index 2164e038a5d..cd3f72e2513 100644 --- a/misc/suite-helpers/codeql-pack.release.yml +++ b/misc/suite-helpers/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.5.3 +lastReleaseVersion: 0.5.4 diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index f07f050124a..6f452066fa6 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,3 +1,3 @@ name: codeql/suite-helpers -version: 0.5.4-dev +version: 0.5.4 groups: shared diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index 3bfc2ddf115..4a27642ba5b 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.4 + +No user-facing changes. + ## 0.9.3 No user-facing changes. diff --git a/python/ql/lib/change-notes/released/0.9.4.md b/python/ql/lib/change-notes/released/0.9.4.md new file mode 100644 index 00000000000..092c14cb5d4 --- /dev/null +++ b/python/ql/lib/change-notes/released/0.9.4.md @@ -0,0 +1,3 @@ +## 0.9.4 + +No user-facing changes. diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index 7af7247cbb0..694907ca221 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.9.3 +lastReleaseVersion: 0.9.4 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index ff2c246a618..f24282bf699 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.9.4-dev +version: 0.9.4 groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index 655914b4a32..f6131409875 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.4 + +No user-facing changes. + ## 0.7.3 ### Bug Fixes diff --git a/python/ql/src/change-notes/released/0.7.4.md b/python/ql/src/change-notes/released/0.7.4.md new file mode 100644 index 00000000000..1b33df9cb1e --- /dev/null +++ b/python/ql/src/change-notes/released/0.7.4.md @@ -0,0 +1,3 @@ +## 0.7.4 + +No user-facing changes. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index a4ea9c8de17..e388f34b4ec 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.3 +lastReleaseVersion: 0.7.4 diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 7dd13516d8b..352afef47a7 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.7.4-dev +version: 0.7.4 groups: - python - queries diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index 5803375fd51..1bfe6b913c7 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.4 + +No user-facing changes. + ## 0.6.3 ### Minor Analysis Improvements diff --git a/ruby/ql/lib/change-notes/released/0.6.4.md b/ruby/ql/lib/change-notes/released/0.6.4.md new file mode 100644 index 00000000000..7e98b0159fc --- /dev/null +++ b/ruby/ql/lib/change-notes/released/0.6.4.md @@ -0,0 +1,3 @@ +## 0.6.4 + +No user-facing changes. diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index b7dafe32c5d..ced8cf94614 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.3 +lastReleaseVersion: 0.6.4 diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index d7c154febf3..98f917bc02c 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.6.4-dev +version: 0.6.4 groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index 8bc499539cb..db531529e74 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.4 + +No user-facing changes. + ## 0.6.3 ### Minor Analysis Improvements diff --git a/ruby/ql/src/change-notes/released/0.6.4.md b/ruby/ql/src/change-notes/released/0.6.4.md new file mode 100644 index 00000000000..7e98b0159fc --- /dev/null +++ b/ruby/ql/src/change-notes/released/0.6.4.md @@ -0,0 +1,3 @@ +## 0.6.4 + +No user-facing changes. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index b7dafe32c5d..ced8cf94614 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.3 +lastReleaseVersion: 0.6.4 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 6e1eb058cd4..50034ddfea5 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.6.4-dev +version: 0.6.4 groups: - ruby - queries diff --git a/shared/regex/CHANGELOG.md b/shared/regex/CHANGELOG.md index e45483b6d3c..2f5ce2ea5db 100644 --- a/shared/regex/CHANGELOG.md +++ b/shared/regex/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.15 + +No user-facing changes. + ## 0.0.14 No user-facing changes. diff --git a/shared/regex/change-notes/released/0.0.15.md b/shared/regex/change-notes/released/0.0.15.md new file mode 100644 index 00000000000..7af9c05f23f --- /dev/null +++ b/shared/regex/change-notes/released/0.0.15.md @@ -0,0 +1,3 @@ +## 0.0.15 + +No user-facing changes. diff --git a/shared/regex/codeql-pack.release.yml b/shared/regex/codeql-pack.release.yml index ca29e45d0a6..dff35216fc6 100644 --- a/shared/regex/codeql-pack.release.yml +++ b/shared/regex/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.14 +lastReleaseVersion: 0.0.15 diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 03c1586d407..fb5958d29fd 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 0.0.15-dev +version: 0.0.15 groups: shared library: true dependencies: diff --git a/shared/ssa/CHANGELOG.md b/shared/ssa/CHANGELOG.md index 41f9216baff..b5e659d15c3 100644 --- a/shared/ssa/CHANGELOG.md +++ b/shared/ssa/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.19 + +No user-facing changes. + ## 0.0.18 No user-facing changes. diff --git a/shared/ssa/change-notes/released/0.0.19.md b/shared/ssa/change-notes/released/0.0.19.md new file mode 100644 index 00000000000..914e4c9074d --- /dev/null +++ b/shared/ssa/change-notes/released/0.0.19.md @@ -0,0 +1,3 @@ +## 0.0.19 + +No user-facing changes. diff --git a/shared/ssa/codeql-pack.release.yml b/shared/ssa/codeql-pack.release.yml index a0d2bc59d97..f406319f372 100644 --- a/shared/ssa/codeql-pack.release.yml +++ b/shared/ssa/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.18 +lastReleaseVersion: 0.0.19 diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index c3fdb224479..b10d003f884 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 0.0.19-dev +version: 0.0.19 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/tutorial/CHANGELOG.md b/shared/tutorial/CHANGELOG.md index 28a38e6333b..546e2c83454 100644 --- a/shared/tutorial/CHANGELOG.md +++ b/shared/tutorial/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.12 + +No user-facing changes. + ## 0.0.11 No user-facing changes. diff --git a/shared/tutorial/change-notes/released/0.0.12.md b/shared/tutorial/change-notes/released/0.0.12.md new file mode 100644 index 00000000000..0e206033bc4 --- /dev/null +++ b/shared/tutorial/change-notes/released/0.0.12.md @@ -0,0 +1,3 @@ +## 0.0.12 + +No user-facing changes. diff --git a/shared/tutorial/codeql-pack.release.yml b/shared/tutorial/codeql-pack.release.yml index e679dc42092..997fb8da83c 100644 --- a/shared/tutorial/codeql-pack.release.yml +++ b/shared/tutorial/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.11 +lastReleaseVersion: 0.0.12 diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index 7dc19224a82..998e677c731 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,6 +1,6 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 0.0.12-dev +version: 0.0.12 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typetracking/CHANGELOG.md b/shared/typetracking/CHANGELOG.md index e87bb476477..155c9f11656 100644 --- a/shared/typetracking/CHANGELOG.md +++ b/shared/typetracking/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.12 + +No user-facing changes. + ## 0.0.11 No user-facing changes. diff --git a/shared/typetracking/change-notes/released/0.0.12.md b/shared/typetracking/change-notes/released/0.0.12.md new file mode 100644 index 00000000000..0e206033bc4 --- /dev/null +++ b/shared/typetracking/change-notes/released/0.0.12.md @@ -0,0 +1,3 @@ +## 0.0.12 + +No user-facing changes. diff --git a/shared/typetracking/codeql-pack.release.yml b/shared/typetracking/codeql-pack.release.yml index e679dc42092..997fb8da83c 100644 --- a/shared/typetracking/codeql-pack.release.yml +++ b/shared/typetracking/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.11 +lastReleaseVersion: 0.0.12 diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index 09ae3c23605..987916acfab 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 0.0.12-dev +version: 0.0.12 groups: shared library: true dependencies: diff --git a/shared/typos/CHANGELOG.md b/shared/typos/CHANGELOG.md index 9b3dcbace69..6a3b3161939 100644 --- a/shared/typos/CHANGELOG.md +++ b/shared/typos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.19 + +No user-facing changes. + ## 0.0.18 No user-facing changes. diff --git a/shared/typos/change-notes/released/0.0.19.md b/shared/typos/change-notes/released/0.0.19.md new file mode 100644 index 00000000000..914e4c9074d --- /dev/null +++ b/shared/typos/change-notes/released/0.0.19.md @@ -0,0 +1,3 @@ +## 0.0.19 + +No user-facing changes. diff --git a/shared/typos/codeql-pack.release.yml b/shared/typos/codeql-pack.release.yml index a0d2bc59d97..f406319f372 100644 --- a/shared/typos/codeql-pack.release.yml +++ b/shared/typos/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.18 +lastReleaseVersion: 0.0.19 diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index 65a104d1f01..b9cff555e5f 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 0.0.19-dev +version: 0.0.19 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/CHANGELOG.md b/shared/util/CHANGELOG.md index fe9befff25a..4bab5793788 100644 --- a/shared/util/CHANGELOG.md +++ b/shared/util/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.12 + +No user-facing changes. + ## 0.0.11 No user-facing changes. diff --git a/shared/util/change-notes/released/0.0.12.md b/shared/util/change-notes/released/0.0.12.md new file mode 100644 index 00000000000..0e206033bc4 --- /dev/null +++ b/shared/util/change-notes/released/0.0.12.md @@ -0,0 +1,3 @@ +## 0.0.12 + +No user-facing changes. diff --git a/shared/util/codeql-pack.release.yml b/shared/util/codeql-pack.release.yml index e679dc42092..997fb8da83c 100644 --- a/shared/util/codeql-pack.release.yml +++ b/shared/util/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.11 +lastReleaseVersion: 0.0.12 diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index 5dce17506ce..893b9e160f8 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 0.0.12-dev +version: 0.0.12 groups: shared library: true dependencies: diff --git a/shared/yaml/CHANGELOG.md b/shared/yaml/CHANGELOG.md index 390989ba76a..f2981af2aa0 100644 --- a/shared/yaml/CHANGELOG.md +++ b/shared/yaml/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.4 + +No user-facing changes. + ## 0.0.3 No user-facing changes. diff --git a/shared/yaml/change-notes/released/0.0.4.md b/shared/yaml/change-notes/released/0.0.4.md new file mode 100644 index 00000000000..eefe286a4d8 --- /dev/null +++ b/shared/yaml/change-notes/released/0.0.4.md @@ -0,0 +1,3 @@ +## 0.0.4 + +No user-facing changes. diff --git a/shared/yaml/codeql-pack.release.yml b/shared/yaml/codeql-pack.release.yml index a24b693d1e7..ec411a674bc 100644 --- a/shared/yaml/codeql-pack.release.yml +++ b/shared/yaml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.3 +lastReleaseVersion: 0.0.4 diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index ffbf802a8c4..962a76f8ce9 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 0.0.4-dev +version: 0.0.4 groups: shared library: true warnOnImplicitThis: true diff --git a/swift/ql/lib/CHANGELOG.md b/swift/ql/lib/CHANGELOG.md index 572ca004c63..fbd0cd1a9a1 100644 --- a/swift/ql/lib/CHANGELOG.md +++ b/swift/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.2 + +No user-facing changes. + ## 0.1.1 ### Major Analysis Improvements diff --git a/swift/ql/lib/change-notes/released/0.1.2.md b/swift/ql/lib/change-notes/released/0.1.2.md new file mode 100644 index 00000000000..9b0e2e7d717 --- /dev/null +++ b/swift/ql/lib/change-notes/released/0.1.2.md @@ -0,0 +1,3 @@ +## 0.1.2 + +No user-facing changes. diff --git a/swift/ql/lib/codeql-pack.release.yml b/swift/ql/lib/codeql-pack.release.yml index 92d1505475f..6abd14b1ef8 100644 --- a/swift/ql/lib/codeql-pack.release.yml +++ b/swift/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.1 +lastReleaseVersion: 0.1.2 diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index ccce91fd9c1..20b6a17a834 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 0.1.2-dev +version: 0.1.2 groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/CHANGELOG.md b/swift/ql/src/CHANGELOG.md index a682b626bb8..cfa79d360a4 100644 --- a/swift/ql/src/CHANGELOG.md +++ b/swift/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.2 + +No user-facing changes. + ## 0.1.1 ### Minor Analysis Improvements diff --git a/swift/ql/src/change-notes/released/0.1.2.md b/swift/ql/src/change-notes/released/0.1.2.md new file mode 100644 index 00000000000..9b0e2e7d717 --- /dev/null +++ b/swift/ql/src/change-notes/released/0.1.2.md @@ -0,0 +1,3 @@ +## 0.1.2 + +No user-facing changes. diff --git a/swift/ql/src/codeql-pack.release.yml b/swift/ql/src/codeql-pack.release.yml index 92d1505475f..6abd14b1ef8 100644 --- a/swift/ql/src/codeql-pack.release.yml +++ b/swift/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.1 +lastReleaseVersion: 0.1.2 diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index 9fac028053b..065f00e3a79 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 0.1.2-dev +version: 0.1.2 groups: - swift - queries From e210b0d0a7ad8df9fb792b38533bfff7828c48f0 Mon Sep 17 00:00:00 2001 From: Jorge <46056498+jorgectf@users.noreply.github.com> Date: Thu, 29 Jun 2023 16:06:34 +0200 Subject: [PATCH 045/118] Apply suggestions from code review Co-authored-by: Asger F --- javascript/ql/lib/semmle/javascript/frameworks/Webix.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Webix.qll b/javascript/ql/lib/semmle/javascript/frameworks/Webix.qll index 7dc36675ed0..effd49c632b 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Webix.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Webix.qll @@ -18,7 +18,6 @@ module Webix { /** Gets a reference to the Webix package. */ API::Node webix() { result = API::moduleImport("webix") or - result.asSource() = DataFlow::moduleImport("webix") or result = any(WebixGlobalEntry w).getANode() } } From 668aaa2dc80a3db2726346c158905e6e653975e9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 30 Jun 2023 08:51:48 +0000 Subject: [PATCH 046/118] Post-release preparation for codeql-cli-2.13.5 --- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/yaml/qlpack.yml | 2 +- swift/ql/lib/qlpack.yml | 2 +- swift/ql/src/qlpack.yml | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 338a44230ad..d92c7e5ee20 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.7.4 +version: 0.7.5-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 9fe8de41610..7872e9b16d1 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.6.4 +version: 0.6.5-dev groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index a3c749c973c..8bce120dbb0 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.5.4 +version: 1.5.5-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index de3883ef605..793257a494b 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.5.4 +version: 1.5.5-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 6cc981f3901..b09a68ee781 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.6.4 +version: 0.6.5-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 6ee46bb7a94..1f4ae8a3f47 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.6.4 +version: 0.6.5-dev groups: - csharp - queries diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 5fd797f6176..36e3b7154e8 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.5.4 +version: 0.5.5-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index e8b06b3fabf..c38121af910 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.5.4 +version: 0.5.5-dev groups: - go - queries diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index f7c9a607d33..dee9ae027a6 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.6.4 +version: 0.6.5-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 416e1007534..7dfc938e23f 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.6.4 +version: 0.6.5-dev groups: - java - queries diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 95fcaa3e9e5..4603d9330d9 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.6.4 +version: 0.6.5-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index a39c1967877..b5b41db1e93 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.6.4 +version: 0.6.5-dev groups: - javascript - queries diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index 6f452066fa6..d14aedc72f3 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,3 +1,3 @@ name: codeql/suite-helpers -version: 0.5.4 +version: 0.5.5-dev groups: shared diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index f24282bf699..33ecbe7252e 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.9.4 +version: 0.9.5-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 352afef47a7..0727c903ee3 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.7.4 +version: 0.7.5-dev groups: - python - queries diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 98f917bc02c..ab08dee7960 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.6.4 +version: 0.6.5-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 50034ddfea5..6d8f23f920e 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.6.4 +version: 0.6.5-dev groups: - ruby - queries diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index fb5958d29fd..2294498ec21 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 0.0.15 +version: 0.0.16-dev groups: shared library: true dependencies: diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index b10d003f884..bbd518f34df 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 0.0.19 +version: 0.0.20-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index 998e677c731..b7b422107ef 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,6 +1,6 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 0.0.12 +version: 0.0.13-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index 987916acfab..18bcbcfe047 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 0.0.12 +version: 0.0.13-dev groups: shared library: true dependencies: diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index b9cff555e5f..60f096a7fd5 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 0.0.19 +version: 0.0.20-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index 893b9e160f8..18ed4e9bbd9 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 0.0.12 +version: 0.0.13-dev groups: shared library: true dependencies: diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index 962a76f8ce9..8dda9a03906 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 0.0.4 +version: 0.0.5-dev groups: shared library: true warnOnImplicitThis: true diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index 20b6a17a834..e83d1bdd170 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 0.1.2 +version: 0.1.3-dev groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index 065f00e3a79..52c067ad6fe 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 0.1.2 +version: 0.1.3-dev groups: - swift - queries From 9ccbe73750b82db9d275289eb5a4d33fd4fb3bb1 Mon Sep 17 00:00:00 2001 From: Philip Ginsbach Date: Fri, 30 Jun 2023 11:58:30 +0100 Subject: [PATCH 047/118] document final extensions in the language specification --- .../ql-language-specification.rst | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/docs/codeql/ql-language-reference/ql-language-specification.rst b/docs/codeql/ql-language-reference/ql-language-specification.rst index 9328a0f3ec3..c87fe76401d 100644 --- a/docs/codeql/ql-language-reference/ql-language-specification.rst +++ b/docs/codeql/ql-language-reference/ql-language-specification.rst @@ -959,13 +959,18 @@ The types specified after the ``extends`` keyword are the *base types* of the cl The types specified after the ``instanceof`` keyword are the *instanceof types* of the class. -A class type is said to *inherit* from the base types. In addition, inheritance is transitive: If a type ``A`` inherits from a type ``B``, and ``B`` inherits from a type ``C``, then ``A`` inherits from ``C``. +A class type is said to *final inherit* from base types that are final or referenced through final aliases, and a class type is said to *inherit* from its other base types. In addition, inheritance is transitive: + +- If a type ``A`` inherits from a type ``B``, and ``B`` inherits from a type ``C``, then ``A`` inherits from ``C``. +- If a type ``A`` final inherits from a type ``B``, and ``B`` inherits from a type ``C``, then ``A`` final inherits from ``C``. +- If a type ``A`` inherits from a type ``B``, and ``B`` final inherits from a type ``C``, then ``A`` final inherits from ``C``. +- If a type ``A`` final inherits from a type ``B``, and ``B`` final inherits from a type ``C``, then ``A`` final inherits from ``C``. A class adds a mapping from the class name to the class declaration to the current module's declared type environment. A valid class can be annotated with ``abstract``, ``final``, ``library``, and ``private``. Any other annotation renders the class invalid. -A valid class may not inherit from a final class, from itself, or from more than one primitive type. +A valid class may not inherit from itself, or from more than one primitive type. The set of types that a valid class inherits from must be disjunct from the set of types that it final inherits from. A valid class must have at least one base type or instanceof type. @@ -975,9 +980,10 @@ Class dependencies The program is invalid if there is a cycle of class dependencies. The following are class dependencies: + - ``C`` depends on ``C.C`` - ``C.C`` depends on ``C.extends`` -- If ``C`` is abstract then it depends on all classes ``D`` such that ``C`` is a base type of ``D``. +- If ``C`` is abstract then it depends on all classes ``D`` such that ``C`` is a base type of ``D`` and ``D`` inherits from ``C``. - ``C.extends`` depends on ``D.D`` for each base type ``D`` of ``C``. - ``C.extends`` depends on ``D`` for each instanceof type ``D`` of ``C``. @@ -1029,7 +1035,9 @@ A valid member predicate can be annotated with ``abstract``, ``cached``, ``final If a type is provided before the name of the member predicate, then that type is the *result type* of the predicate. Otherwise, the predicate has no result type. The types of the variables in the ``var_decls`` are called the predicate's *argument types*. -A member predicate ``p`` with enclosing class ``C`` *overrides* a member predicate ``p'`` with enclosing class ``D`` when ``C`` inherits from ``D``, ``p'`` is visible in ``C``, and both ``p`` and ``p'`` have the same name and the same arity. An overriding predicate must have the same sequence of argument types as any predicates which it overrides, otherwise the program is invalid. +A member predicate ``p`` with enclosing class ``C`` *overrides* a member predicate ``p'`` with enclosing class ``D`` when ``p`` is annotated ``overrride``, ``C`` inherits from ``D``, ``p'`` is visible in ``C``, ``p'`` is not final, and both ``p`` and ``p'`` have the same name and the same arity. An overriding predicate must have the same sequence of argument types as any predicates which it overrides, otherwise the program is invalid. + +A member predicate ``p`` with enclosing class ``C`` *shadows* a member predicate ``p'`` with enclosing class ``D`` when ``C`` final inherits from ``D``, ``p'`` is visible in ``C``, and both ``p`` and ``p'`` have the same name and the same arity. Additionally, a member predicate ``p`` with enclosing class ``C`` *shadows* a member predicate ``p'`` with enclosing class ``D`` when ``C`` inherits from ``D``, ``p'`` is visible in ``C``, ``p'`` is final, and both ``p`` and ``p'`` have the same name and the same arity. Member predicates have one or more *root definitions*. If a member predicate overrides no other member predicate, then it is its own root definition. Otherwise, its root definitions are those of any member predicate that it overrides. @@ -1043,7 +1051,9 @@ A class may not inherit from a class with an abstract member predicate unless it A valid class must include a non-private predicate named ``toString`` with no arguments and a result type of ``string``, or it must inherit from a class that does. -A valid class may not inherit from two different classes that include a predicate with the same name and number of arguments, unless either one of the predicates overrides the other, or the class defines a predicate that overrides both of them. +A valid class may not inherit from two different classes that include a predicate with the same name and number of arguments, unless either one of the predicates overrides or shadows the other, or the class defines a predicate that overrides or shadows both of them. + +A valid class may not final inherit from two different classes that include a predicate with the same name and number of arguments, unless either one of the predicates overrides or shadows the other, or the class defines a predicate that shadows both of them. The typing environment for a member predicate or character is the same as if it were a non-member predicate, except that it additionally maps ``this`` to a type and also maps any fields on a class to a type. If the member is a character, then the typing environment maps ``this`` to the class domain type of the class. Otherwise, it maps ``this`` to the class type of the class itself. The typing environment also maps any field to the type of the field. @@ -1053,9 +1063,13 @@ Fields A field declaration introduces a mapping from the field name to the field declaration in the class's declared field environment. -A field ``f`` with enclosing class ``C`` *overrides* a field ``f'`` with enclosing class ``D`` when ``f`` is annotated ``override``, ``C`` inherits from ``D``, ``p'`` is visible in ``C``, and both ``p`` and ``p'`` have the same name. +A field ``f`` with enclosing class ``C`` *overrides* a field ``f'`` with enclosing class ``D`` when ``f`` is annotated ``override``, ``C`` inherits from ``D``, ``p'`` is visible in ``C``, ``p'`` is not final, and both ``p`` and ``p'`` have the same name. -A valid class may not inherit from two different classes that include a field with the same name, unless either one of the fields overrides the other, or the class defines a field that overrides both of them. +A field ``f`` with enclosing class ``C`` *shadows* a field ``f'`` with enclosing class ``D`` when ``C`` final inherits from ``D``, ``p'`` is visible in ``C``, and both ``p`` and ``p'`` have the same name. Additionally, a field ``f`` with enclosing class ``C`` *shadows* a field ``f'`` with enclosing class ``D`` when ``C`` inherits from ``D``, ``p'`` is visible in ``C``, ``p'`` is final, and both ``p`` and ``p'`` have the same name. + +A valid class may not inherit from two different classes that include a field with the same name, unless either one of the fields overrides or shadows the other, or the class defines a field that overrides or shadows both of them. + +A valid class may not final inherit from two different classes that include a field with the same name, unless either one of the fields overrides or shadows the other, or the class defines a field that shadows both of them. A valid field must override another field if it is annotated ``override``. @@ -1349,9 +1363,10 @@ If the call includes a closure, then all declared predicate arguments, the enclo A call to a member predicate may be a *direct* call: - If the receiver is not a super expression it is not direct. - - If the receiver is ``A.super`` and ``A`` is an instanceof type and not a base type then it is not direct. - - If the receiver is ``A.super`` and ``A`` is a base type type and not an instanceof type then it is direct. - - If the receiver is ``A.super`` and ``A`` is a base type and an instanceof type then the call is not valid. + - If the receiver is ``A.super`` and ``A`` is an instanceof type and not a base type that is inherited from then it is not direct. + - If the receiver is ``A.super`` and ``A`` is a base type that is final inherited from then it is not direct. + - If the receiver is ``A.super`` and ``A`` is a base type that is inherited from and not an instanceof type then it is direct. + - If the receiver is ``A.super`` and ``A`` is a base type that is inherited from and an instanceof type then the call is not valid. - If the receiver is ``super`` and the member predicate is in the exported member predicate environment of an instanceof type and not in the exported member predicate environment of a base type then it isn't direct. - If the receiver is ``super`` and the member predicate is in the exported member predicate environment of a base type and not in the exported member predicate environment of an instanceof type then it is direct. - If the receiver is ``super`` and the member predicate is in the exported member predicate environment of a base type and in the exported member predicate environment of an instanceof type then the call is not valid. @@ -2123,7 +2138,7 @@ Predicates, and types can *depend* and *strictly depend* on each other. Such dep - For each class ``C`` with a characteristic predicate, ``C.C`` depends on the characteristic predicate. -- For each abstract class ``A`` in the program, for each type ``C`` that has ``A`` as a base type, ``A.class`` depends on ``C.class``. +- For each abstract class ``A`` in the program, for each type ``C`` that inherits from ``A`` and has ``A`` as a base type, ``A.class`` depends on ``C.class``. - A predicate with a higher-order body may strictly depend or depend on each predicate reference within the body. The exact dependencies are left unspecified. @@ -2175,7 +2190,7 @@ Each layer of the stratification is *populated* in order. To populate a layer, e - To populate the type ``C.class`` for an abstract class type ``C``, identify each named tuple that has the following properties: - It is a member of ``C.C``. - - For each class ``D`` that has ``C`` as a base type then there is a named tuple with variables from the public fields of ``C`` and ``this`` that the given tuple and a tuple in ``D.class`` both extend. + - For each class ``D`` that inherits from ``C`` and has ``C`` as a base type then there is a named tuple with variables from the public fields of ``C`` and ``this`` that the given tuple and a tuple in ``D.class`` both extend. Query evaluation From ce464a7d6960689565fb87f431ede75746af7c36 Mon Sep 17 00:00:00 2001 From: Chuan-kai Lin Date: Fri, 30 Jun 2023 11:09:29 -0700 Subject: [PATCH 048/118] Remove pragma[assume_small_delta] --- .../cpp/dataflow/internal/DataFlowImpl.qll | 10 -- .../dataflow/internal/DataFlowImplCommon.qll | 2 - .../cpp/ir/dataflow/internal/DataFlowImpl.qll | 10 -- .../dataflow/internal/DataFlowImplCommon.qll | 2 - .../cpp/ir/dataflow/internal/ProductFlow.qll | 3 - .../dataflow/internal/SsaInternalsCommon.qll | 1 - .../gvn/internal/ValueNumberingInternal.qll | 3 - .../gvn/internal/ValueNumberingInternal.qll | 3 - .../gvn/internal/ValueNumberingInternal.qll | 3 - .../semantic/analysis/RangeAnalysisStage.qll | 1 - .../csharp/dataflow/internal/DataFlowImpl.qll | 10 -- .../dataflow/internal/DataFlowImplCommon.qll | 2 - .../dataflow/internal/FlowSummaryImpl.qll | 1 - .../gvn/internal/ValueNumberingInternal.qll | 3 - .../gvn/internal/ValueNumberingInternal.qll | 3 - .../go/dataflow/internal/DataFlowImpl.qll | 10 -- .../dataflow/internal/DataFlowImplCommon.qll | 2 - .../go/dataflow/internal/FlowSummaryImpl.qll | 1 - java/ql/lib/semmle/code/java/Constants.qll | 2 - .../lib/semmle/code/java/ControlFlowGraph.qll | 4 - java/ql/lib/semmle/code/java/Expr.qll | 4 - java/ql/lib/semmle/code/java/Member.qll | 1 - java/ql/lib/semmle/code/java/Type.qll | 1 - .../semmle/code/java/dataflow/NullGuards.qll | 2 - java/ql/lib/semmle/code/java/dataflow/SSA.qll | 3 - .../semmle/code/java/dataflow/TypeFlow.qll | 1 - .../code/java/dataflow/internal/BaseSSA.qll | 1 - .../java/dataflow/internal/DataFlowImpl.qll | 10 -- .../dataflow/internal/DataFlowImplCommon.qll | 2 - .../dataflow/internal/FlowSummaryImpl.qll | 1 - .../dataflow/internal/TaintTrackingUtil.qll | 1 - .../code/java/dispatch/DispatchFlow.qll | 1 - .../lib/semmle/code/java/dispatch/ObjFlow.qll | 1 - .../lib/semmle/code/java/frameworks/JaxWS.qll | 2 - .../lib/semmle/code/java/frameworks/Rmi.qll | 1 - .../frameworks/google/GsonSerializability.qll | 1 - .../jackson/JacksonSerializability.qll | 1 - .../lib/semmle/javascript/InclusionTests.qll | 2 - .../ql/lib/semmle/javascript/StringOps.qll | 4 - ...ondOrderCommandInjectionCustomizations.qll | 1 - .../new/internal/DataFlowDispatch.qll | 1 - .../dataflow/new/internal/DataFlowImpl.qll | 10 -- .../new/internal/DataFlowImplCommon.qll | 2 - .../dataflow/new/internal/FlowSummaryImpl.qll | 1 - ql/ql/test/printAst/Foo.qll | 5 +- ql/ql/test/printAst/printAst.expected | 170 ++++++++---------- .../ruby/dataflow/internal/DataFlowImpl.qll | 10 -- .../dataflow/internal/DataFlowImplCommon.qll | 2 - .../dataflow/internal/FlowSummaryImpl.qll | 1 - .../codeql/typetracking/TypeTracking.qll | 1 - .../swift/dataflow/internal/DataFlowImpl.qll | 10 -- .../dataflow/internal/DataFlowImplCommon.qll | 2 - .../dataflow/internal/FlowSummaryImpl.qll | 1 - 53 files changed, 78 insertions(+), 255 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index 284fff191ae..410543e0fc9 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -460,7 +460,6 @@ module Impl { * The Boolean `cc` records whether the node is reached through an * argument in a call. */ - pragma[assume_small_delta] private predicate fwdFlow(NodeEx node, Cc cc) { sourceNode(node, _) and if hasSourceCallCtx() then cc = true else cc = false @@ -570,7 +569,6 @@ module Impl { /** * Holds if `c` is the target of a store in the flow covered by `fwdFlow`. */ - pragma[assume_small_delta] pragma[nomagic] private predicate fwdFlowConsCand(Content c) { exists(NodeEx mid, NodeEx node | @@ -1216,7 +1214,6 @@ module Impl { fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } - pragma[assume_small_delta] pragma[nomagic] private predicate fwdFlow0( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, @@ -2777,7 +2774,6 @@ module Impl { /** * Gets the number of `AccessPath`s that correspond to `apa`. */ - pragma[assume_small_delta] private int countAps(AccessPathApprox apa) { evalUnfold(apa, false) and result = 1 and @@ -2796,7 +2792,6 @@ module Impl { * that it is expanded to a precise head-tail representation. */ language[monotonicAggregates] - pragma[assume_small_delta] private int countPotentialAps(AccessPathApprox apa) { apa instanceof AccessPathApproxNil and result = 1 or @@ -2833,7 +2828,6 @@ module Impl { } private newtype TPathNode = - pragma[assume_small_delta] TPathNodeMid( NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap ) { @@ -2918,7 +2912,6 @@ module Impl { override AccessPathFrontHead getFront() { result = TFrontHead(head_) } - pragma[assume_small_delta] override AccessPathApproxCons getApprox() { result = TConsNil(head_, t) and tail_ = TAccessPathNil() or @@ -2927,7 +2920,6 @@ module Impl { result = TCons1(head_, this.length()) } - pragma[assume_small_delta] override int length() { result = 1 + tail_.length() } private string toStringImpl(boolean needsSuffix) { @@ -3379,7 +3371,6 @@ module Impl { * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ - pragma[assume_small_delta] pragma[nomagic] private predicate pathStep0( PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, @@ -3592,7 +3583,6 @@ module Impl { ) } - pragma[assume_small_delta] pragma[nomagic] private predicate pathThroughCallable0( DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, FlowState state, CallContext cc, diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll index 0d4c033c95d..aff14e7b44d 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll @@ -187,7 +187,6 @@ private module LambdaFlow { else any() } - pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlow0( DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, @@ -274,7 +273,6 @@ private module LambdaFlow { ) } - pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlowOut( DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 284fff191ae..410543e0fc9 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -460,7 +460,6 @@ module Impl { * The Boolean `cc` records whether the node is reached through an * argument in a call. */ - pragma[assume_small_delta] private predicate fwdFlow(NodeEx node, Cc cc) { sourceNode(node, _) and if hasSourceCallCtx() then cc = true else cc = false @@ -570,7 +569,6 @@ module Impl { /** * Holds if `c` is the target of a store in the flow covered by `fwdFlow`. */ - pragma[assume_small_delta] pragma[nomagic] private predicate fwdFlowConsCand(Content c) { exists(NodeEx mid, NodeEx node | @@ -1216,7 +1214,6 @@ module Impl { fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } - pragma[assume_small_delta] pragma[nomagic] private predicate fwdFlow0( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, @@ -2777,7 +2774,6 @@ module Impl { /** * Gets the number of `AccessPath`s that correspond to `apa`. */ - pragma[assume_small_delta] private int countAps(AccessPathApprox apa) { evalUnfold(apa, false) and result = 1 and @@ -2796,7 +2792,6 @@ module Impl { * that it is expanded to a precise head-tail representation. */ language[monotonicAggregates] - pragma[assume_small_delta] private int countPotentialAps(AccessPathApprox apa) { apa instanceof AccessPathApproxNil and result = 1 or @@ -2833,7 +2828,6 @@ module Impl { } private newtype TPathNode = - pragma[assume_small_delta] TPathNodeMid( NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap ) { @@ -2918,7 +2912,6 @@ module Impl { override AccessPathFrontHead getFront() { result = TFrontHead(head_) } - pragma[assume_small_delta] override AccessPathApproxCons getApprox() { result = TConsNil(head_, t) and tail_ = TAccessPathNil() or @@ -2927,7 +2920,6 @@ module Impl { result = TCons1(head_, this.length()) } - pragma[assume_small_delta] override int length() { result = 1 + tail_.length() } private string toStringImpl(boolean needsSuffix) { @@ -3379,7 +3371,6 @@ module Impl { * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ - pragma[assume_small_delta] pragma[nomagic] private predicate pathStep0( PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, @@ -3592,7 +3583,6 @@ module Impl { ) } - pragma[assume_small_delta] pragma[nomagic] private predicate pathThroughCallable0( DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, FlowState state, CallContext cc, diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll index 0d4c033c95d..aff14e7b44d 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll @@ -187,7 +187,6 @@ private module LambdaFlow { else any() } - pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlow0( DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, @@ -274,7 +273,6 @@ private module LambdaFlow { ) } - pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlowOut( DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ProductFlow.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ProductFlow.qll index cb06245c568..cb99d3e5a1e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ProductFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ProductFlow.qll @@ -359,7 +359,6 @@ module ProductFlow { Config::isSinkPair(node1.getNode(), node1.getState(), node2.getNode(), node2.getState()) } - pragma[assume_small_delta] pragma[nomagic] private predicate fwdReachableInterprocEntry(Flow1::PathNode node1, Flow2::PathNode node2) { isSourcePair(node1, node2) @@ -396,7 +395,6 @@ module ProductFlow { fwdIsSuccessorExit(pragma[only_bind_into](mid1), pragma[only_bind_into](mid2), succ1, succ2) } - pragma[assume_small_delta] private predicate fwdIsSuccessor( Flow1::PathNode pred1, Flow2::PathNode pred2, Flow1::PathNode succ1, Flow2::PathNode succ2 ) { @@ -406,7 +404,6 @@ module ProductFlow { ) } - pragma[assume_small_delta] pragma[nomagic] private predicate revReachableInterprocEntry(Flow1::PathNode node1, Flow2::PathNode node2) { fwdReachableInterprocEntry(node1, node2) and diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll index 56702bd79a9..33b33113d43 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll @@ -588,7 +588,6 @@ private module Cached { ) } - pragma[assume_small_delta] private predicate convertsIntoArgumentRev(Instruction instr) { convertsIntoArgumentFwd(instr) and ( diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll index 85a28fbc677..ec003891774 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/internal/ValueNumberingInternal.qll @@ -176,7 +176,6 @@ private predicate binaryValueNumber0( ) } -pragma[assume_small_delta] private predicate binaryValueNumber( BinaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand @@ -202,7 +201,6 @@ private predicate pointerArithmeticValueNumber0( ) } -pragma[assume_small_delta] private predicate pointerArithmeticValueNumber( PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize, TValueNumber leftOperand, TValueNumber rightOperand @@ -249,7 +247,6 @@ private predicate loadTotalOverlapValueNumber0( ) } -pragma[assume_small_delta] private predicate loadTotalOverlapValueNumber( LoadTotalOverlapInstruction instr, IRFunction irFunc, IRType type, TValueNumber memOperand, TValueNumber operand diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll index 85a28fbc677..ec003891774 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll @@ -176,7 +176,6 @@ private predicate binaryValueNumber0( ) } -pragma[assume_small_delta] private predicate binaryValueNumber( BinaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand @@ -202,7 +201,6 @@ private predicate pointerArithmeticValueNumber0( ) } -pragma[assume_small_delta] private predicate pointerArithmeticValueNumber( PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize, TValueNumber leftOperand, TValueNumber rightOperand @@ -249,7 +247,6 @@ private predicate loadTotalOverlapValueNumber0( ) } -pragma[assume_small_delta] private predicate loadTotalOverlapValueNumber( LoadTotalOverlapInstruction instr, IRFunction irFunc, IRType type, TValueNumber memOperand, TValueNumber operand diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll index 85a28fbc677..ec003891774 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll @@ -176,7 +176,6 @@ private predicate binaryValueNumber0( ) } -pragma[assume_small_delta] private predicate binaryValueNumber( BinaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand @@ -202,7 +201,6 @@ private predicate pointerArithmeticValueNumber0( ) } -pragma[assume_small_delta] private predicate pointerArithmeticValueNumber( PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize, TValueNumber leftOperand, TValueNumber rightOperand @@ -249,7 +247,6 @@ private predicate loadTotalOverlapValueNumber0( ) } -pragma[assume_small_delta] private predicate loadTotalOverlapValueNumber( LoadTotalOverlapInstruction instr, IRFunction irFunc, IRType type, TValueNumber memOperand, TValueNumber operand diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisStage.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisStage.qll index c07a3ea55a0..0576f5ff373 100644 --- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisStage.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisStage.qll @@ -877,7 +877,6 @@ module RangeStage< ) } - pragma[assume_small_delta] pragma[nomagic] private predicate boundedPhiRankStep( SemSsaPhiNode phi, SemBound b, D::Delta delta, boolean upper, boolean fromBackEdge, diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index 284fff191ae..410543e0fc9 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -460,7 +460,6 @@ module Impl { * The Boolean `cc` records whether the node is reached through an * argument in a call. */ - pragma[assume_small_delta] private predicate fwdFlow(NodeEx node, Cc cc) { sourceNode(node, _) and if hasSourceCallCtx() then cc = true else cc = false @@ -570,7 +569,6 @@ module Impl { /** * Holds if `c` is the target of a store in the flow covered by `fwdFlow`. */ - pragma[assume_small_delta] pragma[nomagic] private predicate fwdFlowConsCand(Content c) { exists(NodeEx mid, NodeEx node | @@ -1216,7 +1214,6 @@ module Impl { fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } - pragma[assume_small_delta] pragma[nomagic] private predicate fwdFlow0( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, @@ -2777,7 +2774,6 @@ module Impl { /** * Gets the number of `AccessPath`s that correspond to `apa`. */ - pragma[assume_small_delta] private int countAps(AccessPathApprox apa) { evalUnfold(apa, false) and result = 1 and @@ -2796,7 +2792,6 @@ module Impl { * that it is expanded to a precise head-tail representation. */ language[monotonicAggregates] - pragma[assume_small_delta] private int countPotentialAps(AccessPathApprox apa) { apa instanceof AccessPathApproxNil and result = 1 or @@ -2833,7 +2828,6 @@ module Impl { } private newtype TPathNode = - pragma[assume_small_delta] TPathNodeMid( NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap ) { @@ -2918,7 +2912,6 @@ module Impl { override AccessPathFrontHead getFront() { result = TFrontHead(head_) } - pragma[assume_small_delta] override AccessPathApproxCons getApprox() { result = TConsNil(head_, t) and tail_ = TAccessPathNil() or @@ -2927,7 +2920,6 @@ module Impl { result = TCons1(head_, this.length()) } - pragma[assume_small_delta] override int length() { result = 1 + tail_.length() } private string toStringImpl(boolean needsSuffix) { @@ -3379,7 +3371,6 @@ module Impl { * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ - pragma[assume_small_delta] pragma[nomagic] private predicate pathStep0( PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, @@ -3592,7 +3583,6 @@ module Impl { ) } - pragma[assume_small_delta] pragma[nomagic] private predicate pathThroughCallable0( DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, FlowState state, CallContext cc, diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll index 0d4c033c95d..aff14e7b44d 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll @@ -187,7 +187,6 @@ private module LambdaFlow { else any() } - pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlow0( DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, @@ -274,7 +273,6 @@ private module LambdaFlow { ) } - pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlowOut( DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll index 9ea7c44c50c..d62ed3f2c13 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll @@ -110,7 +110,6 @@ module Public { } /** Gets the stack obtained by dropping the first `i` elements, if any. */ - pragma[assume_small_delta] SummaryComponentStack drop(int i) { i = 0 and result = this or diff --git a/csharp/ql/src/experimental/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll b/csharp/ql/src/experimental/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll index 85a28fbc677..ec003891774 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/gvn/internal/ValueNumberingInternal.qll @@ -176,7 +176,6 @@ private predicate binaryValueNumber0( ) } -pragma[assume_small_delta] private predicate binaryValueNumber( BinaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand @@ -202,7 +201,6 @@ private predicate pointerArithmeticValueNumber0( ) } -pragma[assume_small_delta] private predicate pointerArithmeticValueNumber( PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize, TValueNumber leftOperand, TValueNumber rightOperand @@ -249,7 +247,6 @@ private predicate loadTotalOverlapValueNumber0( ) } -pragma[assume_small_delta] private predicate loadTotalOverlapValueNumber( LoadTotalOverlapInstruction instr, IRFunction irFunc, IRType type, TValueNumber memOperand, TValueNumber operand diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll index 85a28fbc677..ec003891774 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingInternal.qll @@ -176,7 +176,6 @@ private predicate binaryValueNumber0( ) } -pragma[assume_small_delta] private predicate binaryValueNumber( BinaryInstruction instr, IRFunction irFunc, Opcode opcode, TValueNumber leftOperand, TValueNumber rightOperand @@ -202,7 +201,6 @@ private predicate pointerArithmeticValueNumber0( ) } -pragma[assume_small_delta] private predicate pointerArithmeticValueNumber( PointerArithmeticInstruction instr, IRFunction irFunc, Opcode opcode, int elementSize, TValueNumber leftOperand, TValueNumber rightOperand @@ -249,7 +247,6 @@ private predicate loadTotalOverlapValueNumber0( ) } -pragma[assume_small_delta] private predicate loadTotalOverlapValueNumber( LoadTotalOverlapInstruction instr, IRFunction irFunc, IRType type, TValueNumber memOperand, TValueNumber operand diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index 284fff191ae..410543e0fc9 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -460,7 +460,6 @@ module Impl { * The Boolean `cc` records whether the node is reached through an * argument in a call. */ - pragma[assume_small_delta] private predicate fwdFlow(NodeEx node, Cc cc) { sourceNode(node, _) and if hasSourceCallCtx() then cc = true else cc = false @@ -570,7 +569,6 @@ module Impl { /** * Holds if `c` is the target of a store in the flow covered by `fwdFlow`. */ - pragma[assume_small_delta] pragma[nomagic] private predicate fwdFlowConsCand(Content c) { exists(NodeEx mid, NodeEx node | @@ -1216,7 +1214,6 @@ module Impl { fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } - pragma[assume_small_delta] pragma[nomagic] private predicate fwdFlow0( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, @@ -2777,7 +2774,6 @@ module Impl { /** * Gets the number of `AccessPath`s that correspond to `apa`. */ - pragma[assume_small_delta] private int countAps(AccessPathApprox apa) { evalUnfold(apa, false) and result = 1 and @@ -2796,7 +2792,6 @@ module Impl { * that it is expanded to a precise head-tail representation. */ language[monotonicAggregates] - pragma[assume_small_delta] private int countPotentialAps(AccessPathApprox apa) { apa instanceof AccessPathApproxNil and result = 1 or @@ -2833,7 +2828,6 @@ module Impl { } private newtype TPathNode = - pragma[assume_small_delta] TPathNodeMid( NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap ) { @@ -2918,7 +2912,6 @@ module Impl { override AccessPathFrontHead getFront() { result = TFrontHead(head_) } - pragma[assume_small_delta] override AccessPathApproxCons getApprox() { result = TConsNil(head_, t) and tail_ = TAccessPathNil() or @@ -2927,7 +2920,6 @@ module Impl { result = TCons1(head_, this.length()) } - pragma[assume_small_delta] override int length() { result = 1 + tail_.length() } private string toStringImpl(boolean needsSuffix) { @@ -3379,7 +3371,6 @@ module Impl { * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ - pragma[assume_small_delta] pragma[nomagic] private predicate pathStep0( PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, @@ -3592,7 +3583,6 @@ module Impl { ) } - pragma[assume_small_delta] pragma[nomagic] private predicate pathThroughCallable0( DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, FlowState state, CallContext cc, diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll index 0d4c033c95d..aff14e7b44d 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll @@ -187,7 +187,6 @@ private module LambdaFlow { else any() } - pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlow0( DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, @@ -274,7 +273,6 @@ private module LambdaFlow { ) } - pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlowOut( DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index 9ea7c44c50c..d62ed3f2c13 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -110,7 +110,6 @@ module Public { } /** Gets the stack obtained by dropping the first `i` elements, if any. */ - pragma[assume_small_delta] SummaryComponentStack drop(int i) { i = 0 and result = this or diff --git a/java/ql/lib/semmle/code/java/Constants.qll b/java/ql/lib/semmle/code/java/Constants.qll index e9ace210d70..9e35a925be3 100644 --- a/java/ql/lib/semmle/code/java/Constants.qll +++ b/java/ql/lib/semmle/code/java/Constants.qll @@ -17,7 +17,6 @@ signature int getIntValSig(Expr e); */ module CalculateConstants { /** Gets the value of a constant boolean expression. */ - pragma[assume_small_delta] boolean calculateBooleanValue(Expr e) { // No casts relevant to booleans. // `!` is the only unary operator that evaluates to a boolean. @@ -99,7 +98,6 @@ module CalculateConstants } /** Gets the value of a constant integer expression. */ - pragma[assume_small_delta] int calculateIntValue(Expr e) { exists(IntegralType t | e.getType() = t | t.getName().toLowerCase() != "long") and ( diff --git a/java/ql/lib/semmle/code/java/ControlFlowGraph.qll b/java/ql/lib/semmle/code/java/ControlFlowGraph.qll index f94658e1372..229c526d270 100644 --- a/java/ql/lib/semmle/code/java/ControlFlowGraph.qll +++ b/java/ql/lib/semmle/code/java/ControlFlowGraph.qll @@ -365,7 +365,6 @@ private module ControlFlowGraphImpl { /** * Gets a non-overridable method that always throws an exception or calls `exit`. */ - pragma[assume_small_delta] private Method nonReturningMethod() { result instanceof MethodExit or @@ -382,7 +381,6 @@ private module ControlFlowGraphImpl { /** * Gets a virtual method that always throws an exception or calls `exit`. */ - pragma[assume_small_delta] private EffectivelyNonVirtualMethod likelyNonReturningMethod() { result.getReturnType() instanceof VoidType and not exists(ReturnStmt ret | ret.getEnclosingCallable() = result) and @@ -402,7 +400,6 @@ private module ControlFlowGraphImpl { /** * Gets a statement that always throws an exception or calls `exit`. */ - pragma[assume_small_delta] private Stmt nonReturningStmt() { result instanceof ThrowStmt or @@ -424,7 +421,6 @@ private module ControlFlowGraphImpl { /** * Gets an expression that always throws an exception or calls `exit`. */ - pragma[assume_small_delta] private Expr nonReturningExpr() { result = nonReturningMethodAccess() or diff --git a/java/ql/lib/semmle/code/java/Expr.qll b/java/ql/lib/semmle/code/java/Expr.qll index 92c81650bc3..312d7767ac2 100644 --- a/java/ql/lib/semmle/code/java/Expr.qll +++ b/java/ql/lib/semmle/code/java/Expr.qll @@ -131,7 +131,6 @@ private predicate primitiveOrString(Type t) { * See JLS v8, section 15.28 (Constant Expressions). */ class CompileTimeConstantExpr extends Expr { - pragma[assume_small_delta] CompileTimeConstantExpr() { primitiveOrString(this.getType()) and ( @@ -181,7 +180,6 @@ class CompileTimeConstantExpr extends Expr { /** * Gets the string value of this expression, where possible. */ - pragma[assume_small_delta] pragma[nomagic] string getStringValue() { result = this.(StringLiteral).getValue() @@ -207,7 +205,6 @@ class CompileTimeConstantExpr extends Expr { /** * Gets the boolean value of this expression, where possible. */ - pragma[assume_small_delta] pragma[nomagic] boolean getBooleanValue() { // Literal value. @@ -1910,7 +1907,6 @@ class TypeAccess extends Expr, Annotatable, @typeaccess { override CompilationUnit getCompilationUnit() { result = Expr.super.getCompilationUnit() } /** Gets a printable representation of this expression. */ - pragma[assume_small_delta] override string toString() { result = this.getQualifier().toString() + "." + this.getType().toString() or diff --git a/java/ql/lib/semmle/code/java/Member.qll b/java/ql/lib/semmle/code/java/Member.qll index d09fa9042d9..565da1b6d97 100644 --- a/java/ql/lib/semmle/code/java/Member.qll +++ b/java/ql/lib/semmle/code/java/Member.qll @@ -736,7 +736,6 @@ class FieldDeclaration extends ExprParent, @fielddecl, Annotatable { /** Gets the number of fields declared in this declaration. */ int getNumField() { result = max(int idx | fieldDeclaredIn(_, this, idx) | idx) + 1 } - pragma[assume_small_delta] override string toString() { if this.getNumField() = 1 then result = this.getTypeAccess() + " " + this.getField(0) + ";" diff --git a/java/ql/lib/semmle/code/java/Type.qll b/java/ql/lib/semmle/code/java/Type.qll index fcf31e3be0d..e8e9c2bf916 100644 --- a/java/ql/lib/semmle/code/java/Type.qll +++ b/java/ql/lib/semmle/code/java/Type.qll @@ -309,7 +309,6 @@ private predicate hasSubtypeStar1(RefType t, RefType sub) { /** * Holds if `hasSubtype*(t, sub)`, but manual-magic'ed with `getAWildcardLowerBound(sub)`. */ -pragma[assume_small_delta] pragma[nomagic] private predicate hasSubtypeStar2(RefType t, RefType sub) { sub = t and getAWildcardLowerBound(sub) diff --git a/java/ql/lib/semmle/code/java/dataflow/NullGuards.qll b/java/ql/lib/semmle/code/java/dataflow/NullGuards.qll index 25b39458656..011932bc48b 100644 --- a/java/ql/lib/semmle/code/java/dataflow/NullGuards.qll +++ b/java/ql/lib/semmle/code/java/dataflow/NullGuards.qll @@ -42,7 +42,6 @@ EqualityTest varEqualityTestExpr(SsaVariable v1, SsaVariable v2, boolean isEqual } /** Gets an expression that is provably not `null`. */ -pragma[assume_small_delta] Expr clearlyNotNullExpr(Expr reason) { result instanceof ClassInstanceExpr and reason = result or @@ -237,7 +236,6 @@ Expr directNullGuard(SsaVariable v, boolean branch, boolean isnull) { * If `result` evaluates to `branch`, then `v` is guaranteed to be null if `isnull` * is true, and non-null if `isnull` is false. */ -pragma[assume_small_delta] Guard nullGuard(SsaVariable v, boolean branch, boolean isnull) { result = directNullGuard(v, branch, isnull) or exists(boolean branch0 | implies_v3(result, branch, nullGuard(v, branch0, isnull), branch0)) diff --git a/java/ql/lib/semmle/code/java/dataflow/SSA.qll b/java/ql/lib/semmle/code/java/dataflow/SSA.qll index dd478b2a869..fb2e87e9bc7 100644 --- a/java/ql/lib/semmle/code/java/dataflow/SSA.qll +++ b/java/ql/lib/semmle/code/java/dataflow/SSA.qll @@ -61,7 +61,6 @@ class SsaSourceVariable extends TSsaSourceVariable { * accessed from nested callables are therefore associated with several * `SsaSourceVariable`s. */ - pragma[assume_small_delta] cached VarAccess getAnAccess() { exists(LocalScopeVariable v, Callable c | @@ -451,7 +450,6 @@ private module SsaImpl { * Holds if `f` is live in `b` at index `i`. The rank of `i` is `rankix` as * defined by `callDefUseRank`. */ - pragma[assume_small_delta] private predicate liveAtRank(TrackedField f, BasicBlock b, int rankix, int i) { callDefUseRank(f, b, rankix, i) and ( @@ -565,7 +563,6 @@ private module SsaImpl { } /** Holds if a phi node for `v` is needed at the beginning of basic block `b`. */ - pragma[assume_small_delta] cached predicate phiNode(TrackedVar v, BasicBlock b) { liveAtEntry(v, b) and diff --git a/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll b/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll index add7ebc66d4..6d1946a47f6 100644 --- a/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll @@ -241,7 +241,6 @@ private module ForAll E, TypePropagation T> { * Holds if `t` is a candidate bound for `n` that is also valid for data coming * through the edges into `n` ranked from `1` to `r`. */ - pragma[assume_small_delta] private predicate flowJoin(int r, Node n, T::Typ t) { ( r = 1 and candJoinType(n, t) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll b/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll index 6e41c803553..f4af8f506d6 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll @@ -151,7 +151,6 @@ private module SsaImpl { } /** Holds if a phi node for `v` is needed at the beginning of basic block `b`. */ - pragma[assume_small_delta] cached predicate phiNode(BaseSsaSourceVariable v, BasicBlock b) { liveAtEntry(v, b) and diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll index 284fff191ae..410543e0fc9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -460,7 +460,6 @@ module Impl { * The Boolean `cc` records whether the node is reached through an * argument in a call. */ - pragma[assume_small_delta] private predicate fwdFlow(NodeEx node, Cc cc) { sourceNode(node, _) and if hasSourceCallCtx() then cc = true else cc = false @@ -570,7 +569,6 @@ module Impl { /** * Holds if `c` is the target of a store in the flow covered by `fwdFlow`. */ - pragma[assume_small_delta] pragma[nomagic] private predicate fwdFlowConsCand(Content c) { exists(NodeEx mid, NodeEx node | @@ -1216,7 +1214,6 @@ module Impl { fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } - pragma[assume_small_delta] pragma[nomagic] private predicate fwdFlow0( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, @@ -2777,7 +2774,6 @@ module Impl { /** * Gets the number of `AccessPath`s that correspond to `apa`. */ - pragma[assume_small_delta] private int countAps(AccessPathApprox apa) { evalUnfold(apa, false) and result = 1 and @@ -2796,7 +2792,6 @@ module Impl { * that it is expanded to a precise head-tail representation. */ language[monotonicAggregates] - pragma[assume_small_delta] private int countPotentialAps(AccessPathApprox apa) { apa instanceof AccessPathApproxNil and result = 1 or @@ -2833,7 +2828,6 @@ module Impl { } private newtype TPathNode = - pragma[assume_small_delta] TPathNodeMid( NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap ) { @@ -2918,7 +2912,6 @@ module Impl { override AccessPathFrontHead getFront() { result = TFrontHead(head_) } - pragma[assume_small_delta] override AccessPathApproxCons getApprox() { result = TConsNil(head_, t) and tail_ = TAccessPathNil() or @@ -2927,7 +2920,6 @@ module Impl { result = TCons1(head_, this.length()) } - pragma[assume_small_delta] override int length() { result = 1 + tail_.length() } private string toStringImpl(boolean needsSuffix) { @@ -3379,7 +3371,6 @@ module Impl { * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ - pragma[assume_small_delta] pragma[nomagic] private predicate pathStep0( PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, @@ -3592,7 +3583,6 @@ module Impl { ) } - pragma[assume_small_delta] pragma[nomagic] private predicate pathThroughCallable0( DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, FlowState state, CallContext cc, diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll index 0d4c033c95d..aff14e7b44d 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll @@ -187,7 +187,6 @@ private module LambdaFlow { else any() } - pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlow0( DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, @@ -274,7 +273,6 @@ private module LambdaFlow { ) } - pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlowOut( DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll index 9ea7c44c50c..d62ed3f2c13 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll @@ -110,7 +110,6 @@ module Public { } /** Gets the stack obtained by dropping the first `i` elements, if any. */ - pragma[assume_small_delta] SummaryComponentStack drop(int i) { i = 0 and result = this or diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index a43aa5be4f1..c992f92ee8a 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -617,7 +617,6 @@ private MethodAccess callReturningSameType(Expr ref) { result.getMethod().getReturnType() = ref.getType() } -pragma[assume_small_delta] private SrcRefType entrypointType() { exists(RemoteFlowSource s, RefType t | s instanceof DataFlow::ExplicitParameterNode and diff --git a/java/ql/lib/semmle/code/java/dispatch/DispatchFlow.qll b/java/ql/lib/semmle/code/java/dispatch/DispatchFlow.qll index c6419f4c26b..e3eb298dd13 100644 --- a/java/ql/lib/semmle/code/java/dispatch/DispatchFlow.qll +++ b/java/ql/lib/semmle/code/java/dispatch/DispatchFlow.qll @@ -31,7 +31,6 @@ private Callable dispatchCand(Call c) { /** * Holds if `t` and all its enclosing types are public. */ -pragma[assume_small_delta] private predicate veryPublic(RefType t) { t.isPublic() and ( diff --git a/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll b/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll index d4c0d7e5ab5..14ea6e81718 100644 --- a/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll +++ b/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll @@ -206,7 +206,6 @@ private predicate relevantNodeBack(ObjNode n) { exists(ObjNode mid | objStep(n, mid) and relevantNodeBack(mid)) } -pragma[assume_small_delta] private predicate relevantNode(ObjNode n) { source(_, n) and relevantNodeBack(n) or diff --git a/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll b/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll index 5c20af2f457..54b41f28a08 100644 --- a/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll +++ b/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll @@ -53,7 +53,6 @@ private predicate hasPathAnnotation(Annotatable annotatable) { * A method which is annotated with one or more JaxRS resource type annotations e.g. `@GET`, `@POST` etc. */ class JaxRsResourceMethod extends Method { - pragma[assume_small_delta] JaxRsResourceMethod() { exists(AnnotationType a | a = this.getAnAnnotation().getType() and @@ -92,7 +91,6 @@ class JaxRsResourceMethod extends Method { * This class contains resource methods, which are executed in response to requests. */ class JaxRsResourceClass extends Class { - pragma[assume_small_delta] JaxRsResourceClass() { // A root resource class has a @Path annotation on the class. hasPathAnnotation(this) diff --git a/java/ql/lib/semmle/code/java/frameworks/Rmi.qll b/java/ql/lib/semmle/code/java/frameworks/Rmi.qll index 7cff44a69ff..922f90bccb6 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Rmi.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Rmi.qll @@ -12,7 +12,6 @@ class RemoteCallableMethod extends Method { RemoteCallableMethod() { remoteCallableMethod(this) } } -pragma[assume_small_delta] private predicate remoteCallableMethod(Method method) { method.getDeclaringType().getASupertype() instanceof TypeRemote or diff --git a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll index f7de80daaf4..8a286c93a16 100644 --- a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll +++ b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll @@ -45,7 +45,6 @@ private class FieldReferencedGsonDeserializableType extends GsonDeserializableTy /** A field that may be deserialized using the Gson JSON framework. */ private class GsonDeserializableField extends DeserializableField { - pragma[assume_small_delta] GsonDeserializableField() { exists(GsonDeserializableType superType | superType = this.getDeclaringType().getAnAncestor() and diff --git a/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll b/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll index f1395431a3c..4f857afb660 100644 --- a/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll +++ b/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll @@ -146,7 +146,6 @@ class JacksonSerializableField extends SerializableField { /** A field that may be deserialized using the Jackson JSON framework. */ class JacksonDeserializableField extends DeserializableField { - pragma[assume_small_delta] JacksonDeserializableField() { exists(JacksonDeserializableType superType | superType = this.getDeclaringType().getAnAncestor() and diff --git a/javascript/ql/lib/semmle/javascript/InclusionTests.qll b/javascript/ql/lib/semmle/javascript/InclusionTests.qll index 849376374ad..3d9921bf6ff 100644 --- a/javascript/ql/lib/semmle/javascript/InclusionTests.qll +++ b/javascript/ql/lib/semmle/javascript/InclusionTests.qll @@ -69,7 +69,6 @@ module InclusionTest { inner.getContainerNode().getALocalSource() = DataFlow::parameterNode(callee.getAParameter()) } - pragma[assume_small_delta] override DataFlow::Node getContainerNode() { exists(int arg | inner.getContainerNode().getALocalSource() = @@ -78,7 +77,6 @@ module InclusionTest { ) } - pragma[assume_small_delta] override DataFlow::Node getContainedNode() { exists(int arg | inner.getContainedNode().getALocalSource() = diff --git a/javascript/ql/lib/semmle/javascript/StringOps.qll b/javascript/ql/lib/semmle/javascript/StringOps.qll index da751b550d7..6b7820e964d 100644 --- a/javascript/ql/lib/semmle/javascript/StringOps.qll +++ b/javascript/ql/lib/semmle/javascript/StringOps.qll @@ -67,7 +67,6 @@ module StringOps { inner.getSubstring().getALocalSource().getEnclosingExpr() = callee.getAParameter() } - pragma[assume_small_delta] override DataFlow::Node getBaseString() { exists(int arg | inner.getBaseString().getALocalSource().getEnclosingExpr() = callee.getParameter(arg) and @@ -75,7 +74,6 @@ module StringOps { ) } - pragma[assume_small_delta] override DataFlow::Node getSubstring() { exists(int arg | inner.getSubstring().getALocalSource().getEnclosingExpr() = callee.getParameter(arg) and @@ -294,7 +292,6 @@ module StringOps { inner.getSubstring().getALocalSource().getEnclosingExpr() = callee.getAParameter() } - pragma[assume_small_delta] override DataFlow::Node getBaseString() { exists(int arg | inner.getBaseString().getALocalSource().getEnclosingExpr() = callee.getParameter(arg) and @@ -302,7 +299,6 @@ module StringOps { ) } - pragma[assume_small_delta] override DataFlow::Node getSubstring() { exists(int arg | inner.getSubstring().getALocalSource().getEnclosingExpr() = callee.getParameter(arg) and diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionCustomizations.qll index 04e2c358788..c405dec31f7 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/SecondOrderCommandInjectionCustomizations.qll @@ -117,7 +117,6 @@ module SecondOrderCommandInjection { int cmdIndex; int argIndex; - pragma[assume_small_delta] IndirectCmdFunc() { exists(CommandExecutingCall call | this.getParameter(cmdIndex).flowsTo(call.getCommandArg()) and diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll index ba451a21fdf..97802218f3d 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll @@ -1227,7 +1227,6 @@ predicate normalCallArg(CallNode call, Node arg, ArgumentPosition apos) { * time the bound method is used, such that the `clear()` call would essentially be * translated into `l.clear()`, and we can still have use-use flow. */ -pragma[assume_small_delta] cached predicate getCallArg(CallNode call, Function target, CallType type, Node arg, ArgumentPosition apos) { Stages::DataFlow::ref() and diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll index 284fff191ae..410543e0fc9 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -460,7 +460,6 @@ module Impl { * The Boolean `cc` records whether the node is reached through an * argument in a call. */ - pragma[assume_small_delta] private predicate fwdFlow(NodeEx node, Cc cc) { sourceNode(node, _) and if hasSourceCallCtx() then cc = true else cc = false @@ -570,7 +569,6 @@ module Impl { /** * Holds if `c` is the target of a store in the flow covered by `fwdFlow`. */ - pragma[assume_small_delta] pragma[nomagic] private predicate fwdFlowConsCand(Content c) { exists(NodeEx mid, NodeEx node | @@ -1216,7 +1214,6 @@ module Impl { fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } - pragma[assume_small_delta] pragma[nomagic] private predicate fwdFlow0( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, @@ -2777,7 +2774,6 @@ module Impl { /** * Gets the number of `AccessPath`s that correspond to `apa`. */ - pragma[assume_small_delta] private int countAps(AccessPathApprox apa) { evalUnfold(apa, false) and result = 1 and @@ -2796,7 +2792,6 @@ module Impl { * that it is expanded to a precise head-tail representation. */ language[monotonicAggregates] - pragma[assume_small_delta] private int countPotentialAps(AccessPathApprox apa) { apa instanceof AccessPathApproxNil and result = 1 or @@ -2833,7 +2828,6 @@ module Impl { } private newtype TPathNode = - pragma[assume_small_delta] TPathNodeMid( NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap ) { @@ -2918,7 +2912,6 @@ module Impl { override AccessPathFrontHead getFront() { result = TFrontHead(head_) } - pragma[assume_small_delta] override AccessPathApproxCons getApprox() { result = TConsNil(head_, t) and tail_ = TAccessPathNil() or @@ -2927,7 +2920,6 @@ module Impl { result = TCons1(head_, this.length()) } - pragma[assume_small_delta] override int length() { result = 1 + tail_.length() } private string toStringImpl(boolean needsSuffix) { @@ -3379,7 +3371,6 @@ module Impl { * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ - pragma[assume_small_delta] pragma[nomagic] private predicate pathStep0( PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, @@ -3592,7 +3583,6 @@ module Impl { ) } - pragma[assume_small_delta] pragma[nomagic] private predicate pathThroughCallable0( DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, FlowState state, CallContext cc, diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll index 0d4c033c95d..aff14e7b44d 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll @@ -187,7 +187,6 @@ private module LambdaFlow { else any() } - pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlow0( DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, @@ -274,7 +273,6 @@ private module LambdaFlow { ) } - pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlowOut( DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll index 9ea7c44c50c..d62ed3f2c13 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll @@ -110,7 +110,6 @@ module Public { } /** Gets the stack obtained by dropping the first `i` elements, if any. */ - pragma[assume_small_delta] SummaryComponentStack drop(int i) { i = 0 and result = this or diff --git a/ql/ql/test/printAst/Foo.qll b/ql/ql/test/printAst/Foo.qll index 0a28779092b..0c7f4689428 100644 --- a/ql/ql/test/printAst/Foo.qll +++ b/ql/ql/test/printAst/Foo.qll @@ -26,11 +26,8 @@ predicate calls(Foo f) { true = false } -newtype TPathNode = - pragma[assume_small_delta] - TPathNodeMid() +newtype TPathNode = TPathNodeMid() private newtype TPathNode2 = - pragma[assume_small_delta] TPathNodeMid2(boolean foo) { foo = true } or TPathNodeSink(string bar) { bar = "bar" } diff --git a/ql/ql/test/printAst/printAst.expected b/ql/ql/test/printAst/printAst.expected index 2194cf06864..88f3af7c09a 100644 --- a/ql/ql/test/printAst/printAst.expected +++ b/ql/ql/test/printAst/printAst.expected @@ -1,8 +1,8 @@ nodes | Foo.qll:1:1:1:17 | Import | semmle.label | [Import] Import | | Foo.qll:1:1:1:17 | Import | semmle.order | 1 | -| Foo.qll:1:1:36:44 | TopLevel | semmle.label | [TopLevel] TopLevel | -| Foo.qll:1:1:36:44 | TopLevel | semmle.order | 1 | +| Foo.qll:1:1:33:44 | TopLevel | semmle.label | [TopLevel] TopLevel | +| Foo.qll:1:1:33:44 | TopLevel | semmle.order | 1 | | Foo.qll:1:8:1:17 | javascript | semmle.label | [ModuleExpr] javascript | | Foo.qll:1:8:1:17 | javascript | semmle.order | 3 | | Foo.qll:3:7:3:9 | Class Foo | semmle.label | [Class] Class Foo | @@ -155,44 +155,36 @@ nodes | Foo.qll:26:10:26:14 | Boolean | semmle.order | 77 | | Foo.qll:29:9:29:17 | NewType TPathNode | semmle.label | [NewType] NewType TPathNode | | Foo.qll:29:9:29:17 | NewType TPathNode | semmle.order | 78 | -| Foo.qll:30:3:30:28 | annotation | semmle.label | [Annotation] annotation | -| Foo.qll:30:3:30:28 | annotation | semmle.order | 79 | -| Foo.qll:30:10:30:27 | assume_small_delta | semmle.label | [AnnotationArg] assume_small_delta | -| Foo.qll:30:10:30:27 | assume_small_delta | semmle.order | 80 | -| Foo.qll:31:3:31:14 | NewTypeBranch TPathNodeMid | semmle.label | [NewTypeBranch] NewTypeBranch TPathNodeMid | -| Foo.qll:31:3:31:14 | NewTypeBranch TPathNodeMid | semmle.order | 81 | -| Foo.qll:33:1:33:7 | annotation | semmle.label | [Annotation] annotation | -| Foo.qll:33:1:33:7 | annotation | semmle.order | 82 | -| Foo.qll:33:17:33:26 | NewType TPathNode2 | semmle.label | [NewType] NewType TPathNode2 | -| Foo.qll:33:17:33:26 | NewType TPathNode2 | semmle.order | 83 | -| Foo.qll:34:3:34:28 | annotation | semmle.label | [Annotation] annotation | -| Foo.qll:34:3:34:28 | annotation | semmle.order | 84 | -| Foo.qll:34:10:34:27 | assume_small_delta | semmle.label | [AnnotationArg] assume_small_delta | -| Foo.qll:34:10:34:27 | assume_small_delta | semmle.order | 85 | -| Foo.qll:35:3:35:15 | NewTypeBranch TPathNodeMid2 | semmle.label | [NewTypeBranch] NewTypeBranch TPathNodeMid2 | -| Foo.qll:35:3:35:15 | NewTypeBranch TPathNodeMid2 | semmle.order | 86 | -| Foo.qll:35:17:35:23 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | -| Foo.qll:35:17:35:23 | TypeExpr | semmle.order | 87 | -| Foo.qll:35:17:35:27 | foo | semmle.label | [VarDecl] foo | -| Foo.qll:35:17:35:27 | foo | semmle.order | 87 | -| Foo.qll:35:32:35:34 | foo | semmle.label | [VarAccess] foo | -| Foo.qll:35:32:35:34 | foo | semmle.order | 89 | -| Foo.qll:35:32:35:41 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula | -| Foo.qll:35:32:35:41 | ComparisonFormula | semmle.order | 89 | -| Foo.qll:35:38:35:41 | Boolean | semmle.label | [Boolean] Boolean | -| Foo.qll:35:38:35:41 | Boolean | semmle.order | 91 | -| Foo.qll:36:3:36:15 | NewTypeBranch TPathNodeSink | semmle.label | [NewTypeBranch] NewTypeBranch TPathNodeSink | -| Foo.qll:36:3:36:15 | NewTypeBranch TPathNodeSink | semmle.order | 92 | -| Foo.qll:36:17:36:22 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | -| Foo.qll:36:17:36:22 | TypeExpr | semmle.order | 93 | -| Foo.qll:36:17:36:26 | bar | semmle.label | [VarDecl] bar | -| Foo.qll:36:17:36:26 | bar | semmle.order | 93 | -| Foo.qll:36:31:36:33 | bar | semmle.label | [VarAccess] bar | -| Foo.qll:36:31:36:33 | bar | semmle.order | 95 | -| Foo.qll:36:31:36:41 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula | -| Foo.qll:36:31:36:41 | ComparisonFormula | semmle.order | 95 | -| Foo.qll:36:37:36:41 | String | semmle.label | [String] String | -| Foo.qll:36:37:36:41 | String | semmle.order | 97 | +| Foo.qll:29:21:29:32 | NewTypeBranch TPathNodeMid | semmle.label | [NewTypeBranch] NewTypeBranch TPathNodeMid | +| Foo.qll:29:21:29:32 | NewTypeBranch TPathNodeMid | semmle.order | 79 | +| Foo.qll:31:1:31:7 | annotation | semmle.label | [Annotation] annotation | +| Foo.qll:31:1:31:7 | annotation | semmle.order | 80 | +| Foo.qll:31:17:31:26 | NewType TPathNode2 | semmle.label | [NewType] NewType TPathNode2 | +| Foo.qll:31:17:31:26 | NewType TPathNode2 | semmle.order | 81 | +| Foo.qll:32:3:32:15 | NewTypeBranch TPathNodeMid2 | semmle.label | [NewTypeBranch] NewTypeBranch TPathNodeMid2 | +| Foo.qll:32:3:32:15 | NewTypeBranch TPathNodeMid2 | semmle.order | 82 | +| Foo.qll:32:17:32:23 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | +| Foo.qll:32:17:32:23 | TypeExpr | semmle.order | 83 | +| Foo.qll:32:17:32:27 | foo | semmle.label | [VarDecl] foo | +| Foo.qll:32:17:32:27 | foo | semmle.order | 83 | +| Foo.qll:32:32:32:34 | foo | semmle.label | [VarAccess] foo | +| Foo.qll:32:32:32:34 | foo | semmle.order | 85 | +| Foo.qll:32:32:32:41 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula | +| Foo.qll:32:32:32:41 | ComparisonFormula | semmle.order | 85 | +| Foo.qll:32:38:32:41 | Boolean | semmle.label | [Boolean] Boolean | +| Foo.qll:32:38:32:41 | Boolean | semmle.order | 87 | +| Foo.qll:33:3:33:15 | NewTypeBranch TPathNodeSink | semmle.label | [NewTypeBranch] NewTypeBranch TPathNodeSink | +| Foo.qll:33:3:33:15 | NewTypeBranch TPathNodeSink | semmle.order | 88 | +| Foo.qll:33:17:33:22 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | +| Foo.qll:33:17:33:22 | TypeExpr | semmle.order | 89 | +| Foo.qll:33:17:33:26 | bar | semmle.label | [VarDecl] bar | +| Foo.qll:33:17:33:26 | bar | semmle.order | 89 | +| Foo.qll:33:31:33:33 | bar | semmle.label | [VarAccess] bar | +| Foo.qll:33:31:33:33 | bar | semmle.order | 91 | +| Foo.qll:33:31:33:41 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula | +| Foo.qll:33:31:33:41 | ComparisonFormula | semmle.order | 91 | +| Foo.qll:33:37:33:41 | String | semmle.label | [String] String | +| Foo.qll:33:37:33:41 | String | semmle.order | 93 | | file://:0:0:0:0 | abs | semmle.label | [BuiltinPredicate] abs | | file://:0:0:0:0 | abs | semmle.label | [BuiltinPredicate] abs | | file://:0:0:0:0 | acos | semmle.label | [BuiltinPredicate] acos | @@ -275,26 +267,26 @@ nodes | file://:0:0:0:0 | trim | semmle.label | [BuiltinPredicate] trim | | file://:0:0:0:0 | ulp | semmle.label | [BuiltinPredicate] ulp | | printAst.ql:1:1:1:28 | Import | semmle.label | [Import] Import | -| printAst.ql:1:1:1:28 | Import | semmle.order | 98 | +| printAst.ql:1:1:1:28 | Import | semmle.order | 94 | | printAst.ql:1:1:1:29 | TopLevel | semmle.label | [TopLevel] TopLevel | -| printAst.ql:1:1:1:29 | TopLevel | semmle.order | 98 | +| printAst.ql:1:1:1:29 | TopLevel | semmle.order | 94 | | printAst.ql:1:18:1:28 | printAstAst | semmle.label | [ModuleExpr] printAstAst | -| printAst.ql:1:18:1:28 | printAstAst | semmle.order | 100 | +| printAst.ql:1:18:1:28 | printAstAst | semmle.order | 96 | edges | Foo.qll:1:1:1:17 | Import | Foo.qll:1:8:1:17 | javascript | semmle.label | getModuleExpr() | | Foo.qll:1:1:1:17 | Import | Foo.qll:1:8:1:17 | javascript | semmle.order | 3 | -| Foo.qll:1:1:36:44 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.label | getAnImport() | -| Foo.qll:1:1:36:44 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.order | 1 | -| Foo.qll:1:1:36:44 | TopLevel | Foo.qll:3:7:3:9 | Class Foo | semmle.label | getAClass() | -| Foo.qll:1:1:36:44 | TopLevel | Foo.qll:3:7:3:9 | Class Foo | semmle.order | 4 | -| Foo.qll:1:1:36:44 | TopLevel | Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.label | getAPredicate() | -| Foo.qll:1:1:36:44 | TopLevel | Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.order | 16 | -| Foo.qll:1:1:36:44 | TopLevel | Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.label | getAPredicate() | -| Foo.qll:1:1:36:44 | TopLevel | Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.order | 32 | -| Foo.qll:1:1:36:44 | TopLevel | Foo.qll:29:9:29:17 | NewType TPathNode | semmle.label | getANewType() | -| Foo.qll:1:1:36:44 | TopLevel | Foo.qll:29:9:29:17 | NewType TPathNode | semmle.order | 78 | -| Foo.qll:1:1:36:44 | TopLevel | Foo.qll:33:17:33:26 | NewType TPathNode2 | semmle.label | getANewType() | -| Foo.qll:1:1:36:44 | TopLevel | Foo.qll:33:17:33:26 | NewType TPathNode2 | semmle.order | 83 | +| Foo.qll:1:1:33:44 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.label | getAnImport() | +| Foo.qll:1:1:33:44 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.order | 1 | +| Foo.qll:1:1:33:44 | TopLevel | Foo.qll:3:7:3:9 | Class Foo | semmle.label | getAClass() | +| Foo.qll:1:1:33:44 | TopLevel | Foo.qll:3:7:3:9 | Class Foo | semmle.order | 4 | +| Foo.qll:1:1:33:44 | TopLevel | Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.label | getAPredicate() | +| Foo.qll:1:1:33:44 | TopLevel | Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.order | 16 | +| Foo.qll:1:1:33:44 | TopLevel | Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.label | getAPredicate() | +| Foo.qll:1:1:33:44 | TopLevel | Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.order | 32 | +| Foo.qll:1:1:33:44 | TopLevel | Foo.qll:29:9:29:17 | NewType TPathNode | semmle.label | getANewType() | +| Foo.qll:1:1:33:44 | TopLevel | Foo.qll:29:9:29:17 | NewType TPathNode | semmle.order | 78 | +| Foo.qll:1:1:33:44 | TopLevel | Foo.qll:31:17:31:26 | NewType TPathNode2 | semmle.label | getANewType() | +| Foo.qll:1:1:33:44 | TopLevel | Foo.qll:31:17:31:26 | NewType TPathNode2 | semmle.order | 81 | | Foo.qll:3:7:3:9 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.label | getASuperType() | | Foo.qll:3:7:3:9 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.order | 5 | | Foo.qll:3:7:3:9 | Class Foo | Foo.qll:4:3:4:17 | CharPred Foo | semmle.label | getCharPred() | @@ -437,45 +429,37 @@ edges | Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:3:26:6 | Boolean | semmle.order | 75 | | Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:10:26:14 | Boolean | semmle.label | getRightOperand() | | Foo.qll:26:3:26:14 | ComparisonFormula | Foo.qll:26:10:26:14 | Boolean | semmle.order | 77 | -| Foo.qll:29:9:29:17 | NewType TPathNode | Foo.qll:31:3:31:14 | NewTypeBranch TPathNodeMid | semmle.label | getABranch() | -| Foo.qll:29:9:29:17 | NewType TPathNode | Foo.qll:31:3:31:14 | NewTypeBranch TPathNodeMid | semmle.order | 81 | -| Foo.qll:30:3:30:28 | annotation | Foo.qll:30:10:30:27 | assume_small_delta | semmle.label | getArgs(_) | -| Foo.qll:30:3:30:28 | annotation | Foo.qll:30:10:30:27 | assume_small_delta | semmle.order | 80 | -| Foo.qll:31:3:31:14 | NewTypeBranch TPathNodeMid | Foo.qll:30:3:30:28 | annotation | semmle.label | getAnAnnotation() | -| Foo.qll:31:3:31:14 | NewTypeBranch TPathNodeMid | Foo.qll:30:3:30:28 | annotation | semmle.order | 79 | -| Foo.qll:33:17:33:26 | NewType TPathNode2 | Foo.qll:33:1:33:7 | annotation | semmle.label | getAnAnnotation() | -| Foo.qll:33:17:33:26 | NewType TPathNode2 | Foo.qll:33:1:33:7 | annotation | semmle.order | 82 | -| Foo.qll:33:17:33:26 | NewType TPathNode2 | Foo.qll:35:3:35:15 | NewTypeBranch TPathNodeMid2 | semmle.label | getABranch() | -| Foo.qll:33:17:33:26 | NewType TPathNode2 | Foo.qll:35:3:35:15 | NewTypeBranch TPathNodeMid2 | semmle.order | 86 | -| Foo.qll:33:17:33:26 | NewType TPathNode2 | Foo.qll:36:3:36:15 | NewTypeBranch TPathNodeSink | semmle.label | getABranch() | -| Foo.qll:33:17:33:26 | NewType TPathNode2 | Foo.qll:36:3:36:15 | NewTypeBranch TPathNodeSink | semmle.order | 92 | -| Foo.qll:34:3:34:28 | annotation | Foo.qll:34:10:34:27 | assume_small_delta | semmle.label | getArgs(_) | -| Foo.qll:34:3:34:28 | annotation | Foo.qll:34:10:34:27 | assume_small_delta | semmle.order | 85 | -| Foo.qll:35:3:35:15 | NewTypeBranch TPathNodeMid2 | Foo.qll:34:3:34:28 | annotation | semmle.label | getAnAnnotation() | -| Foo.qll:35:3:35:15 | NewTypeBranch TPathNodeMid2 | Foo.qll:34:3:34:28 | annotation | semmle.order | 84 | -| Foo.qll:35:3:35:15 | NewTypeBranch TPathNodeMid2 | Foo.qll:35:17:35:27 | foo | semmle.label | getField(_) | -| Foo.qll:35:3:35:15 | NewTypeBranch TPathNodeMid2 | Foo.qll:35:17:35:27 | foo | semmle.order | 87 | -| Foo.qll:35:3:35:15 | NewTypeBranch TPathNodeMid2 | Foo.qll:35:32:35:41 | ComparisonFormula | semmle.label | getBody() | -| Foo.qll:35:3:35:15 | NewTypeBranch TPathNodeMid2 | Foo.qll:35:32:35:41 | ComparisonFormula | semmle.order | 89 | -| Foo.qll:35:17:35:27 | foo | Foo.qll:35:17:35:23 | TypeExpr | semmle.label | getTypeExpr() | -| Foo.qll:35:17:35:27 | foo | Foo.qll:35:17:35:23 | TypeExpr | semmle.order | 87 | -| Foo.qll:35:32:35:41 | ComparisonFormula | Foo.qll:35:32:35:34 | foo | semmle.label | getLeftOperand() | -| Foo.qll:35:32:35:41 | ComparisonFormula | Foo.qll:35:32:35:34 | foo | semmle.order | 89 | -| Foo.qll:35:32:35:41 | ComparisonFormula | Foo.qll:35:38:35:41 | Boolean | semmle.label | getRightOperand() | -| Foo.qll:35:32:35:41 | ComparisonFormula | Foo.qll:35:38:35:41 | Boolean | semmle.order | 91 | -| Foo.qll:36:3:36:15 | NewTypeBranch TPathNodeSink | Foo.qll:36:17:36:26 | bar | semmle.label | getField(_) | -| Foo.qll:36:3:36:15 | NewTypeBranch TPathNodeSink | Foo.qll:36:17:36:26 | bar | semmle.order | 93 | -| Foo.qll:36:3:36:15 | NewTypeBranch TPathNodeSink | Foo.qll:36:31:36:41 | ComparisonFormula | semmle.label | getBody() | -| Foo.qll:36:3:36:15 | NewTypeBranch TPathNodeSink | Foo.qll:36:31:36:41 | ComparisonFormula | semmle.order | 95 | -| Foo.qll:36:17:36:26 | bar | Foo.qll:36:17:36:22 | TypeExpr | semmle.label | getTypeExpr() | -| Foo.qll:36:17:36:26 | bar | Foo.qll:36:17:36:22 | TypeExpr | semmle.order | 93 | -| Foo.qll:36:31:36:41 | ComparisonFormula | Foo.qll:36:31:36:33 | bar | semmle.label | getLeftOperand() | -| Foo.qll:36:31:36:41 | ComparisonFormula | Foo.qll:36:31:36:33 | bar | semmle.order | 95 | -| Foo.qll:36:31:36:41 | ComparisonFormula | Foo.qll:36:37:36:41 | String | semmle.label | getRightOperand() | -| Foo.qll:36:31:36:41 | ComparisonFormula | Foo.qll:36:37:36:41 | String | semmle.order | 97 | +| Foo.qll:29:9:29:17 | NewType TPathNode | Foo.qll:29:21:29:32 | NewTypeBranch TPathNodeMid | semmle.label | getABranch() | +| Foo.qll:29:9:29:17 | NewType TPathNode | Foo.qll:29:21:29:32 | NewTypeBranch TPathNodeMid | semmle.order | 79 | +| Foo.qll:31:17:31:26 | NewType TPathNode2 | Foo.qll:31:1:31:7 | annotation | semmle.label | getAnAnnotation() | +| Foo.qll:31:17:31:26 | NewType TPathNode2 | Foo.qll:31:1:31:7 | annotation | semmle.order | 80 | +| Foo.qll:31:17:31:26 | NewType TPathNode2 | Foo.qll:32:3:32:15 | NewTypeBranch TPathNodeMid2 | semmle.label | getABranch() | +| Foo.qll:31:17:31:26 | NewType TPathNode2 | Foo.qll:32:3:32:15 | NewTypeBranch TPathNodeMid2 | semmle.order | 82 | +| Foo.qll:31:17:31:26 | NewType TPathNode2 | Foo.qll:33:3:33:15 | NewTypeBranch TPathNodeSink | semmle.label | getABranch() | +| Foo.qll:31:17:31:26 | NewType TPathNode2 | Foo.qll:33:3:33:15 | NewTypeBranch TPathNodeSink | semmle.order | 88 | +| Foo.qll:32:3:32:15 | NewTypeBranch TPathNodeMid2 | Foo.qll:32:17:32:27 | foo | semmle.label | getField(_) | +| Foo.qll:32:3:32:15 | NewTypeBranch TPathNodeMid2 | Foo.qll:32:17:32:27 | foo | semmle.order | 83 | +| Foo.qll:32:3:32:15 | NewTypeBranch TPathNodeMid2 | Foo.qll:32:32:32:41 | ComparisonFormula | semmle.label | getBody() | +| Foo.qll:32:3:32:15 | NewTypeBranch TPathNodeMid2 | Foo.qll:32:32:32:41 | ComparisonFormula | semmle.order | 85 | +| Foo.qll:32:17:32:27 | foo | Foo.qll:32:17:32:23 | TypeExpr | semmle.label | getTypeExpr() | +| Foo.qll:32:17:32:27 | foo | Foo.qll:32:17:32:23 | TypeExpr | semmle.order | 83 | +| Foo.qll:32:32:32:41 | ComparisonFormula | Foo.qll:32:32:32:34 | foo | semmle.label | getLeftOperand() | +| Foo.qll:32:32:32:41 | ComparisonFormula | Foo.qll:32:32:32:34 | foo | semmle.order | 85 | +| Foo.qll:32:32:32:41 | ComparisonFormula | Foo.qll:32:38:32:41 | Boolean | semmle.label | getRightOperand() | +| Foo.qll:32:32:32:41 | ComparisonFormula | Foo.qll:32:38:32:41 | Boolean | semmle.order | 87 | +| Foo.qll:33:3:33:15 | NewTypeBranch TPathNodeSink | Foo.qll:33:17:33:26 | bar | semmle.label | getField(_) | +| Foo.qll:33:3:33:15 | NewTypeBranch TPathNodeSink | Foo.qll:33:17:33:26 | bar | semmle.order | 89 | +| Foo.qll:33:3:33:15 | NewTypeBranch TPathNodeSink | Foo.qll:33:31:33:41 | ComparisonFormula | semmle.label | getBody() | +| Foo.qll:33:3:33:15 | NewTypeBranch TPathNodeSink | Foo.qll:33:31:33:41 | ComparisonFormula | semmle.order | 91 | +| Foo.qll:33:17:33:26 | bar | Foo.qll:33:17:33:22 | TypeExpr | semmle.label | getTypeExpr() | +| Foo.qll:33:17:33:26 | bar | Foo.qll:33:17:33:22 | TypeExpr | semmle.order | 89 | +| Foo.qll:33:31:33:41 | ComparisonFormula | Foo.qll:33:31:33:33 | bar | semmle.label | getLeftOperand() | +| Foo.qll:33:31:33:41 | ComparisonFormula | Foo.qll:33:31:33:33 | bar | semmle.order | 91 | +| Foo.qll:33:31:33:41 | ComparisonFormula | Foo.qll:33:37:33:41 | String | semmle.label | getRightOperand() | +| Foo.qll:33:31:33:41 | ComparisonFormula | Foo.qll:33:37:33:41 | String | semmle.order | 93 | | printAst.ql:1:1:1:28 | Import | printAst.ql:1:18:1:28 | printAstAst | semmle.label | getModuleExpr() | -| printAst.ql:1:1:1:28 | Import | printAst.ql:1:18:1:28 | printAstAst | semmle.order | 100 | +| printAst.ql:1:1:1:28 | Import | printAst.ql:1:18:1:28 | printAstAst | semmle.order | 96 | | printAst.ql:1:1:1:29 | TopLevel | printAst.ql:1:1:1:28 | Import | semmle.label | getAnImport() | -| printAst.ql:1:1:1:29 | TopLevel | printAst.ql:1:1:1:28 | Import | semmle.order | 98 | +| printAst.ql:1:1:1:29 | TopLevel | printAst.ql:1:1:1:28 | Import | semmle.order | 94 | graphProperties | semmle.graphKind | tree | diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index 284fff191ae..410543e0fc9 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -460,7 +460,6 @@ module Impl { * The Boolean `cc` records whether the node is reached through an * argument in a call. */ - pragma[assume_small_delta] private predicate fwdFlow(NodeEx node, Cc cc) { sourceNode(node, _) and if hasSourceCallCtx() then cc = true else cc = false @@ -570,7 +569,6 @@ module Impl { /** * Holds if `c` is the target of a store in the flow covered by `fwdFlow`. */ - pragma[assume_small_delta] pragma[nomagic] private predicate fwdFlowConsCand(Content c) { exists(NodeEx mid, NodeEx node | @@ -1216,7 +1214,6 @@ module Impl { fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } - pragma[assume_small_delta] pragma[nomagic] private predicate fwdFlow0( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, @@ -2777,7 +2774,6 @@ module Impl { /** * Gets the number of `AccessPath`s that correspond to `apa`. */ - pragma[assume_small_delta] private int countAps(AccessPathApprox apa) { evalUnfold(apa, false) and result = 1 and @@ -2796,7 +2792,6 @@ module Impl { * that it is expanded to a precise head-tail representation. */ language[monotonicAggregates] - pragma[assume_small_delta] private int countPotentialAps(AccessPathApprox apa) { apa instanceof AccessPathApproxNil and result = 1 or @@ -2833,7 +2828,6 @@ module Impl { } private newtype TPathNode = - pragma[assume_small_delta] TPathNodeMid( NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap ) { @@ -2918,7 +2912,6 @@ module Impl { override AccessPathFrontHead getFront() { result = TFrontHead(head_) } - pragma[assume_small_delta] override AccessPathApproxCons getApprox() { result = TConsNil(head_, t) and tail_ = TAccessPathNil() or @@ -2927,7 +2920,6 @@ module Impl { result = TCons1(head_, this.length()) } - pragma[assume_small_delta] override int length() { result = 1 + tail_.length() } private string toStringImpl(boolean needsSuffix) { @@ -3379,7 +3371,6 @@ module Impl { * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ - pragma[assume_small_delta] pragma[nomagic] private predicate pathStep0( PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, @@ -3592,7 +3583,6 @@ module Impl { ) } - pragma[assume_small_delta] pragma[nomagic] private predicate pathThroughCallable0( DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, FlowState state, CallContext cc, diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll index 0d4c033c95d..aff14e7b44d 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll @@ -187,7 +187,6 @@ private module LambdaFlow { else any() } - pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlow0( DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, @@ -274,7 +273,6 @@ private module LambdaFlow { ) } - pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlowOut( DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll index 9ea7c44c50c..d62ed3f2c13 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll @@ -110,7 +110,6 @@ module Public { } /** Gets the stack obtained by dropping the first `i` elements, if any. */ - pragma[assume_small_delta] SummaryComponentStack drop(int i) { i = 0 and result = this or diff --git a/shared/typetracking/codeql/typetracking/TypeTracking.qll b/shared/typetracking/codeql/typetracking/TypeTracking.qll index 5ab814e0ddd..24411405c65 100644 --- a/shared/typetracking/codeql/typetracking/TypeTracking.qll +++ b/shared/typetracking/codeql/typetracking/TypeTracking.qll @@ -803,7 +803,6 @@ module TypeTracking { * those sources. */ module TypeTrack { - pragma[assume_small_delta] private Node flow(TypeTracker tt) { tt.start() and source(result) or diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index 284fff191ae..410543e0fc9 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -460,7 +460,6 @@ module Impl { * The Boolean `cc` records whether the node is reached through an * argument in a call. */ - pragma[assume_small_delta] private predicate fwdFlow(NodeEx node, Cc cc) { sourceNode(node, _) and if hasSourceCallCtx() then cc = true else cc = false @@ -570,7 +569,6 @@ module Impl { /** * Holds if `c` is the target of a store in the flow covered by `fwdFlow`. */ - pragma[assume_small_delta] pragma[nomagic] private predicate fwdFlowConsCand(Content c) { exists(NodeEx mid, NodeEx node | @@ -1216,7 +1214,6 @@ module Impl { fwdFlow1(_, _, _, _, _, _, t0, t, ap, _) and t0 != t } - pragma[assume_small_delta] pragma[nomagic] private predicate fwdFlow0( NodeEx node, FlowState state, Cc cc, ParamNodeOption summaryCtx, TypOption argT, @@ -2777,7 +2774,6 @@ module Impl { /** * Gets the number of `AccessPath`s that correspond to `apa`. */ - pragma[assume_small_delta] private int countAps(AccessPathApprox apa) { evalUnfold(apa, false) and result = 1 and @@ -2796,7 +2792,6 @@ module Impl { * that it is expanded to a precise head-tail representation. */ language[monotonicAggregates] - pragma[assume_small_delta] private int countPotentialAps(AccessPathApprox apa) { apa instanceof AccessPathApproxNil and result = 1 or @@ -2833,7 +2828,6 @@ module Impl { } private newtype TPathNode = - pragma[assume_small_delta] TPathNodeMid( NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, AccessPath ap ) { @@ -2918,7 +2912,6 @@ module Impl { override AccessPathFrontHead getFront() { result = TFrontHead(head_) } - pragma[assume_small_delta] override AccessPathApproxCons getApprox() { result = TConsNil(head_, t) and tail_ = TAccessPathNil() or @@ -2927,7 +2920,6 @@ module Impl { result = TCons1(head_, this.length()) } - pragma[assume_small_delta] override int length() { result = 1 + tail_.length() } private string toStringImpl(boolean needsSuffix) { @@ -3379,7 +3371,6 @@ module Impl { * Holds if data may flow from `mid` to `node`. The last step in or out of * a callable is recorded by `cc`. */ - pragma[assume_small_delta] pragma[nomagic] private predicate pathStep0( PathNodeMid mid, NodeEx node, FlowState state, CallContext cc, SummaryCtx sc, DataFlowType t, @@ -3592,7 +3583,6 @@ module Impl { ) } - pragma[assume_small_delta] pragma[nomagic] private predicate pathThroughCallable0( DataFlowCall call, PathNodeMid mid, ReturnKindExt kind, FlowState state, CallContext cc, diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll index 0d4c033c95d..aff14e7b44d 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll @@ -187,7 +187,6 @@ private module LambdaFlow { else any() } - pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlow0( DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, @@ -274,7 +273,6 @@ private module LambdaFlow { ) } - pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlowOut( DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll index 9ea7c44c50c..d62ed3f2c13 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll @@ -110,7 +110,6 @@ module Public { } /** Gets the stack obtained by dropping the first `i` elements, if any. */ - pragma[assume_small_delta] SummaryComponentStack drop(int i) { i = 0 and result = this or From fcf003ceb5f999b372a883eda014a6e8a36275e9 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Fri, 30 Jun 2023 19:32:37 +0100 Subject: [PATCH 049/118] Revert "Kotlin: Remove a use of ObsoleteDescriptorBasedAPI" This reverts commit a50d804ad710e0e314afc823ae2c10f334be8655. --- .../src/main/kotlin/KotlinFileExtractor.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index ef7fafc913a..6e5d921a406 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -157,10 +157,21 @@ open class KotlinFileExtractor( else -> false } + @OptIn(ObsoleteDescriptorBasedAPI::class) private fun isFake(d: IrDeclarationWithVisibility): Boolean { val hasFakeVisibility = d.visibility.let { it is DelegatedDescriptorVisibility && it.delegate == Visibilities.InvisibleFake } || d.isFakeOverride if (hasFakeVisibility && !isJavaBinaryObjectMethodRedeclaration(d)) return true + try { + if ((d as? IrFunction)?.descriptor?.isHiddenToOvercomeSignatureClash == true) { + return true + } + } + catch (e: NotImplementedError) { + // `org.jetbrains.kotlin.ir.descriptors.IrBasedClassConstructorDescriptor.isHiddenToOvercomeSignatureClash` throws the exception + logger.warnElement("Couldn't query if element is fake, deciding it's not.", d, e) + return false + } return false } From bd400be6ec3f30b622348940d4f9f4db6d984312 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Sat, 1 Jul 2023 20:28:31 +0200 Subject: [PATCH 050/118] add FP for incomplete-multi-char-sanitization --- .../IncompleteMultiCharacterSanitization.expected | 1 + .../IncompleteSanitization/tst-multi-character-sanitization.js | 2 ++ 2 files changed, 3 insertions(+) diff --git a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteMultiCharacterSanitization.expected b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteMultiCharacterSanitization.expected index 32400608814..0d385ca78c7 100644 --- a/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteMultiCharacterSanitization.expected +++ b/javascript/ql/test/query-tests/Security/CWE-116/IncompleteSanitization/IncompleteMultiCharacterSanitization.expected @@ -39,3 +39,4 @@ | tst-multi-character-sanitization.js:145:13:145:90 | content ... /g, '') | This string may still contain $@, which may cause an HTML element injection vulnerability. | tst-multi-character-sanitization.js:145:30:145:30 | < |