mirror of
https://github.com/github/codeql.git
synced 2026-02-11 20:51:06 +01:00
Merge remote-tracking branch 'upstream/main' into igfoo/mb
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added `PreCallGraphStep` flow model for React's `useRef` hook.
|
||||
* Added a `DomValueSource` that uses the `current` property off the object returned by React's `useRef` hook.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
|
||||
- Support `use cache` directives for Next.js 16.
|
||||
@@ -434,6 +434,21 @@ module Directive {
|
||||
class UseClientDirective extends KnownDirective {
|
||||
UseClientDirective() { this.getDirectiveText() = "use client" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `use cache` directive.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```
|
||||
* "use cache";
|
||||
* "use cache: remote";
|
||||
* "use cache: private";
|
||||
* ```
|
||||
*/
|
||||
class UseCacheDirective extends KnownDirective {
|
||||
UseCacheDirective() { this.getDirectiveText().regexpMatch("use cache(:.*)?") }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -612,6 +612,25 @@ private class UseStateStep extends PreCallGraphStep {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Step through a `useRef` call.
|
||||
*
|
||||
* It returns an object with a single property (`current`) initialized to the initial value.
|
||||
*
|
||||
* For example:
|
||||
* ```js
|
||||
* const inputRef1 = useRef(initialValue);
|
||||
* ```
|
||||
*/
|
||||
private class UseRefStep extends PreCallGraphStep {
|
||||
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(DataFlow::CallNode call | call = react().getAMemberCall("useRef") |
|
||||
pred = call.getArgument(0) and // initial state
|
||||
succ = call.getAPropertyRead("current")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A step through a React context object.
|
||||
*
|
||||
@@ -785,6 +804,17 @@ private class ReactRouterLocationSource extends DOM::LocationSource::Range {
|
||||
}
|
||||
}
|
||||
|
||||
private class UseRefDomValueSource extends DOM::DomValueSource::Range {
|
||||
UseRefDomValueSource() {
|
||||
this =
|
||||
any(JsxAttribute attrib | attrib.getName() = "ref")
|
||||
.getValue()
|
||||
.flow()
|
||||
.getALocalSource()
|
||||
.getAPropertyRead("current")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reference to a function which, if called with a React component, returns wrapped
|
||||
* version of that component, which we model as a direct reference to the underlying component.
|
||||
|
||||
@@ -97,7 +97,7 @@ class ExternalApiDataNode extends DataFlow::Node instanceof Sink { }
|
||||
|
||||
/** A node representing untrusted data being passed to an external API. */
|
||||
class UntrustedExternalApiDataNode extends ExternalApiDataNode {
|
||||
UntrustedExternalApiDataNode() { ExternalAPIUsedWithUntrustedDataFlow::flow(_, this) }
|
||||
UntrustedExternalApiDataNode() { ExternalAPIUsedWithUntrustedDataFlow::flowTo(this) }
|
||||
|
||||
/** Gets a source of untrusted data which is passed to this external API data node. */
|
||||
DataFlow::Node getAnUntrustedSource() { ExternalAPIUsedWithUntrustedDataFlow::flow(result, this) }
|
||||
@@ -110,7 +110,7 @@ private newtype TExternalApi =
|
||||
/** An external API sink with `name`. */
|
||||
MkExternalApiNode(string name) {
|
||||
exists(Sink sink |
|
||||
ExternalAPIUsedWithUntrustedDataFlow::flow(_, sink) and
|
||||
ExternalAPIUsedWithUntrustedDataFlow::flowTo(sink) and
|
||||
name = sink.getApiName()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -36,6 +36,6 @@ import UnverifiedDecodeFlow::PathGraph
|
||||
from UnverifiedDecodeFlow::PathNode source, UnverifiedDecodeFlow::PathNode sink
|
||||
where
|
||||
UnverifiedDecodeFlow::flowPath(source, sink) and
|
||||
not VerifiedDecodeFlow::flow(source.getNode(), _)
|
||||
not VerifiedDecodeFlow::flowFrom(source.getNode())
|
||||
select source.getNode(), source, sink, "Decoding JWT $@.", sink.getNode(),
|
||||
"without signature verification"
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
| tst.js:1:1:1:13 | 'use strict'; | use strict |
|
||||
| tst.js:2:1:2:10 | 'use asm'; | use asm |
|
||||
| tst.js:3:1:3:9 | 'bundle'; | bundle |
|
||||
| tst.js:12:3:12:12 | 'use asm'; | use asm |
|
||||
| tst.js:19:5:19:17 | 'use strict'; | use strict |
|
||||
| tst.js:4:1:4:13 | 'use server'; | use server |
|
||||
| tst.js:5:1:5:13 | 'use client'; | use client |
|
||||
| tst.js:6:1:6:12 | 'use cache'; | use cache |
|
||||
| tst.js:7:1:7:20 | 'use cache: remote'; | use cache: remote |
|
||||
| tst.js:8:1:8:21 | 'use ca ... ivate'; | use cache: private |
|
||||
| tst.js:17:3:17:12 | 'use asm'; | use asm |
|
||||
| tst.js:18:3:18:11 | 'bundle'; | bundle |
|
||||
| tst.js:19:3:19:15 | 'use server'; | use server |
|
||||
| tst.js:20:3:20:15 | 'use client'; | use client |
|
||||
| tst.js:21:3:21:14 | 'use cache'; | use cache |
|
||||
| tst.js:22:3:22:22 | 'use cache: remote'; | use cache: remote |
|
||||
| tst.js:23:3:23:23 | 'use ca ... ivate'; | use cache: private |
|
||||
| tst.js:30:5:30:17 | 'use strict'; | use strict |
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
'use strict'; // this is a directive
|
||||
'use asm'; // and so is this
|
||||
'bundle';// and this
|
||||
'use server';
|
||||
'use client';
|
||||
'use cache';
|
||||
'use cache: remote';
|
||||
'use cache: private';
|
||||
{
|
||||
'use strict'; // but this isn't a directive
|
||||
}
|
||||
@@ -10,6 +15,12 @@
|
||||
function f() {
|
||||
'use\x20strict'; // this is a directive, though not a strict mode directive
|
||||
'use asm'; // and so is this
|
||||
'bundle';
|
||||
'use server';
|
||||
'use client';
|
||||
'use cache';
|
||||
'use cache: remote';
|
||||
'use cache: private';
|
||||
;
|
||||
'use strict'; // but this isn't a directive
|
||||
}
|
||||
|
||||
@@ -32,5 +32,5 @@ class BasicBarrierGuard extends DataFlow::CallNode {
|
||||
deprecated class ConsistencyConfig extends ConsistencyConfiguration {
|
||||
ConsistencyConfig() { this = "ConsistencyConfig" }
|
||||
|
||||
override DataFlow::Node getAnAlert() { Flow::flow(_, result) }
|
||||
override DataFlow::Node getAnAlert() { Flow::flowTo(result) }
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
| UnknownDirective.js:12:5:12:17 | "use struct;" | Unknown directive: 'use struct;'. |
|
||||
| UnknownDirective.js:13:5:13:17 | "Use Strict"; | Unknown directive: 'Use Strict'. |
|
||||
| UnknownDirective.js:14:5:14:14 | "use bar"; | Unknown directive: 'use bar'. |
|
||||
| UnknownDirective.js:40:5:40:17 | "[0, 0, 0];"; | Unknown directive: '[0, 0, 0];'. |
|
||||
| UnknownDirective.js:41:5:41:65 | "[0, 0, ... , 0];"; | Unknown directive: '[0, 0, 0, 0, 0, 0, 0 ... (truncated)'. |
|
||||
| UnknownDirective.js:47:5:47:15 | ":nomunge"; | Unknown directive: ':nomunge'. |
|
||||
| UnknownDirective.js:48:5:48:30 | "foo(), ... munge"; | Unknown directive: 'foo(), bar, baz:nomu ... (truncated)'. |
|
||||
| UnknownDirective.js:43:5:43:17 | "[0, 0, 0];"; | Unknown directive: '[0, 0, 0];'. |
|
||||
| UnknownDirective.js:44:5:44:65 | "[0, 0, ... , 0];"; | Unknown directive: '[0, 0, 0, 0, 0, 0, 0 ... (truncated)'. |
|
||||
| UnknownDirective.js:50:5:50:15 | ":nomunge"; | Unknown directive: ':nomunge'. |
|
||||
| UnknownDirective.js:51:5:51:30 | "foo(), ... munge"; | Unknown directive: 'foo(), bar, baz:nomu ... (truncated)'. |
|
||||
|
||||
@@ -34,6 +34,9 @@ function good() {
|
||||
"deps bar";
|
||||
"use server";
|
||||
"use client";
|
||||
"use cache";
|
||||
"use cache: remote";
|
||||
"use cache: private";
|
||||
}
|
||||
|
||||
function data() {
|
||||
|
||||
@@ -14,7 +14,7 @@ predicate passwordVarAssign(Variable v, DataFlow::Node nd) {
|
||||
module PasswordFlow = DataFlow::Global<PasswordConfig>;
|
||||
|
||||
query predicate test_query17(DataFlow::Node sink, string res) {
|
||||
exists(Variable v | PasswordFlow::flow(_, sink) and passwordVarAssign(v, sink) |
|
||||
exists(Variable v | PasswordFlow::flowTo(sink) and passwordVarAssign(v, sink) |
|
||||
res = "Password variable " + v.toString() + " is assigned a constant string."
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user