From 48b90b28c70dd19d228d01f56fb03679f4846b62 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 5 Mar 2025 00:01:08 -0500 Subject: [PATCH 01/16] Component parameter passing step --- .../microsoft/aspnetcore/Components.qll | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll index 6e37fc0480fb..806ac7fa9030 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll @@ -112,6 +112,16 @@ class MicrosoftAspNetCoreComponentsComponent extends Class { } } +/** + * The `Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder::AddComponentParameter` method. + */ +private class MicrosoftAspNetCoreComponentsAddComponentParameterMethod extends Method { + MicrosoftAspNetCoreComponentsAddComponentParameterMethod() { + this.hasFullyQualifiedName("Microsoft.AspNetCore.Components.Rendering", "RenderTreeBuilder", + "AddComponentParameter") + } +} + private module Sources { private import semmle.code.csharp.security.dataflow.flowsources.Remote @@ -133,3 +143,42 @@ private module Sources { override string getSourceType() { result = "ASP.NET Core component route parameter" } } } + +private module JumpNodes { + /** + * A call to `Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder::AddComponentParameter` which + * sets the value of a parameter. + */ + private class ParameterPassingCall extends Call { + ParameterPassingCall() { + this.getTarget() instanceof MicrosoftAspNetCoreComponentsAddComponentParameterMethod + } + + /** + * Gets the property whose value is being set. + */ + Property getParameterProperty() { + result.getAnAttribute() instanceof MicrosoftAspNetCoreComponentsParameterAttribute and + exists(NameOfExpr ne | ne = this.getArgument(1) | + result.getAnAccess() = ne.getAccess().(MemberAccess) + ) + } + + /** + * Gets the value being set. + */ + Expr getParameterValue() { result = this.getArgument(2) } + } + + private class ComponentParameterJump extends DataFlow::NonLocalJumpNode { + ParameterPassingCall call; + + ComponentParameterJump() { this.asExpr() = call.getParameterValue() } + + override DataFlow::Node getAJumpSuccessor(boolean preservesValue) { + preservesValue = false and + result.asExpr() = call.getParameterProperty().getAnAccess() + } + } +} + From 0463f48565a95b0f43ac331db02a65889d9f98ee Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 5 Mar 2025 00:37:33 -0500 Subject: [PATCH 02/16] Add Name and NameList test classes --- .../microsoft/aspnetcore/blazor/Name.cs | 22 ++++++++ .../microsoft/aspnetcore/blazor/NameList.cs | 50 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/Name.cs create mode 100644 csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/NameList.cs diff --git a/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/Name.cs b/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/Name.cs new file mode 100644 index 000000000000..a9d098470e44 --- /dev/null +++ b/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/Name.cs @@ -0,0 +1,22 @@ +namespace VulnerableBlazorApp.Components +{ + using Microsoft.AspNetCore.Components; + + public partial class Name : Microsoft.AspNetCore.Components.ComponentBase + { + protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) + { + if (TheName is not null) + { + builder.OpenElement(0, "div"); + builder.OpenElement(1, "p"); + builder.AddContent(2, (MarkupString)TheName); + builder.CloseElement(); + builder.CloseElement(); + } + } + + [Parameter] + public string TheName { get; set; } + } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/NameList.cs b/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/NameList.cs new file mode 100644 index 000000000000..ceffb35303e5 --- /dev/null +++ b/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/NameList.cs @@ -0,0 +1,50 @@ +namespace VulnerableBlazorApp.Components +{ + using System.Collections.Generic; + using Microsoft.AspNetCore.Components; + + [RouteAttribute("/names/{name?}")] + public partial class NameList : Microsoft.AspNetCore.Components.ComponentBase + { + protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) + { + if (Names is not null) + { + builder.OpenElement(0, "div"); + builder.OpenElement(1, "ul"); + foreach (var name in Names) + { + builder.OpenElement(2, "li"); + builder.OpenComponent(3); + builder.AddComponentParameter(4, nameof(VulnerableBlazorApp.Components.Name.TheName), name); + builder.CloseComponent(); + builder.CloseElement(); + } + builder.CloseElement(); + builder.CloseElement(); + } + + builder.OpenElement(5, "div"); + builder.OpenElement(6, "p"); + builder.AddContent(7, "Name: "); + builder.OpenComponent(8); + builder.AddComponentParameter(9, nameof(VulnerableBlazorApp.Components.Name.TheName), Name); + builder.CloseComponent(); + builder.CloseElement(); + } + + [Parameter] + public string Name { get; set; } + + protected override void OnParametersSet() + { + if (Name is not null) + { + Names.Add(Name); + } + } + + + public List Names { get; set; } = new List(); + } +} \ No newline at end of file From 17da291910fe6838f14002470fa2daffb3e7a430 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 5 Mar 2025 00:50:19 -0500 Subject: [PATCH 03/16] fixup! Component parameter passing step --- .../frameworks/microsoft/aspnetcore/Components.qll | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll index 806ac7fa9030..f468487498cc 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll @@ -172,11 +172,16 @@ private module JumpNodes { private class ComponentParameterJump extends DataFlow::NonLocalJumpNode { ParameterPassingCall call; + Property prop; - ComponentParameterJump() { this.asExpr() = call.getParameterValue() } + ComponentParameterJump() { + prop = call.getParameterProperty() and + // this.(DataFlowPrivate::PostUpdateNode).getPreUpdateNode().asExpr() = call.getParameterValue() + this.asExpr() = call.getParameterValue() + } override DataFlow::Node getAJumpSuccessor(boolean preservesValue) { - preservesValue = false and + preservesValue = true and result.asExpr() = call.getParameterProperty().getAnAccess() } } From 824b182ca5de47e9f7c807fa9112b3200b75484e Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 5 Mar 2025 00:50:42 -0500 Subject: [PATCH 04/16] fixup! Add Name and NameList test classes --- .../microsoft/aspnetcore/blazor/remoteFlowSource.expected | 2 ++ 1 file changed, 2 insertions(+) diff --git a/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/remoteFlowSource.expected b/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/remoteFlowSource.expected index 2c845e8e4001..fc334e8885a3 100644 --- a/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/remoteFlowSource.expected +++ b/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/remoteFlowSource.expected @@ -2,3 +2,5 @@ | Components_Pages_TestPage_razor.g.cs:138:15:138:22 | access to property UrlParam | ASP.NET Core component route parameter | | Components_Pages_TestPage_razor.g.cs:176:1:176:10 | access to property QueryParam | external | | Components_Pages_TestPage_razor.g.cs:188:18:188:27 | access to property QueryParam | external | +| NameList.cs:33:17:33:20 | access to property Name | ASP.NET Core component route parameter | +| NameList.cs:35:27:35:30 | access to property Name | ASP.NET Core component route parameter | From 97e00ae053c6b64d33a7589ec0850ced9b1a53ed Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 5 Mar 2025 00:58:15 -0500 Subject: [PATCH 05/16] Fix formatting --- .../code/csharp/frameworks/microsoft/aspnetcore/Components.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll index f468487498cc..e9e2d1d2debf 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll @@ -186,4 +186,3 @@ private module JumpNodes { } } } - From 8ea697486859cce94b46d2802e7ed472754d2228 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 5 Mar 2025 00:59:51 -0500 Subject: [PATCH 06/16] XSS qlref --- .../frameworks/microsoft/aspnetcore/blazor/Xss.qlref | 1 + 1 file changed, 1 insertion(+) create mode 100644 csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/Xss.qlref diff --git a/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/Xss.qlref b/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/Xss.qlref new file mode 100644 index 000000000000..faad1d6403c1 --- /dev/null +++ b/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/Xss.qlref @@ -0,0 +1 @@ +Security Features/CWE-079/XSS.ql \ No newline at end of file From 22e958b24566f70c8d7677408368aef9ade6c7b7 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 5 Mar 2025 01:08:45 -0500 Subject: [PATCH 07/16] Fix jump node by using associated property --- .../code/csharp/frameworks/microsoft/aspnetcore/Components.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll index e9e2d1d2debf..045e8aaf6719 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll @@ -182,7 +182,7 @@ private module JumpNodes { override DataFlow::Node getAJumpSuccessor(boolean preservesValue) { preservesValue = true and - result.asExpr() = call.getParameterProperty().getAnAccess() + result.asExpr() = prop.getAnAccess() } } } From 133c6fa40048132ba120bee6718d43f5603242d6 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 5 Mar 2025 01:09:19 -0500 Subject: [PATCH 08/16] Fix test expectations --- .../microsoft/aspnetcore/blazor/Xss.expected | 12 ++++++++++++ .../aspnetcore/blazor/remoteFlowSource.expected | 5 +++-- 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/Xss.expected diff --git a/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/Xss.expected b/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/Xss.expected new file mode 100644 index 000000000000..951269f2b580 --- /dev/null +++ b/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/Xss.expected @@ -0,0 +1,12 @@ +edges +| NameList.cs:31:99:31:102 | access to property Name : String | Name.cs:13:53:13:59 | access to property TheName | provenance | Sink:MaD:149 | +nodes +| Components_Pages_TestPage_razor.g.cs:138:15:138:22 | access to property UrlParam | semmle.label | access to property UrlParam | +| Components_Pages_TestPage_razor.g.cs:188:18:188:27 | access to property QueryParam | semmle.label | access to property QueryParam | +| Name.cs:13:53:13:59 | access to property TheName | semmle.label | access to property TheName | +| NameList.cs:31:99:31:102 | access to property Name : String | semmle.label | access to property Name : String | +subpaths +#select +| Components_Pages_TestPage_razor.g.cs:138:15:138:22 | access to property UrlParam | Components_Pages_TestPage_razor.g.cs:138:15:138:22 | access to property UrlParam | Components_Pages_TestPage_razor.g.cs:138:15:138:22 | access to property UrlParam | $@ flows to here and is written to HTML or JavaScript. | Components_Pages_TestPage_razor.g.cs:138:15:138:22 | access to property UrlParam | User-provided value | +| Components_Pages_TestPage_razor.g.cs:188:18:188:27 | access to property QueryParam | Components_Pages_TestPage_razor.g.cs:188:18:188:27 | access to property QueryParam | Components_Pages_TestPage_razor.g.cs:188:18:188:27 | access to property QueryParam | $@ flows to here and is written to HTML or JavaScript. | Components_Pages_TestPage_razor.g.cs:188:18:188:27 | access to property QueryParam | User-provided value | +| Name.cs:13:53:13:59 | access to property TheName | NameList.cs:31:99:31:102 | access to property Name : String | Name.cs:13:53:13:59 | access to property TheName | $@ flows to here and is written to HTML or JavaScript. | NameList.cs:31:99:31:102 | access to property Name : String | User-provided value | diff --git a/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/remoteFlowSource.expected b/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/remoteFlowSource.expected index fc334e8885a3..2a9268cf01e3 100644 --- a/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/remoteFlowSource.expected +++ b/csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/remoteFlowSource.expected @@ -2,5 +2,6 @@ | Components_Pages_TestPage_razor.g.cs:138:15:138:22 | access to property UrlParam | ASP.NET Core component route parameter | | Components_Pages_TestPage_razor.g.cs:176:1:176:10 | access to property QueryParam | external | | Components_Pages_TestPage_razor.g.cs:188:18:188:27 | access to property QueryParam | external | -| NameList.cs:33:17:33:20 | access to property Name | ASP.NET Core component route parameter | -| NameList.cs:35:27:35:30 | access to property Name | ASP.NET Core component route parameter | +| NameList.cs:31:99:31:102 | access to property Name | ASP.NET Core component route parameter | +| NameList.cs:41:17:41:20 | access to property Name | ASP.NET Core component route parameter | +| NameList.cs:43:27:43:30 | access to property Name | ASP.NET Core component route parameter | From a0fe7d6a1a72c317732c7d1569bfe2d8ab990137 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 5 Mar 2025 11:04:41 -0500 Subject: [PATCH 09/16] Remove unused line --- .../code/csharp/frameworks/microsoft/aspnetcore/Components.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll index 045e8aaf6719..d5782b26851a 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll @@ -176,7 +176,6 @@ private module JumpNodes { ComponentParameterJump() { prop = call.getParameterProperty() and - // this.(DataFlowPrivate::PostUpdateNode).getPreUpdateNode().asExpr() = call.getParameterValue() this.asExpr() = call.getParameterValue() } From e2f0a61f89725ff5693c64761f504e6356743112 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 5 Mar 2025 12:40:02 -0500 Subject: [PATCH 10/16] Add XSS test to integration tests --- csharp/ql/integration-tests/all-platforms/blazor/XSS.qlref | 1 + .../all-platforms/blazor_build_mode_none/XSS.qlref | 1 + csharp/ql/integration-tests/all-platforms/blazor_net_8/XSS.qlref | 1 + 3 files changed, 3 insertions(+) create mode 100644 csharp/ql/integration-tests/all-platforms/blazor/XSS.qlref create mode 100644 csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/XSS.qlref create mode 100644 csharp/ql/integration-tests/all-platforms/blazor_net_8/XSS.qlref diff --git a/csharp/ql/integration-tests/all-platforms/blazor/XSS.qlref b/csharp/ql/integration-tests/all-platforms/blazor/XSS.qlref new file mode 100644 index 000000000000..faad1d6403c1 --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/blazor/XSS.qlref @@ -0,0 +1 @@ +Security Features/CWE-079/XSS.ql \ No newline at end of file diff --git a/csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/XSS.qlref b/csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/XSS.qlref new file mode 100644 index 000000000000..faad1d6403c1 --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/XSS.qlref @@ -0,0 +1 @@ +Security Features/CWE-079/XSS.ql \ No newline at end of file diff --git a/csharp/ql/integration-tests/all-platforms/blazor_net_8/XSS.qlref b/csharp/ql/integration-tests/all-platforms/blazor_net_8/XSS.qlref new file mode 100644 index 000000000000..faad1d6403c1 --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/blazor_net_8/XSS.qlref @@ -0,0 +1 @@ +Security Features/CWE-079/XSS.ql \ No newline at end of file From ca14c5722d1d2560be60f5c470e144b0340df593 Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Wed, 5 Mar 2025 12:40:26 -0500 Subject: [PATCH 11/16] Add likely XSS case to integration tests --- .../blazor/BlazorTest/Components/Pages/TestPage.razor | 4 ++++ .../BlazorTest/Components/Pages/TestPage.razor | 4 ++++ .../blazor_net_8/BlazorTest/Components/Pages/TestPage.razor | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/csharp/ql/integration-tests/all-platforms/blazor/BlazorTest/Components/Pages/TestPage.razor b/csharp/ql/integration-tests/all-platforms/blazor/BlazorTest/Components/Pages/TestPage.razor index 39238d724298..ac3ccbe19207 100644 --- a/csharp/ql/integration-tests/all-platforms/blazor/BlazorTest/Components/Pages/TestPage.razor +++ b/csharp/ql/integration-tests/all-platforms/blazor/BlazorTest/Components/Pages/TestPage.razor @@ -81,6 +81,10 @@ +
+ +
+ @code { public class Container diff --git a/csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/BlazorTest/Components/Pages/TestPage.razor b/csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/BlazorTest/Components/Pages/TestPage.razor index 39238d724298..ac3ccbe19207 100644 --- a/csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/BlazorTest/Components/Pages/TestPage.razor +++ b/csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/BlazorTest/Components/Pages/TestPage.razor @@ -81,6 +81,10 @@ +
+ +
+ @code { public class Container diff --git a/csharp/ql/integration-tests/all-platforms/blazor_net_8/BlazorTest/Components/Pages/TestPage.razor b/csharp/ql/integration-tests/all-platforms/blazor_net_8/BlazorTest/Components/Pages/TestPage.razor index 39238d724298..ac3ccbe19207 100644 --- a/csharp/ql/integration-tests/all-platforms/blazor_net_8/BlazorTest/Components/Pages/TestPage.razor +++ b/csharp/ql/integration-tests/all-platforms/blazor_net_8/BlazorTest/Components/Pages/TestPage.razor @@ -81,6 +81,10 @@ +
+ +
+ @code { public class Container From f6968af3ae11f0ab554a06810bea2653b37c96bc Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 26 Mar 2025 11:03:32 +0100 Subject: [PATCH 12/16] Add expected XSS test results --- .../all-platforms/blazor/XSS.expected | 14 ++++++++++++++ .../blazor_build_mode_none/XSS.expected | 14 ++++++++++++++ .../all-platforms/blazor_net_8/XSS.expected | 8 ++++++++ 3 files changed, 36 insertions(+) create mode 100644 csharp/ql/integration-tests/all-platforms/blazor/XSS.expected create mode 100644 csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/XSS.expected create mode 100644 csharp/ql/integration-tests/all-platforms/blazor_net_8/XSS.expected diff --git a/csharp/ql/integration-tests/all-platforms/blazor/XSS.expected b/csharp/ql/integration-tests/all-platforms/blazor/XSS.expected new file mode 100644 index 000000000000..baf5a2e9c78d --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/blazor/XSS.expected @@ -0,0 +1,14 @@ +edges +| BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs:569:16:577:13 | call to method TypeCheck : String | provenance | Src:MaD:146 MaD:142 | +| BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs:569:16:577:13 | call to method TypeCheck : String | BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | provenance | Sink:MaD:148 | +nodes +| BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | semmle.label | access to property Value | +| BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | semmle.label | access to property UrlParam | +| BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | semmle.label | access to property QueryParam | +| BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | semmle.label | access to property QueryParam : String | +| BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs:569:16:577:13 | call to method TypeCheck : String | semmle.label | call to method TypeCheck : String | +subpaths +#select +| BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | User-provided value | +| BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | User-provided value | +| BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | User-provided value | diff --git a/csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/XSS.expected b/csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/XSS.expected new file mode 100644 index 000000000000..dad526f6d9cd --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/XSS.expected @@ -0,0 +1,14 @@ +edges +| BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | test-db/working/razor/AC613014E59A413B9538FF8068364499/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs:569:16:577:13 | call to method TypeCheck : String | provenance | Src:MaD:146 MaD:142 | +| test-db/working/razor/AC613014E59A413B9538FF8068364499/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs:569:16:577:13 | call to method TypeCheck : String | BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | provenance | Sink:MaD:148 | +nodes +| BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | semmle.label | access to property Value | +| BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | semmle.label | access to property UrlParam | +| BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | semmle.label | access to property QueryParam | +| BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | semmle.label | access to property QueryParam : String | +| test-db/working/razor/AC613014E59A413B9538FF8068364499/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs:569:16:577:13 | call to method TypeCheck : String | semmle.label | call to method TypeCheck : String | +subpaths +#select +| BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | User-provided value | +| BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | User-provided value | +| BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | User-provided value | diff --git a/csharp/ql/integration-tests/all-platforms/blazor_net_8/XSS.expected b/csharp/ql/integration-tests/all-platforms/blazor_net_8/XSS.expected new file mode 100644 index 000000000000..931cebe93ba0 --- /dev/null +++ b/csharp/ql/integration-tests/all-platforms/blazor_net_8/XSS.expected @@ -0,0 +1,8 @@ +edges +nodes +| BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | semmle.label | access to property UrlParam | +| BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | semmle.label | access to property QueryParam | +subpaths +#select +| BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | User-provided value | +| BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | User-provided value | From 68f96d39d2989332bf3242c0df7885e8c68f44c2 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 26 Mar 2025 11:42:59 +0100 Subject: [PATCH 13/16] Make working directory name the same on all OS --- .../DotnetSourceGeneratorWrapper.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/DotnetSourceGeneratorWrapper/DotnetSourceGeneratorWrapper.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/DotnetSourceGeneratorWrapper/DotnetSourceGeneratorWrapper.cs index 2feafb8323b5..680802449010 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/DotnetSourceGeneratorWrapper/DotnetSourceGeneratorWrapper.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/DotnetSourceGeneratorWrapper/DotnetSourceGeneratorWrapper.cs @@ -37,7 +37,8 @@ public IEnumerable RunSourceGenerator(IEnumerable additionalFile { try { - var relativePathToCsProj = Path.GetRelativePath(sourceDir, csprojFile); + var relativePathToCsProj = Path.GetRelativePath(sourceDir, csprojFile) + .Replace('\\', '/'); // Ensure we're generating the same hash regardless of the OS var name = FileUtils.ComputeHash($"{relativePathToCsProj}\n{this.GetType().Name}"); using var tempDir = new TemporaryDirectory(Path.Join(FileUtils.GetTemporaryWorkingDirectory(out _), "source-generator"), "source generator temporary", logger); var analyzerConfigPath = Path.Combine(tempDir.DirInfo.FullName, $"{name}.txt"); From 4e37e5add5be3d299ace42d1a72793bdd8f2ce4c Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Wed, 26 Mar 2025 13:50:39 +0100 Subject: [PATCH 14/16] Add change note --- .../lib/change-notes/2025-03-26-blazor-parameter-passing.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 csharp/ql/lib/change-notes/2025-03-26-blazor-parameter-passing.md diff --git a/csharp/ql/lib/change-notes/2025-03-26-blazor-parameter-passing.md b/csharp/ql/lib/change-notes/2025-03-26-blazor-parameter-passing.md new file mode 100644 index 000000000000..9838aa8d44af --- /dev/null +++ b/csharp/ql/lib/change-notes/2025-03-26-blazor-parameter-passing.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Modeled parameter passing between Blazor parent and child components. From d824d24c497011fc53a1b6f811117aacf83577ec Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Thu, 27 Mar 2025 10:31:48 +0100 Subject: [PATCH 15/16] Improve code quality --- .../all-platforms/blazor/XSS.expected | 16 ++++++++++------ .../all-platforms/blazor/XSS.qlref | 3 ++- .../blazor_build_mode_none/XSS.expected | 16 ++++++++++------ .../blazor_build_mode_none/XSS.qlref | 3 ++- .../all-platforms/blazor_net_8/XSS.expected | 6 +++--- .../all-platforms/blazor_net_8/XSS.qlref | 3 ++- .../microsoft/aspnetcore/Components.qll | 11 +++++------ 7 files changed, 34 insertions(+), 24 deletions(-) diff --git a/csharp/ql/integration-tests/all-platforms/blazor/XSS.expected b/csharp/ql/integration-tests/all-platforms/blazor/XSS.expected index baf5a2e9c78d..795e9ad7de08 100644 --- a/csharp/ql/integration-tests/all-platforms/blazor/XSS.expected +++ b/csharp/ql/integration-tests/all-platforms/blazor/XSS.expected @@ -1,6 +1,14 @@ +#select +| BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | User-provided value | +| BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | User-provided value | +| BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | User-provided value | edges -| BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs:569:16:577:13 | call to method TypeCheck : String | provenance | Src:MaD:146 MaD:142 | -| BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs:569:16:577:13 | call to method TypeCheck : String | BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | provenance | Sink:MaD:148 | +| BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs:569:16:577:13 | call to method TypeCheck : String | provenance | Src:MaD:2 MaD:3 | +| BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs:569:16:577:13 | call to method TypeCheck : String | BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | provenance | Sink:MaD:1 | +models +| 1 | Sink: Microsoft.AspNetCore.Components; MarkupString; false; MarkupString; (System.String); ; Argument[0]; html-injection; manual | +| 2 | Source: Microsoft.AspNetCore.Components; SupplyParameterFromQueryAttribute; false; ; ; Attribute.Getter; ReturnValue; remote; manual | +| 3 | Summary: Microsoft.AspNetCore.Components.CompilerServices; RuntimeHelpers; false; TypeCheck; (T); ; Argument[0]; ReturnValue; value; manual | nodes | BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | semmle.label | access to property Value | | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | semmle.label | access to property UrlParam | @@ -8,7 +16,3 @@ nodes | BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | semmle.label | access to property QueryParam : String | | BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs:569:16:577:13 | call to method TypeCheck : String | semmle.label | call to method TypeCheck : String | subpaths -#select -| BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | User-provided value | -| BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | User-provided value | -| BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | User-provided value | diff --git a/csharp/ql/integration-tests/all-platforms/blazor/XSS.qlref b/csharp/ql/integration-tests/all-platforms/blazor/XSS.qlref index faad1d6403c1..89b5b951bdb6 100644 --- a/csharp/ql/integration-tests/all-platforms/blazor/XSS.qlref +++ b/csharp/ql/integration-tests/all-platforms/blazor/XSS.qlref @@ -1 +1,2 @@ -Security Features/CWE-079/XSS.ql \ No newline at end of file +query: Security Features/CWE-079/XSS.ql +postprocess: utils/test/PrettyPrintModels.ql diff --git a/csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/XSS.expected b/csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/XSS.expected index dad526f6d9cd..64ab3e186a1f 100644 --- a/csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/XSS.expected +++ b/csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/XSS.expected @@ -1,6 +1,14 @@ +#select +| BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | User-provided value | +| BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | User-provided value | +| BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | User-provided value | edges -| BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | test-db/working/razor/AC613014E59A413B9538FF8068364499/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs:569:16:577:13 | call to method TypeCheck : String | provenance | Src:MaD:146 MaD:142 | -| test-db/working/razor/AC613014E59A413B9538FF8068364499/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs:569:16:577:13 | call to method TypeCheck : String | BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | provenance | Sink:MaD:148 | +| BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | test-db/working/razor/AC613014E59A413B9538FF8068364499/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs:569:16:577:13 | call to method TypeCheck : String | provenance | Src:MaD:2 MaD:3 | +| test-db/working/razor/AC613014E59A413B9538FF8068364499/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs:569:16:577:13 | call to method TypeCheck : String | BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | provenance | Sink:MaD:1 | +models +| 1 | Sink: Microsoft.AspNetCore.Components; MarkupString; false; MarkupString; (System.String); ; Argument[0]; html-injection; manual | +| 2 | Source: Microsoft.AspNetCore.Components; SupplyParameterFromQueryAttribute; false; ; ; Attribute.Getter; ReturnValue; remote; manual | +| 3 | Summary: Microsoft.AspNetCore.Components.CompilerServices; RuntimeHelpers; false; TypeCheck; (T); ; Argument[0]; ReturnValue; value; manual | nodes | BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | semmle.label | access to property Value | | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | semmle.label | access to property UrlParam | @@ -8,7 +16,3 @@ nodes | BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | semmle.label | access to property QueryParam : String | | test-db/working/razor/AC613014E59A413B9538FF8068364499/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs:569:16:577:13 | call to method TypeCheck : String | semmle.label | call to method TypeCheck : String | subpaths -#select -| BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | User-provided value | -| BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | User-provided value | -| BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | User-provided value | diff --git a/csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/XSS.qlref b/csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/XSS.qlref index faad1d6403c1..89b5b951bdb6 100644 --- a/csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/XSS.qlref +++ b/csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/XSS.qlref @@ -1 +1,2 @@ -Security Features/CWE-079/XSS.ql \ No newline at end of file +query: Security Features/CWE-079/XSS.ql +postprocess: utils/test/PrettyPrintModels.ql diff --git a/csharp/ql/integration-tests/all-platforms/blazor_net_8/XSS.expected b/csharp/ql/integration-tests/all-platforms/blazor_net_8/XSS.expected index 931cebe93ba0..204c31945956 100644 --- a/csharp/ql/integration-tests/all-platforms/blazor_net_8/XSS.expected +++ b/csharp/ql/integration-tests/all-platforms/blazor_net_8/XSS.expected @@ -1,8 +1,8 @@ +#select +| BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | User-provided value | +| BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | User-provided value | edges nodes | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | semmle.label | access to property UrlParam | | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | semmle.label | access to property QueryParam | subpaths -#select -| BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | User-provided value | -| BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | $@ flows to here and is written to HTML or JavaScript. | BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | User-provided value | diff --git a/csharp/ql/integration-tests/all-platforms/blazor_net_8/XSS.qlref b/csharp/ql/integration-tests/all-platforms/blazor_net_8/XSS.qlref index faad1d6403c1..89b5b951bdb6 100644 --- a/csharp/ql/integration-tests/all-platforms/blazor_net_8/XSS.qlref +++ b/csharp/ql/integration-tests/all-platforms/blazor_net_8/XSS.qlref @@ -1 +1,2 @@ -Security Features/CWE-079/XSS.ql \ No newline at end of file +query: Security Features/CWE-079/XSS.ql +postprocess: utils/test/PrettyPrintModels.ql diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll index d5782b26851a..be937661b477 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll @@ -159,9 +159,7 @@ private module JumpNodes { */ Property getParameterProperty() { result.getAnAttribute() instanceof MicrosoftAspNetCoreComponentsParameterAttribute and - exists(NameOfExpr ne | ne = this.getArgument(1) | - result.getAnAccess() = ne.getAccess().(MemberAccess) - ) + exists(NameOfExpr ne | ne = this.getArgument(1) | result.getAnAccess() = ne.getAccess()) } /** @@ -171,12 +169,13 @@ private module JumpNodes { } private class ComponentParameterJump extends DataFlow::NonLocalJumpNode { - ParameterPassingCall call; Property prop; ComponentParameterJump() { - prop = call.getParameterProperty() and - this.asExpr() = call.getParameterValue() + exists(ParameterPassingCall call | + prop = call.getParameterProperty() and + this.asExpr() = call.getParameterValue() + ) } override DataFlow::Node getAJumpSuccessor(boolean preservesValue) { From 42278eb6cfe65037ba4e04bba30e083905e66f50 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Thu, 27 Mar 2025 16:07:09 +0100 Subject: [PATCH 16/16] Add imports for specific jump nodes --- .../code/csharp/dataflow/internal/DataFlowPublic.qll | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll index 877630359fda..b21d5e2c3efb 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll @@ -147,6 +147,16 @@ predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) } pragma[inline] predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(e2)) } +/** + * A module importing the modules that provide non local jump node declarations, + * ensuring that they are visible to the taint tracking / data flow library. + */ +private module JumpNodes { + private import semmle.code.csharp.frameworks.microsoft.aspnetcore.Components + private import semmle.code.csharp.frameworks.Razor + private import semmle.code.csharp.frameworks.NHibernate +} + /** * A data flow node that jumps between callables. This can be extended in * framework code to add additional data flow steps.