Skip to content

Conversation

asgerf
Copy link
Contributor

@asgerf asgerf commented May 1, 2025

Makes the JavaScript analysis generate flow summaries from summaryModel rows, and only generate steps if the flow summary library does not support the input/output pair.

@asgerf asgerf added the no-change-note-required This PR does not need a change note label May 2, 2025
@asgerf asgerf marked this pull request as ready for review May 2, 2025 11:57
@Copilot Copilot AI review requested due to automatic review settings May 2, 2025 11:57
@asgerf asgerf requested a review from a team as a code owner May 2, 2025 11:57
Copy link
Contributor

@Copilot 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 enhances JavaScript data-flow analysis by using summaryModel rows for flows and falling back to step generation only when the summary library does not support a given input/output pair.

  • Introduces predicates in FlowSummaryImpl.qll to detect supported input/output stacks and flag unsupported callables.
  • Removes old summary-step logic from ApiGraphModelsSpecific.qll and centralizes fallback logic in ModelsAsData.qll.
  • Updates test expectations to reflect new fallback steps and library-only flows.

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll Added isSupportedInputStack, isSupportedOutputStack, and unsupportedCallable predicates
javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll Removed old summary-step and input/output path predicates; delegating to new fallback mechanism
javascript/ql/lib/semmle/javascript/frameworks/data/ModelsAsData.qll Imported FlowSummaryPrivate, defined SummarizedCallableFromModel, and integrated fallback step logic
javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll Exposed unsupportedCallable predicates for use in dataflow
javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected Updated expected edges/nodes to include fallback-generated steps
javascript/ql/test/library-tests/frameworks/data/test.expected Updated expected flows to reflect library-only and fallback behavior
javascript/ql/test/library-tests/TripleDot/underscore.string.js Adjusted expected taint-flow annotation to match new test behavior
Comments suppressed due to low confidence (2)

javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll:268

  • [nitpick] The predicate 'unsupportedCallable' is overloaded with arity 1 and 4, which may be confusing. Consider renaming one overload or adding documentation to clarify their distinct purposes.
predicate unsupportedCallable = Private::unsupportedCallable/1;

shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll:564

  • The recursive case in isSupportedInputStack handles stacks beyond length 3; consider adding unit tests for deeper input stacks to ensure correct behavior.
isSupportedInputStack(s.tail()) and

s.head() instanceof TReturnSummaryComponent and
s.tail().head() instanceof TArgumentSummaryComponent
or
// Argument[n].Parameter[n].Content.*
Copy link
Contributor

Choose a reason for hiding this comment

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

I hadn't considered the fact that we also support this case, a lambda passed in which has a side-effect on one of it's arguments.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a good thing we do. We rely on this to model the Promise constructor in JavaScript.

}

/**
* Holds if `s` is a valid input stack, in the sense that we generate data flow graph
Copy link
Contributor

Choose a reason for hiding this comment

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

generate a

Comment on lines +574 to +577
// Argument[n].Content.*
s.length() = 2 and
s.head() instanceof TContentSummaryComponent and
s.tail().head() instanceof TArgumentSummaryComponent
Copy link
Contributor

Choose a reason for hiding this comment

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

We actually support just Argument[n] as well, for example one might model a string builder append method as input = Argument[0] and output = Argument[self] and preservesValue = false`.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call. I pushed a commit that recognises this, please take a look.

@asgerf asgerf merged commit aea676d into github:main May 13, 2025
37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DataFlow Library 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.

2 participants