Skip to content

Conversation

@Vasco-jofra
Copy link
Contributor

Adds _.groupBy as a taint step.

This is analogous to the GroupByTaintStep class, which does the same for Object and Map.

https://github.com/github/codeql/blob/d83cbde1cb1263fb476a55ea5fd7972307138905/javascript/ql/lib/semmle/javascript/Collections.qll#L158C1-L166C4

@Vasco-jofra Vasco-jofra requested a review from a team as a code owner June 13, 2025 22:18
@github-actions github-actions bot added the JS label Jun 13, 2025
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
input = "Argument[0]" and
output = ["Argument[1].Parameter[0]", "ReturnValue"] and
preservesValue = false
Copy link
Contributor

Choose a reason for hiding this comment

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

The relevant implementation for Map.groupBy is here:

override predicate propagatesFlow(string input, string output, boolean preservesValue) {
preservesValue = true and
(
input = "Argument[0].ArrayElement" and
output = ["Argument[1].Parameter[0]", "ReturnValue.MapValue.ArrayElement"]
or
input = "Argument[1].ReturnValue" and
output = "ReturnValue.MapKey"
)
}

This would be the closest matching implementation for _.groupBy I think:

   preservesValue = true and
   input = "Argument[0].ArrayElement" and 
   output = ["Argument[1].Parameter[0]", "ReturnValue.AnyMember.ArrayElement"] 

Note that there is currently no content corresponding to MapKey for the keys of a plain object.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I based it on:

private class GroupByTaintStep extends TaintTracking::SharedTaintStep {
override predicate heapStep(DataFlow::Node pred, DataFlow::Node succ) {
exists(DataFlow::MethodCallNode call |
call = DataFlow::globalVarRef(["Map", "Object"]).getAMemberCall("groupBy") and
pred = call.getArgument(0) and
(succ = call.getCallback(1).getParameter(0) or succ = call)
)
}
}

Is there a reason for having these two implementations for Map.groupBy?

Happy to update to your suggestion if you feel that's the best solution. We should add tests for the lodash library, though; they are currently very minimal.

@asgerf asgerf added the no-change-note-required This PR does not need a change note label Jun 25, 2025
@nicolaswill
Copy link
Contributor

@asgerf Are there changes needed here? Merging this PR as well as #19770 is important for a customer.

@asgerf asgerf merged commit f587273 into github:main Sep 16, 2025
13 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

JS no-change-note-required This PR does not need a change note

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants