mirror of
https://github.com/github/codeql.git
synced 2026-04-25 16:55:19 +02:00
Add Tanstack framework support and enhance data flow tracking for fetch responses
This commit is contained in:
@@ -139,6 +139,7 @@ import semmle.javascript.frameworks.Webix
|
||||
import semmle.javascript.frameworks.WebSocket
|
||||
import semmle.javascript.frameworks.XmlParsers
|
||||
import semmle.javascript.frameworks.xUnit
|
||||
import semmle.javascript.frameworks.Tanstack
|
||||
import semmle.javascript.linters.ESLint
|
||||
import semmle.javascript.linters.JSLint
|
||||
import semmle.javascript.linters.Linting
|
||||
|
||||
@@ -861,4 +861,23 @@ module ClientRequest {
|
||||
result = form.getMember("append").getACall().getParameter(1).asSink()
|
||||
}
|
||||
}
|
||||
|
||||
private class ClientRequestThreatModel extends ThreatModelSource::Range {
|
||||
ClientRequestThreatModel() { this = any(ClientRequest r).getAResponseDataNode() }
|
||||
|
||||
override string getThreatModel() { result = "response" }
|
||||
|
||||
override string getSourceType() { result = "HTTP response data" }
|
||||
}
|
||||
|
||||
class FetchResponseStep extends TaintTracking::AdditionalTaintStep {
|
||||
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(DataFlow::MethodCallNode call |
|
||||
call.getMethodName() in ["json", "text", "blob", "arrayBuffer"] and
|
||||
node1 = call.getReceiver() and
|
||||
node2 = call and
|
||||
call.getNumArgument() = 0
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
11
javascript/ql/lib/semmle/javascript/frameworks/Fetch.qll
Normal file
11
javascript/ql/lib/semmle/javascript/frameworks/Fetch.qll
Normal file
@@ -0,0 +1,11 @@
|
||||
private import javascript
|
||||
|
||||
class Fetch extends DataFlow::AdditionalFlowStep {
|
||||
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(DataFlow::MethodCallNode call |
|
||||
call.getMethodName() in ["json", "text", "blob", "arrayBuffer"] and
|
||||
node1 = call.getReceiver() and
|
||||
node2 = call
|
||||
)
|
||||
}
|
||||
}
|
||||
22
javascript/ql/lib/semmle/javascript/frameworks/Tanstack.qll
Normal file
22
javascript/ql/lib/semmle/javascript/frameworks/Tanstack.qll
Normal file
@@ -0,0 +1,22 @@
|
||||
private import javascript
|
||||
|
||||
class TanstackStep extends DataFlow::AdditionalFlowStep {
|
||||
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(DataFlow::CallNode useQuery |
|
||||
useQuery = useQueryCall() and
|
||||
node1 =
|
||||
useQuery
|
||||
.getArgument(0)
|
||||
.getALocalSource()
|
||||
.getAPropertyWrite("queryFn")
|
||||
.getRhs()
|
||||
.getAFunctionValue()
|
||||
.getAReturn() and
|
||||
node2 = useQuery.getAPropertyRead("data")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
DataFlow::CallNode useQueryCall() {
|
||||
result = DataFlow::moduleImport("@tanstack/react-query").getAPropertyRead("useQuery").getACall()
|
||||
}
|
||||
@@ -1,4 +1,24 @@
|
||||
#select
|
||||
| test.jsx:25:29:25:32 | data | test.jsx:5:28:5:63 | fetch(" ... ntent") | test.jsx:25:29:25:32 | data | Cross-site scripting vulnerability due to $@. | test.jsx:5:28:5:63 | fetch(" ... ntent") | user-provided value |
|
||||
edges
|
||||
| test.jsx:5:11:5:63 | response | test.jsx:6:24:6:31 | response | provenance | |
|
||||
| test.jsx:5:22:5:63 | await f ... ntent") | test.jsx:5:11:5:63 | response | provenance | |
|
||||
| test.jsx:5:28:5:63 | fetch(" ... ntent") | test.jsx:5:22:5:63 | await f ... ntent") | provenance | |
|
||||
| test.jsx:6:11:6:38 | data | test.jsx:7:12:7:15 | data | provenance | |
|
||||
| test.jsx:6:18:6:38 | await r ... .json() | test.jsx:6:11:6:38 | data | provenance | |
|
||||
| test.jsx:6:24:6:31 | response | test.jsx:6:24:6:38 | response.json() | provenance | |
|
||||
| test.jsx:6:24:6:38 | response.json() | test.jsx:6:18:6:38 | await r ... .json() | provenance | |
|
||||
| test.jsx:7:12:7:15 | data | test.jsx:11:11:15:5 | data | provenance | |
|
||||
| test.jsx:11:11:15:5 | data | test.jsx:25:29:25:32 | data | provenance | |
|
||||
nodes
|
||||
| test.jsx:5:11:5:63 | response | semmle.label | response |
|
||||
| test.jsx:5:22:5:63 | await f ... ntent") | semmle.label | await f ... ntent") |
|
||||
| test.jsx:5:28:5:63 | fetch(" ... ntent") | semmle.label | fetch(" ... ntent") |
|
||||
| test.jsx:6:11:6:38 | data | semmle.label | data |
|
||||
| test.jsx:6:18:6:38 | await r ... .json() | semmle.label | await r ... .json() |
|
||||
| test.jsx:6:24:6:31 | response | semmle.label | response |
|
||||
| test.jsx:6:24:6:38 | response.json() | semmle.label | response.json() |
|
||||
| test.jsx:7:12:7:15 | data | semmle.label | data |
|
||||
| test.jsx:11:11:15:5 | data | semmle.label | data |
|
||||
| test.jsx:25:29:25:32 | data | semmle.label | data |
|
||||
subpaths
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from "react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
const fetchContent = async () => {
|
||||
const response = await fetch("https://example.com/content"); // $ MISSING: Source[js/xss]
|
||||
const response = await fetch("https://example.com/content"); // $ Source[js/xss]
|
||||
const data = await response.json();
|
||||
return data;
|
||||
};
|
||||
@@ -22,7 +22,7 @@ const ContentWithDangerousHtml = () => {
|
||||
<h1>Content with Dangerous HTML</h1>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: data, // $ MISSING: Alert[js/xss]
|
||||
__html: data, // $ Alert[js/xss]
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user