Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C#: Blazor: Add non-local jump node for parameter passing #19122

Merged

Conversation

tamasvajk
Copy link
Contributor

@tamasvajk tamasvajk commented Mar 26, 2025

Continuation of #18930.

Establishes the pattern that when a variable is passed to a subcomponent, the reads of the set property are considered tainted.

For example, if in the following example Names was tainted,

@foreach (string name in Names)
{
    <DisplayName Name="name"/>
}

Then a read in the DisplayName component would be considered tainted

@* Bad: rendering unsanitized strings *@
<p>@((MarkupString)Name)</p>

@code {
   [Parameter]
   string Name { get; set; }
}

@@ -0,0 +1 @@
Security Features/CWE-079/XSS.ql

Check warning

Code scanning / CodeQL

Query test without inline test expectations Warning test

Query test does not use inline test expectations.
@tamasvajk tamasvajk marked this pull request as ready for review March 26, 2025 11:50
@tamasvajk tamasvajk requested a review from a team as a code owner March 26, 2025 11:50
Copy link
Contributor

@michaelnebel michaelnebel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for following up on this @tamasvajk !
Would it be possible to add a brief explanation in the PR description on, which jump step we are modelling?

Comment on lines +1 to +2
query: Security Features/CWE-079/XSS.ql
postprocess: utils/test/PrettyPrintModels.ql

Check warning

Code scanning / CodeQL

Query test without inline test expectations Warning

Query test does not use inline test expectations.
Comment on lines +1 to +2
query: Security Features/CWE-079/XSS.ql
postprocess: utils/test/PrettyPrintModels.ql

Check warning

Code scanning / CodeQL

Query test without inline test expectations Warning

Query test does not use inline test expectations.
Comment on lines +1 to +2
query: Security Features/CWE-079/XSS.ql
postprocess: utils/test/PrettyPrintModels.ql

Check warning

Code scanning / CodeQL

Query test without inline test expectations Warning

Query test does not use inline test expectations.
Copy link
Contributor

@michaelnebel michaelnebel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for looking into it; One clarifying follow-up question and one comment.

{
builder.OpenElement(2, "li");
builder.OpenComponent<VulnerableBlazorApp.Components.Name>(3);
builder.AddComponentParameter(4, nameof(VulnerableBlazorApp.Components.Name.TheName), name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, the jump step ensures that we have data flow from name into the property VulnerableBlazorApp.Components.Name.TheName?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, there's flow from name to the property reads of VulnerableBlazorApp.Components.Name.TheName.

Expr getParameterValue() { result = this.getArgument(2) }
}

private class ComponentParameterJump extends DataFlow::NonLocalJumpNode {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The NonLocalJumpNode is a bi-directional imported abstract class, but this is not that evident. I think it makes sense to explicitly make a private import module above the NonLocalJumpNode declaration that imports all file modules that extends the class.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean the below?

--- 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,10 @@ predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
 pragma[inline]
 predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(e2)) }
 
+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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and just in a private module.

/**
 * 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
}

Copy link
Contributor

@michaelnebel michaelnebel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent!

@hvitved
Copy link
Contributor

hvitved commented Mar 28, 2025

I have started a DCA run. Also, it would be nicer to use inline test expectations, as suggested by QL4QL.

@tamasvajk
Copy link
Contributor Author

tamasvajk commented Mar 28, 2025

it would be nicer to use inline test expectations, as suggested by QL4QL.

Should inline test expectations work when the source and sink locations are mapped to .razor files?

@hvitved
Copy link
Contributor

hvitved commented Mar 28, 2025

Should inline test expectations work when the source and sink locations are mapped to .razor files?

Sorry, you are right, it doesn't work for .razor pages.

@tamasvajk tamasvajk merged commit 342d4a6 into github:main Mar 28, 2025
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants