Skip to content

C#: Add default taint step from an implicit operator call to its argument.#21400

Open
michaelnebel wants to merge 6 commits intogithub:mainfrom
michaelnebel:csharp/implicitconversionreverseflowtaint
Open

C#: Add default taint step from an implicit operator call to its argument.#21400
michaelnebel wants to merge 6 commits intogithub:mainfrom
michaelnebel:csharp/implicitconversionreverseflowtaint

Conversation

@michaelnebel
Copy link
Contributor

@michaelnebel michaelnebel commented Mar 2, 2026

Consider this flow source row:

extensions:
  - addsTo:
      pack: codeql/csharp-all
      extensible: sourceModel
    data:
      - ["System.Net.WebSockets", "WebSocket", True, "ReceiveAsync", "", "", "Argument[0]", "remote", "manual"]

and this snippet:

var buffer = new byte[1024];
var result = await webSocket.ReceiveAsync(buffer, System.Threading.CancellationToken.None);

On the second line there's a call to operator an implicit conversion which means that buffer is not an argument to webSocket.ReceiveAsync, but rather an argument to the call to an implicit conversion (which is then an argument to ReceiveAsync). However, we would like buffer to be tainted after the call to ReceiveAsync.

This is solved by adding a reverse update default taint step for post-update nodes for implicit conversion calls.
That is, for f(implicit_conv(x)) we add a step from the post-update of implicit_conv(x) to x.

DCA looks good.

@github-actions github-actions bot added the C# label Mar 2, 2026
@michaelnebel michaelnebel force-pushed the csharp/implicitconversionreverseflowtaint branch from 77dbe2c to c3f0d4a Compare March 3, 2026 11:41
@michaelnebel michaelnebel force-pushed the csharp/implicitconversionreverseflowtaint branch from c3f0d4a to cfd4be6 Compare March 3, 2026 13:41
@michaelnebel michaelnebel requested a review from hvitved March 3, 2026 14:39
@michaelnebel
Copy link
Contributor Author

@hvitved : Is this an acceptable approach for solving the problem?

Copy link
Contributor

@hvitved hvitved left a comment

Choose a reason for hiding this comment

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

LGTM, just one minor suggestion.

…ngPrivate.qll

Co-authored-by: Tom Hvitved <hvitved@github.com>
@michaelnebel michaelnebel requested a review from hvitved March 4, 2026 11:28
@michaelnebel michaelnebel marked this pull request as ready for review March 4, 2026 11:28
@michaelnebel michaelnebel requested a review from a team as a code owner March 4, 2026 11:28
Copilot AI review requested due to automatic review settings March 4, 2026 11:28
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates C# taint tracking to handle implicit conversion operator calls in method arguments by adding a default reverse taint step from the post-update node of an implicit conversion to its argument, and adds a regression test plus changelog entry.

Changes:

  • Add a default reverse taint step for post-update nodes of implicit conversion operator calls.
  • Add a new library-test (QL + C# source) and corresponding .expected output to cover the new flow behavior.
  • Add a changelog entry documenting the analysis improvement.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll Adds the new default reverse taint step logic for implicit conversion operator post-update nodes.
csharp/ql/test/library-tests/dataflow/operators/implicitConversionOperatorFlow.ql New taint path-problem test that treats the post-update node as a source and checks flow to the original argument.
csharp/ql/test/library-tests/dataflow/operators/implicitConversionOperatorFlow.expected Expected path output for the new test.
csharp/ql/test/library-tests/dataflow/operators/ImplicitConversionOperator.cs C# fixture exercising implicit conversion from byte[] to ArraySegment<byte>.
csharp/ql/lib/change-notes/2026-03-03-implicit-conversion-reverse-flow.md Change note for the new reverse taint flow behavior.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +191 to +193
// Allow reverse update flow for implicit conversion operator calls.
// This is needed to support flow out of method call arguments, where an implicit conversion is applied
// to a call argument.
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

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

The new comment says "reverse update flow" but this predicate is adding a default taint step. Consider rewording to "reverse taint flow" (and/or explicitly mentioning post-update nodes) to avoid confusion with the data-flow reverse-step logic in DataFlowPrivate.

Suggested change
// Allow reverse update flow for implicit conversion operator calls.
// This is needed to support flow out of method call arguments, where an implicit conversion is applied
// to a call argument.
// Allow reverse taint flow between post-update and pre-update nodes for implicit conversion operator calls.
// This is needed to support taint flow out of method call arguments where an implicit conversion is applied
// to the argument expression.

Copilot uses AI. Check for mistakes.
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.

3 participants