Skip to content

Commit 853fc1a

Browse files
authored
Merge pull request #19852 from asgerf/js/react-use-server
JS: Model React 'use' and 'use server'
2 parents ddae471 + 4fc5738 commit 853fc1a

39 files changed

+363
-317
lines changed

javascript/ql/lib/ext/react.model.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/javascript-all
4+
extensible: summaryModel
5+
data:
6+
- ["react", "Member[use]", "Argument[0].Awaited", "ReturnValue", "value"]

javascript/ql/lib/semmle/javascript/frameworks/React.qll

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,3 +875,22 @@ private class ReactPropAsViewComponentInput extends ViewComponentInput {
875875

876876
override string getSourceType() { result = "React props" }
877877
}
878+
879+
private predicate isServerFunction(DataFlow::FunctionNode func) {
880+
exists(Directive::UseServerDirective useServer |
881+
useServer.getContainer() = func.getFunction()
882+
or
883+
useServer.getContainer().(Module).getAnExportedValue(_).getAFunctionValue() = func
884+
)
885+
}
886+
887+
private class ServerFunctionRemoteFlowSource extends RemoteFlowSource {
888+
ServerFunctionRemoteFlowSource() {
889+
exists(DataFlow::FunctionNode func |
890+
isServerFunction(func) and
891+
this = func.getAParameter()
892+
)
893+
}
894+
895+
override string getSourceType() { result = "React server function parameter" }
896+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
category: majorAnalysis
3+
---
4+
* Taint is now tracked through the React `use` function.
5+
* Parameters of React server functions, marked with the `"use server"` directive, are now seen as taint sources.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { use } from "react";
2+
3+
async function fetchData() {
4+
return new Promise((resolve) => {
5+
resolve(source("fetchedData"));
6+
});
7+
}
8+
9+
function Component() {
10+
const data = use(fetchData());
11+
sink(data); // $ hasValueFlow=fetchedData
12+
}

javascript/ql/test/library-tests/frameworks/ReactJS/ReactComponent.qll

Lines changed: 0 additions & 3 deletions
This file was deleted.

javascript/ql/test/library-tests/frameworks/ReactJS/ReactComponent_getACandidatePropsValue.qll

Lines changed: 0 additions & 5 deletions
This file was deleted.

javascript/ql/test/library-tests/frameworks/ReactJS/ReactComponent_getACandidateStateSource.qll

Lines changed: 0 additions & 7 deletions
This file was deleted.

javascript/ql/test/library-tests/frameworks/ReactJS/ReactComponent_getADirectPropsSource.qll

Lines changed: 0 additions & 5 deletions
This file was deleted.

javascript/ql/test/library-tests/frameworks/ReactJS/ReactComponent_getAPreviousStateSource.qll

Lines changed: 0 additions & 7 deletions
This file was deleted.

javascript/ql/test/library-tests/frameworks/ReactJS/ReactComponent_getAPropRead.qll

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)