Skip to content

Commit 4ff06e4

Browse files
authored
Merge branch 'main' into redsun82/codegen-rename-dbscheme
2 parents 01a69bf + 342d4a6 commit 4ff06e4

File tree

31 files changed

+492
-254
lines changed

31 files changed

+492
-254
lines changed

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/SourceGenerators/DotnetSourceGeneratorWrapper/DotnetSourceGeneratorWrapper.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ public IEnumerable<string> RunSourceGenerator(IEnumerable<string> additionalFile
3737
{
3838
try
3939
{
40-
var relativePathToCsProj = Path.GetRelativePath(sourceDir, csprojFile);
40+
var relativePathToCsProj = Path.GetRelativePath(sourceDir, csprojFile)
41+
.Replace('\\', '/'); // Ensure we're generating the same hash regardless of the OS
4142
var name = FileUtils.ComputeHash($"{relativePathToCsProj}\n{this.GetType().Name}");
4243
using var tempDir = new TemporaryDirectory(Path.Join(FileUtils.GetTemporaryWorkingDirectory(out _), "source-generator"), "source generator temporary", logger);
4344
var analyzerConfigPath = Path.Combine(tempDir.DirInfo.FullName, $"{name}.txt");

csharp/ql/integration-tests/all-platforms/blazor/BlazorTest/Components/Pages/TestPage.razor

+4
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@
8181
<MyOutput Value="@InputValue6" />
8282
</div>
8383

84+
<div>
85+
<MyOutput Value="@QueryParam" />
86+
</div>
87+
8488
@code {
8589

8690
public class Container
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#select
2+
| 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 |
3+
| 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 |
4+
| 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 |
5+
edges
6+
| 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> : String | provenance | Src:MaD:2 MaD:3 |
7+
| 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> : String | BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | provenance | Sink:MaD:1 |
8+
models
9+
| 1 | Sink: Microsoft.AspNetCore.Components; MarkupString; false; MarkupString; (System.String); ; Argument[0]; html-injection; manual |
10+
| 2 | Source: Microsoft.AspNetCore.Components; SupplyParameterFromQueryAttribute; false; ; ; Attribute.Getter; ReturnValue; remote; manual |
11+
| 3 | Summary: Microsoft.AspNetCore.Components.CompilerServices; RuntimeHelpers; false; TypeCheck<T>; (T); ; Argument[0]; ReturnValue; value; manual |
12+
nodes
13+
| BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | semmle.label | access to property Value |
14+
| BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | semmle.label | access to property UrlParam |
15+
| BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | semmle.label | access to property QueryParam |
16+
| BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | semmle.label | access to property QueryParam : String |
17+
| 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> : String | semmle.label | call to method TypeCheck<String> : String |
18+
subpaths
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
query: Security Features/CWE-079/XSS.ql
2+
postprocess: utils/test/PrettyPrintModels.ql

csharp/ql/integration-tests/all-platforms/blazor_build_mode_none/BlazorTest/Components/Pages/TestPage.razor

+4
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@
8181
<MyOutput Value="@InputValue6" />
8282
</div>
8383

84+
<div>
85+
<MyOutput Value="@QueryParam" />
86+
</div>
87+
8488
@code {
8589

8690
public class Container
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#select
2+
| 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 |
3+
| 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 |
4+
| 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 |
5+
edges
6+
| 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> : String | provenance | Src:MaD:2 MaD:3 |
7+
| 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> : String | BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | provenance | Sink:MaD:1 |
8+
models
9+
| 1 | Sink: Microsoft.AspNetCore.Components; MarkupString; false; MarkupString; (System.String); ; Argument[0]; html-injection; manual |
10+
| 2 | Source: Microsoft.AspNetCore.Components; SupplyParameterFromQueryAttribute; false; ; ; Attribute.Getter; ReturnValue; remote; manual |
11+
| 3 | Summary: Microsoft.AspNetCore.Components.CompilerServices; RuntimeHelpers; false; TypeCheck<T>; (T); ; Argument[0]; ReturnValue; value; manual |
12+
nodes
13+
| BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value | semmle.label | access to property Value |
14+
| BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | semmle.label | access to property UrlParam |
15+
| BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | semmle.label | access to property QueryParam |
16+
| BlazorTest/Components/Pages/TestPage.razor:85:23:85:32 | access to property QueryParam : String | semmle.label | access to property QueryParam : String |
17+
| 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> : String | semmle.label | call to method TypeCheck<String> : String |
18+
subpaths
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
query: Security Features/CWE-079/XSS.ql
2+
postprocess: utils/test/PrettyPrintModels.ql

csharp/ql/integration-tests/all-platforms/blazor_net_8/BlazorTest/Components/Pages/TestPage.razor

+4
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@
8181
<MyOutput Value="@InputValue6" />
8282
</div>
8383

84+
<div>
85+
<MyOutput Value="@QueryParam" />
86+
</div>
87+
8488
@code {
8589

8690
public class Container
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#select
2+
| 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 |
3+
| 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 |
4+
edges
5+
nodes
6+
| BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam | semmle.label | access to property UrlParam |
7+
| BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam | semmle.label | access to property QueryParam |
8+
subpaths
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
query: Security Features/CWE-079/XSS.ql
2+
postprocess: utils/test/PrettyPrintModels.ql
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Modeled parameter passing between Blazor parent and child components.

csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll

+10
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,16 @@ predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
147147
pragma[inline]
148148
predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(e2)) }
149149

150+
/**
151+
* A module importing the modules that provide non local jump node declarations,
152+
* ensuring that they are visible to the taint tracking / data flow library.
153+
*/
154+
private module JumpNodes {
155+
private import semmle.code.csharp.frameworks.microsoft.aspnetcore.Components
156+
private import semmle.code.csharp.frameworks.Razor
157+
private import semmle.code.csharp.frameworks.NHibernate
158+
}
159+
150160
/**
151161
* A data flow node that jumps between callables. This can be extended in
152162
* framework code to add additional data flow steps.

csharp/ql/lib/semmle/code/csharp/frameworks/microsoft/aspnetcore/Components.qll

+51
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,16 @@ class MicrosoftAspNetCoreComponentsComponent extends Class {
112112
}
113113
}
114114

115+
/**
116+
* The `Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder::AddComponentParameter` method.
117+
*/
118+
private class MicrosoftAspNetCoreComponentsAddComponentParameterMethod extends Method {
119+
MicrosoftAspNetCoreComponentsAddComponentParameterMethod() {
120+
this.hasFullyQualifiedName("Microsoft.AspNetCore.Components.Rendering", "RenderTreeBuilder",
121+
"AddComponentParameter")
122+
}
123+
}
124+
115125
private module Sources {
116126
private import semmle.code.csharp.security.dataflow.flowsources.Remote
117127

@@ -133,3 +143,44 @@ private module Sources {
133143
override string getSourceType() { result = "ASP.NET Core component route parameter" }
134144
}
135145
}
146+
147+
private module JumpNodes {
148+
/**
149+
* A call to `Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder::AddComponentParameter` which
150+
* sets the value of a parameter.
151+
*/
152+
private class ParameterPassingCall extends Call {
153+
ParameterPassingCall() {
154+
this.getTarget() instanceof MicrosoftAspNetCoreComponentsAddComponentParameterMethod
155+
}
156+
157+
/**
158+
* Gets the property whose value is being set.
159+
*/
160+
Property getParameterProperty() {
161+
result.getAnAttribute() instanceof MicrosoftAspNetCoreComponentsParameterAttribute and
162+
exists(NameOfExpr ne | ne = this.getArgument(1) | result.getAnAccess() = ne.getAccess())
163+
}
164+
165+
/**
166+
* Gets the value being set.
167+
*/
168+
Expr getParameterValue() { result = this.getArgument(2) }
169+
}
170+
171+
private class ComponentParameterJump extends DataFlow::NonLocalJumpNode {
172+
Property prop;
173+
174+
ComponentParameterJump() {
175+
exists(ParameterPassingCall call |
176+
prop = call.getParameterProperty() and
177+
this.asExpr() = call.getParameterValue()
178+
)
179+
}
180+
181+
override DataFlow::Node getAJumpSuccessor(boolean preservesValue) {
182+
preservesValue = true and
183+
result.asExpr() = prop.getAnAccess()
184+
}
185+
}
186+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
namespace VulnerableBlazorApp.Components
2+
{
3+
using Microsoft.AspNetCore.Components;
4+
5+
public partial class Name : Microsoft.AspNetCore.Components.ComponentBase
6+
{
7+
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder)
8+
{
9+
if (TheName is not null)
10+
{
11+
builder.OpenElement(0, "div");
12+
builder.OpenElement(1, "p");
13+
builder.AddContent(2, (MarkupString)TheName);
14+
builder.CloseElement();
15+
builder.CloseElement();
16+
}
17+
}
18+
19+
[Parameter]
20+
public string TheName { get; set; }
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
namespace VulnerableBlazorApp.Components
2+
{
3+
using System.Collections.Generic;
4+
using Microsoft.AspNetCore.Components;
5+
6+
[RouteAttribute("/names/{name?}")]
7+
public partial class NameList : Microsoft.AspNetCore.Components.ComponentBase
8+
{
9+
protected override void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder)
10+
{
11+
if (Names is not null)
12+
{
13+
builder.OpenElement(0, "div");
14+
builder.OpenElement(1, "ul");
15+
foreach (var name in Names)
16+
{
17+
builder.OpenElement(2, "li");
18+
builder.OpenComponent<VulnerableBlazorApp.Components.Name>(3);
19+
builder.AddComponentParameter(4, nameof(VulnerableBlazorApp.Components.Name.TheName), name);
20+
builder.CloseComponent();
21+
builder.CloseElement();
22+
}
23+
builder.CloseElement();
24+
builder.CloseElement();
25+
}
26+
27+
builder.OpenElement(5, "div");
28+
builder.OpenElement(6, "p");
29+
builder.AddContent(7, "Name: ");
30+
builder.OpenComponent<VulnerableBlazorApp.Components.Name>(8);
31+
builder.AddComponentParameter(9, nameof(VulnerableBlazorApp.Components.Name.TheName), Name);
32+
builder.CloseComponent();
33+
builder.CloseElement();
34+
}
35+
36+
[Parameter]
37+
public string Name { get; set; }
38+
39+
protected override void OnParametersSet()
40+
{
41+
if (Name is not null)
42+
{
43+
Names.Add(Name);
44+
}
45+
}
46+
47+
48+
public List<string> Names { get; set; } = new List<string>();
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
edges
2+
| 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 |
3+
nodes
4+
| Components_Pages_TestPage_razor.g.cs:138:15:138:22 | access to property UrlParam | semmle.label | access to property UrlParam |
5+
| Components_Pages_TestPage_razor.g.cs:188:18:188:27 | access to property QueryParam | semmle.label | access to property QueryParam |
6+
| Name.cs:13:53:13:59 | access to property TheName | semmle.label | access to property TheName |
7+
| NameList.cs:31:99:31:102 | access to property Name : String | semmle.label | access to property Name : String |
8+
subpaths
9+
#select
10+
| 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 |
11+
| 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 |
12+
| 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 |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Security Features/CWE-079/XSS.ql

csharp/ql/test/library-tests/frameworks/microsoft/aspnetcore/blazor/remoteFlowSource.expected

+3
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@
22
| Components_Pages_TestPage_razor.g.cs:138:15:138:22 | access to property UrlParam | ASP.NET Core component route parameter |
33
| Components_Pages_TestPage_razor.g.cs:176:1:176:10 | access to property QueryParam | external |
44
| Components_Pages_TestPage_razor.g.cs:188:18:188:27 | access to property QueryParam | external |
5+
| NameList.cs:31:99:31:102 | access to property Name | ASP.NET Core component route parameter |
6+
| NameList.cs:41:17:41:20 | access to property Name | ASP.NET Core component route parameter |
7+
| NameList.cs:43:27:43:30 | access to property Name | ASP.NET Core component route parameter |

python/ql/src/Resources/FileNotAlwaysClosed.py

-15
This file was deleted.

python/ql/src/Resources/FileNotAlwaysClosed.qhelp

+13-15
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,30 @@
44
<qhelp>
55

66
<overview>
7-
<p> If a file is opened then it should always be closed again, even if an
8-
exception is raised.
9-
Failing to ensure that all files are closed may result in failure due to too
10-
many open files.</p>
11-
7+
<p>When a file is opened, it should always be closed.
8+
</p>
9+
<p>A file opened for writing that is not closed when the application exits may result in data loss, where not all of the data written may be saved to the file.
10+
A file opened for reading or writing that is not closed may also use up file descriptors, which is a resource leak that in long running applications could lead to a failure to open additional files.
11+
</p>
1212
</overview>
1313
<recommendation>
1414

15-
<p>Ensure that if you open a file it is always closed on exiting the method.
16-
Wrap the code between the <code>open()</code> and <code>close()</code>
17-
functions in a <code>with</code> statement or use a <code>try...finally</code>
18-
statement. Using a <code>with</code> statement is preferred as it is shorter
19-
and more readable.</p>
15+
<p>Ensure that opened files are always closed, including when an exception could be raised.
16+
The best practice is often to use a <code>with</code> statement to automatically clean up resources.
17+
Otherwise, ensure that <code>.close()</code> is called in a <code>try...except</code> or <code>try...finally</code>
18+
block to handle any possible exceptions.
19+
</p>
2020

2121
</recommendation>
2222
<example>
23-
<p>The following code shows examples of different ways of closing a file. In the first example, the
24-
file is closed only if the method is exited successfully. In the other examples, the file is always
25-
closed on exiting the method.</p>
23+
<p>In the following examples, in the case marked BAD, the file may not be closed if an exception is raised. In the cases marked GOOD, the file is always closed.</p>
2624

27-
<sample src="FileNotAlwaysClosed.py" />
25+
<sample src="examples/FileNotAlwaysClosed.py" />
2826

2927
</example>
3028
<references>
3129

32-
30+
<li>Python Documentation: <a href="https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files">Reading and writing files</a>.</li>
3331
<li>Python Language Reference: <a href="http://docs.python.org/reference/compound_stmts.html#the-with-statement">The with statement</a>,
3432
<a href="http://docs.python.org/reference/compound_stmts.html#the-try-statement">The try statement</a>.</li>
3533
<li>Python PEP 343: <a href="http://www.python.org/dev/peps/pep-0343">The "with" Statement</a>.</li>

0 commit comments

Comments
 (0)