codeql-development-mcp-server 2.24.3 → 2.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/codeql-development-mcp-server.js +48111 -49526
- package/dist/codeql-development-mcp-server.js.map +4 -4
- package/package.json +9 -9
- package/ql/actions/tools/src/PrintCFG/PrintCFG.ql +1 -3
- package/ql/actions/tools/src/codeql-pack.lock.yml +14 -14
- package/ql/actions/tools/src/codeql-pack.yml +2 -2
- package/ql/cpp/tools/src/CallGraphFrom/CallGraphFrom.ql +6 -20
- package/ql/cpp/tools/src/CallGraphFromTo/CallGraphFromTo.md +47 -0
- package/ql/cpp/tools/src/CallGraphFromTo/CallGraphFromTo.ql +77 -0
- package/ql/cpp/tools/src/CallGraphTo/CallGraphTo.ql +6 -20
- package/ql/cpp/tools/src/ExternalPredicates.qll +14 -0
- package/ql/cpp/tools/src/PrintAST/PrintAST.ql +9 -20
- package/ql/cpp/tools/src/PrintCFG/PrintCFG.ql +1 -3
- package/ql/cpp/tools/src/codeql-pack.lock.yml +12 -12
- package/ql/cpp/tools/src/codeql-pack.yml +2 -2
- package/ql/csharp/tools/src/CallGraphFrom/CallGraphFrom.ql +4 -19
- package/ql/csharp/tools/src/CallGraphFromTo/CallGraphFromTo.md +49 -0
- package/ql/csharp/tools/src/CallGraphFromTo/CallGraphFromTo.ql +64 -0
- package/ql/csharp/tools/src/CallGraphTo/CallGraphTo.ql +4 -19
- package/ql/csharp/tools/src/ExternalPredicates.qll +14 -0
- package/ql/csharp/tools/src/PrintAST/PrintAST.ql +9 -17
- package/ql/csharp/tools/src/codeql-pack.lock.yml +10 -10
- package/ql/csharp/tools/src/codeql-pack.yml +2 -2
- package/ql/go/tools/src/CallGraphFrom/CallGraphFrom.ql +4 -19
- package/ql/go/tools/src/CallGraphFromTo/CallGraphFromTo.md +47 -0
- package/ql/go/tools/src/CallGraphFromTo/CallGraphFromTo.ql +53 -0
- package/ql/go/tools/src/CallGraphTo/CallGraphTo.ql +4 -20
- package/ql/go/tools/src/ExternalPredicates.qll +14 -0
- package/ql/go/tools/src/PrintAST/PrintAST.ql +132 -22
- package/ql/go/tools/src/codeql-pack.lock.yml +10 -10
- package/ql/go/tools/src/codeql-pack.yml +2 -2
- package/ql/java/tools/src/CallGraphFrom/CallGraphFrom.ql +4 -19
- package/ql/java/tools/src/CallGraphFromTo/CallGraphFromTo.md +49 -0
- package/ql/java/tools/src/CallGraphFromTo/CallGraphFromTo.ql +64 -0
- package/ql/java/tools/src/CallGraphTo/CallGraphTo.ql +4 -19
- package/ql/java/tools/src/ExternalPredicates.qll +14 -0
- package/ql/java/tools/src/PrintAST/PrintAST.ql +9 -17
- package/ql/java/tools/src/PrintCFG/PrintCFG.ql +11 -10
- package/ql/java/tools/src/codeql-pack.lock.yml +14 -14
- package/ql/java/tools/src/codeql-pack.yml +2 -2
- package/ql/javascript/tools/src/CallGraphFrom/CallGraphFrom.ql +4 -19
- package/ql/javascript/tools/src/CallGraphFromTo/CallGraphFromTo.md +47 -0
- package/ql/javascript/tools/src/CallGraphFromTo/CallGraphFromTo.ql +69 -0
- package/ql/javascript/tools/src/CallGraphTo/CallGraphTo.ql +4 -20
- package/ql/javascript/tools/src/ExternalPredicates.qll +14 -0
- package/ql/javascript/tools/src/PrintAST/PrintAST.ql +9 -20
- package/ql/javascript/tools/src/PrintCFG/PrintCFG.ql +1 -3
- package/ql/javascript/tools/src/codeql-pack.lock.yml +13 -13
- package/ql/javascript/tools/src/codeql-pack.yml +2 -2
- package/ql/python/tools/src/CallGraphFrom/CallGraphFrom.ql +3 -17
- package/ql/python/tools/src/CallGraphFromTo/CallGraphFromTo.md +46 -0
- package/ql/python/tools/src/CallGraphFromTo/CallGraphFromTo.ql +71 -0
- package/ql/python/tools/src/CallGraphTo/CallGraphTo.ql +6 -22
- package/ql/python/tools/src/ExternalPredicates.qll +14 -0
- package/ql/python/tools/src/PrintAST/PrintAST.ql +9 -20
- package/ql/python/tools/src/PrintCFG/PrintCFG.ql +1 -3
- package/ql/python/tools/src/codeql-pack.lock.yml +13 -13
- package/ql/python/tools/src/codeql-pack.yml +2 -2
- package/ql/ruby/tools/src/CallGraphFrom/CallGraphFrom.ql +4 -19
- package/ql/ruby/tools/src/CallGraphFromTo/CallGraphFromTo.md +48 -0
- package/ql/ruby/tools/src/CallGraphFromTo/CallGraphFromTo.ql +50 -0
- package/ql/ruby/tools/src/CallGraphTo/CallGraphTo.ql +4 -20
- package/ql/ruby/tools/src/ExternalPredicates.qll +14 -0
- package/ql/ruby/tools/src/PrintAST/PrintAST.ql +9 -17
- package/ql/ruby/tools/src/PrintCFG/PrintCFG.ql +1 -3
- package/ql/ruby/tools/src/codeql-pack.lock.yml +10 -10
- package/ql/ruby/tools/src/codeql-pack.yml +2 -2
- package/ql/swift/tools/src/CallGraphFrom/CallGraphFrom.ql +7 -16
- package/ql/swift/tools/src/CallGraphFromTo/CallGraphFromTo.md +47 -0
- package/ql/swift/tools/src/CallGraphFromTo/CallGraphFromTo.ql +80 -0
- package/ql/swift/tools/src/CallGraphTo/CallGraphTo.ql +8 -14
- package/ql/swift/tools/src/ExternalPredicates.qll +14 -0
- package/ql/swift/tools/src/PrintAST/PrintAST.ql +5 -15
- package/ql/swift/tools/src/PrintCFG/PrintCFG.ql +5 -15
- package/ql/swift/tools/src/codeql-pack.lock.yml +10 -10
- package/ql/swift/tools/src/codeql-pack.yml +2 -2
|
@@ -8,18 +8,13 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import java
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Gets the target method name for which to generate the call graph.
|
|
14
|
-
* Can be a single method name or comma-separated list of method names.
|
|
15
|
-
*/
|
|
16
|
-
external string targetFunction();
|
|
11
|
+
import ExternalPredicates
|
|
17
12
|
|
|
18
13
|
/**
|
|
19
14
|
* Gets a single target method name from the comma-separated list.
|
|
20
15
|
*/
|
|
21
16
|
string getTargetFunctionName() {
|
|
22
|
-
|
|
17
|
+
exists(string s | targetFunction(s) | result = s.splitAt(",").trim())
|
|
23
18
|
}
|
|
24
19
|
|
|
25
20
|
/**
|
|
@@ -36,15 +31,5 @@ from Call call, Callable target, Callable caller
|
|
|
36
31
|
where
|
|
37
32
|
call.getCallee() = target and
|
|
38
33
|
call.getCaller() = caller and
|
|
39
|
-
(
|
|
40
|
-
|
|
41
|
-
target = getTargetFunction()
|
|
42
|
-
or
|
|
43
|
-
// Fallback for unit tests: include test files
|
|
44
|
-
(
|
|
45
|
-
not exists(getTargetFunction()) and
|
|
46
|
-
target.getFile().getParentContainer().getParentContainer().getBaseName() = "test"
|
|
47
|
-
)
|
|
48
|
-
)
|
|
49
|
-
select call,
|
|
50
|
-
"Call to `" + target.getName() + "` from `" + caller.getName() + "`"
|
|
34
|
+
target = getTargetFunction()
|
|
35
|
+
select call, "Call to `" + target.getName() + "` from `" + caller.getName() + "`"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared extensible predicate declarations for MCP server tools queries.
|
|
3
|
+
* Values are provided via dataExtensions YAML files during testing,
|
|
4
|
+
* or via a temporary data extension pack at runtime from the MCP server.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** Holds for each source function name for call graph analysis. */
|
|
8
|
+
extensible predicate sourceFunction(string name);
|
|
9
|
+
|
|
10
|
+
/** Holds for each target function name for call graph analysis. */
|
|
11
|
+
extensible predicate targetFunction(string name);
|
|
12
|
+
|
|
13
|
+
/** Holds for each selected source file path for AST/CFG printing. */
|
|
14
|
+
extensible predicate selectedSourceFiles(string path);
|
|
@@ -8,18 +8,13 @@
|
|
|
8
8
|
|
|
9
9
|
import java
|
|
10
10
|
import semmle.code.java.PrintAst
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Gets the source files to generate AST from.
|
|
14
|
-
* Can be a single file path or comma-separated list of file paths.
|
|
15
|
-
*/
|
|
16
|
-
external string selectedSourceFiles();
|
|
11
|
+
import ExternalPredicates
|
|
17
12
|
|
|
18
13
|
/**
|
|
19
14
|
* Gets a single source file from the comma-separated list.
|
|
20
15
|
*/
|
|
21
16
|
string getSelectedSourceFile() {
|
|
22
|
-
|
|
17
|
+
exists(string s | selectedSourceFiles(s) | result = s.splitAt(",").trim())
|
|
23
18
|
}
|
|
24
19
|
|
|
25
20
|
/**
|
|
@@ -30,11 +25,14 @@ File getSelectedFile() {
|
|
|
30
25
|
selectedFile = getSelectedSourceFile() and
|
|
31
26
|
(
|
|
32
27
|
// Match by exact relative path from source root
|
|
33
|
-
result.getRelativePath() = selectedFile
|
|
28
|
+
result.getRelativePath() = selectedFile
|
|
29
|
+
or
|
|
34
30
|
// Match by file name if no path separators
|
|
35
|
-
|
|
31
|
+
not selectedFile.matches("%/%") and result.getBaseName() = selectedFile
|
|
32
|
+
or
|
|
36
33
|
// Match by ending path component
|
|
37
|
-
result.getAbsolutePath().suffix(result.getAbsolutePath().length() - selectedFile.length()) =
|
|
34
|
+
result.getAbsolutePath().suffix(result.getAbsolutePath().length() - selectedFile.length()) =
|
|
35
|
+
selectedFile
|
|
38
36
|
)
|
|
39
37
|
)
|
|
40
38
|
}
|
|
@@ -46,12 +44,6 @@ File getSelectedFile() {
|
|
|
46
44
|
class Cfg extends PrintAstConfiguration {
|
|
47
45
|
override predicate shouldPrint(Element e, Location l) {
|
|
48
46
|
super.shouldPrint(e, l) and
|
|
49
|
-
(
|
|
50
|
-
// Use external predicate if available
|
|
51
|
-
l.getFile() = getSelectedFile()
|
|
52
|
-
or
|
|
53
|
-
// Fallback for unit tests: include specific test files
|
|
54
|
-
(not exists(getSelectedFile()) and l.getFile().getBaseName() = "Example1.java")
|
|
55
|
-
)
|
|
47
|
+
l.getFile() = getSelectedFile()
|
|
56
48
|
}
|
|
57
49
|
}
|
|
@@ -10,26 +10,27 @@ import java
|
|
|
10
10
|
import semmle.code.java.ControlFlowGraph
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
* Holds if the node is an exit-related CFG node.
|
|
13
|
+
* Holds if the node is an entry- or exit-related CFG node.
|
|
14
14
|
* These nodes are excluded from the output because their ordering
|
|
15
|
-
* is non-deterministic across CodeQL CLI versions.
|
|
15
|
+
* is non-deterministic across CodeQL CLI versions and environments.
|
|
16
16
|
*/
|
|
17
|
-
private predicate
|
|
18
|
-
node.toString().matches("%Exit")
|
|
17
|
+
private predicate isEntryOrExitNode(ControlFlowNode node) {
|
|
18
|
+
node.toString().matches("%Exit") or
|
|
19
|
+
node.toString() = "Entry"
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Configuration for PrintCFG that outputs all CFG nodes and edges,
|
|
23
|
-
* excluding exit nodes for deterministic output.
|
|
24
|
+
* excluding entry and exit nodes for deterministic output.
|
|
24
25
|
*/
|
|
25
|
-
query predicate nodes(
|
|
26
|
+
query predicate nodes(ControlFlowNode node, string property, string value) {
|
|
26
27
|
property = "semmle.label" and
|
|
27
28
|
value = node.toString() and
|
|
28
|
-
not
|
|
29
|
+
not isEntryOrExitNode(node)
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
query predicate edges(
|
|
32
|
+
query predicate edges(ControlFlowNode pred, ControlFlowNode succ) {
|
|
32
33
|
pred.getASuccessor() = succ and
|
|
33
|
-
not
|
|
34
|
-
not
|
|
34
|
+
not isEntryOrExitNode(pred) and
|
|
35
|
+
not isEntryOrExitNode(succ)
|
|
35
36
|
}
|
|
@@ -2,31 +2,31 @@
|
|
|
2
2
|
lockVersion: 1.0.0
|
|
3
3
|
dependencies:
|
|
4
4
|
codeql/controlflow:
|
|
5
|
-
version: 2.0.
|
|
5
|
+
version: 2.0.28
|
|
6
6
|
codeql/dataflow:
|
|
7
|
-
version: 2.0
|
|
7
|
+
version: 2.1.0
|
|
8
8
|
codeql/java-all:
|
|
9
|
-
version:
|
|
9
|
+
version: 9.0.0
|
|
10
10
|
codeql/mad:
|
|
11
|
-
version: 1.0.
|
|
11
|
+
version: 1.0.44
|
|
12
12
|
codeql/quantum:
|
|
13
|
-
version: 0.0.
|
|
13
|
+
version: 0.0.22
|
|
14
14
|
codeql/rangeanalysis:
|
|
15
|
-
version: 1.0.
|
|
15
|
+
version: 1.0.44
|
|
16
16
|
codeql/regex:
|
|
17
|
-
version: 1.0.
|
|
17
|
+
version: 1.0.44
|
|
18
18
|
codeql/ssa:
|
|
19
|
-
version: 2.0.
|
|
19
|
+
version: 2.0.20
|
|
20
20
|
codeql/threat-models:
|
|
21
|
-
version: 1.0.
|
|
21
|
+
version: 1.0.44
|
|
22
22
|
codeql/tutorial:
|
|
23
|
-
version: 1.0.
|
|
23
|
+
version: 1.0.44
|
|
24
24
|
codeql/typeflow:
|
|
25
|
-
version: 1.0.
|
|
25
|
+
version: 1.0.44
|
|
26
26
|
codeql/typetracking:
|
|
27
|
-
version: 2.0.25
|
|
28
|
-
codeql/util:
|
|
29
27
|
version: 2.0.28
|
|
28
|
+
codeql/util:
|
|
29
|
+
version: 2.0.31
|
|
30
30
|
codeql/xml:
|
|
31
|
-
version: 1.0.
|
|
31
|
+
version: 1.0.44
|
|
32
32
|
compiled: false
|
|
@@ -8,18 +8,13 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import javascript
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Gets the source function name for which to generate the call graph.
|
|
14
|
-
* Can be a single function name or comma-separated list of function names.
|
|
15
|
-
*/
|
|
16
|
-
external string sourceFunction();
|
|
11
|
+
import ExternalPredicates
|
|
17
12
|
|
|
18
13
|
/**
|
|
19
14
|
* Gets a single source function name from the comma-separated list.
|
|
20
15
|
*/
|
|
21
16
|
string getSourceFunctionName() {
|
|
22
|
-
|
|
17
|
+
exists(string s | sourceFunction(s) | result = s.splitAt(",").trim())
|
|
23
18
|
}
|
|
24
19
|
|
|
25
20
|
/**
|
|
@@ -35,15 +30,5 @@ Function getSourceFunction() {
|
|
|
35
30
|
from CallExpr call, Function source
|
|
36
31
|
where
|
|
37
32
|
call.getEnclosingFunction() = source and
|
|
38
|
-
(
|
|
39
|
-
|
|
40
|
-
source = getSourceFunction()
|
|
41
|
-
or
|
|
42
|
-
// Fallback for unit tests: include test files
|
|
43
|
-
(
|
|
44
|
-
not exists(getSourceFunction()) and
|
|
45
|
-
source.getFile().getParentContainer().getParentContainer().getBaseName() = "test"
|
|
46
|
-
)
|
|
47
|
-
)
|
|
48
|
-
select call,
|
|
49
|
-
"Call from `" + source.getName() + "` to `" + call.getCalleeName() + "`"
|
|
33
|
+
source = getSourceFunction()
|
|
34
|
+
select call, "Call from `" + source.getName() + "` to `" + call.getCalleeName() + "`"
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# CallGraphFromTo for JavaScript
|
|
2
|
+
|
|
3
|
+
Displays calls on reachable paths from a source function to a target function, showing transitive call graph connectivity.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This query identifies all function calls that lie on any transitive call path from a specified source function to a specified target function. Given both a source and target function name, it reports each call site along the connecting paths, which is useful for understanding indirect call chains, security-relevant data flow paths, and function reachability.
|
|
8
|
+
|
|
9
|
+
The query uses transitive closure (`calls*`) to determine reachability, then reports only the direct call sites that contribute to paths between the source and target. It accepts function names via extensible predicates (`sourceFunction` and `targetFunction`) populated via CodeQL data extensions / model packs (see `ExternalPredicates.qll`).
|
|
10
|
+
|
|
11
|
+
## Use Cases
|
|
12
|
+
|
|
13
|
+
This query is primarily used for:
|
|
14
|
+
|
|
15
|
+
- Determining if a call path exists between two functions
|
|
16
|
+
- Mapping indirect call chains from a source to a target function
|
|
17
|
+
- Analyzing security-relevant paths (e.g., from user input handlers to sensitive operations)
|
|
18
|
+
- Understanding transitive dependencies between functions
|
|
19
|
+
|
|
20
|
+
## Example
|
|
21
|
+
|
|
22
|
+
The following JavaScript code demonstrates a transitive call chain from `source` through `intermediate` to `target`:
|
|
23
|
+
|
|
24
|
+
```javascript
|
|
25
|
+
function target() {}
|
|
26
|
+
|
|
27
|
+
function intermediate() {
|
|
28
|
+
target();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function source() {
|
|
32
|
+
intermediate();
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Running with `sourceFunction = "source"` and `targetFunction = "target"` produces results showing each call site on the path with a message like: "Reachable call from `source` to `intermediate`".
|
|
37
|
+
|
|
38
|
+
## Output Format
|
|
39
|
+
|
|
40
|
+
The query is a `@kind problem` query producing rows of:
|
|
41
|
+
|
|
42
|
+
- ``select call, "Reachable call from `caller` to `callee`"``
|
|
43
|
+
|
|
44
|
+
## References
|
|
45
|
+
|
|
46
|
+
- [JavaScript Functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions)
|
|
47
|
+
- [CodeQL Call Graph Analysis](https://codeql.github.com/docs/writing-codeql-queries/about-data-flow-analysis/)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @name Call Graph From To for javascript
|
|
3
|
+
* @description Displays calls on reachable paths from a source function to a target function, showing transitive call graph connectivity.
|
|
4
|
+
* @id javascript/tools/call-graph-from-to
|
|
5
|
+
* @kind problem
|
|
6
|
+
* @problem.severity recommendation
|
|
7
|
+
* @tags call-graph
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import javascript
|
|
11
|
+
import ExternalPredicates
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Gets a single source function name from the comma-separated list.
|
|
15
|
+
*/
|
|
16
|
+
string getSourceFunctionName() {
|
|
17
|
+
exists(string s | sourceFunction(s) | result = s.splitAt(",").trim())
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Gets a single target function name from the comma-separated list.
|
|
22
|
+
*/
|
|
23
|
+
string getTargetFunctionName() {
|
|
24
|
+
exists(string s | targetFunction(s) | result = s.splitAt(",").trim())
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Gets a function by matching against the selected source function names.
|
|
29
|
+
*/
|
|
30
|
+
Function getSourceFunction() {
|
|
31
|
+
exists(string selectedFunc |
|
|
32
|
+
selectedFunc = getSourceFunctionName() and
|
|
33
|
+
result.getName() = selectedFunc
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Gets a function by matching against the selected target function names.
|
|
39
|
+
*/
|
|
40
|
+
Function getTargetFunction() {
|
|
41
|
+
exists(string selectedFunc |
|
|
42
|
+
selectedFunc = getTargetFunctionName() and
|
|
43
|
+
result.getName() = selectedFunc
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Holds if function `caller` directly calls function `callee` by name.
|
|
49
|
+
*/
|
|
50
|
+
predicate calls(Function caller_, Function callee_) {
|
|
51
|
+
exists(CallExpr c |
|
|
52
|
+
c.getEnclosingFunction() = caller_ and
|
|
53
|
+
c.getCalleeName() = callee_.getName()
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
from CallExpr call, Function caller
|
|
58
|
+
where
|
|
59
|
+
call.getEnclosingFunction() = caller and
|
|
60
|
+
exists(Function source, Function target |
|
|
61
|
+
source = getSourceFunction() and
|
|
62
|
+
target = getTargetFunction() and
|
|
63
|
+
calls*(source, caller) and
|
|
64
|
+
exists(Function callee |
|
|
65
|
+
call.getCalleeName() = callee.getName() and
|
|
66
|
+
calls*(callee, target)
|
|
67
|
+
)
|
|
68
|
+
)
|
|
69
|
+
select call, "Reachable call from `" + caller.getName() + "` to `" + call.getCalleeName() + "`"
|
|
@@ -8,18 +8,13 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import javascript
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Gets the target function name for which to generate the call graph.
|
|
14
|
-
* Can be a single function name or comma-separated list of function names.
|
|
15
|
-
*/
|
|
16
|
-
external string targetFunction();
|
|
11
|
+
import ExternalPredicates
|
|
17
12
|
|
|
18
13
|
/**
|
|
19
14
|
* Gets a single target function name from the comma-separated list.
|
|
20
15
|
*/
|
|
21
16
|
string getTargetFunctionName() {
|
|
22
|
-
|
|
17
|
+
exists(string s | targetFunction(s) | result = s.splitAt(",").trim())
|
|
23
18
|
}
|
|
24
19
|
|
|
25
20
|
/**
|
|
@@ -32,16 +27,5 @@ string getCallerName(CallExpr call) {
|
|
|
32
27
|
}
|
|
33
28
|
|
|
34
29
|
from CallExpr call
|
|
35
|
-
where
|
|
36
|
-
|
|
37
|
-
// Use external predicate if available
|
|
38
|
-
call.getCalleeName() = getTargetFunctionName()
|
|
39
|
-
or
|
|
40
|
-
// Fallback for unit tests: include test files
|
|
41
|
-
(
|
|
42
|
-
not exists(getTargetFunctionName()) and
|
|
43
|
-
call.getFile().getParentContainer().getParentContainer().getBaseName() = "test"
|
|
44
|
-
)
|
|
45
|
-
)
|
|
46
|
-
select call,
|
|
47
|
-
"Call to `" + call.getCalleeName() + "` from `" + getCallerName(call) + "`"
|
|
30
|
+
where call.getCalleeName() = getTargetFunctionName()
|
|
31
|
+
select call, "Call to `" + call.getCalleeName() + "` from `" + getCallerName(call) + "`"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared extensible predicate declarations for MCP server tools queries.
|
|
3
|
+
* Values are provided via dataExtensions YAML files during testing,
|
|
4
|
+
* or via a temporary data extension pack at runtime from the MCP server.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** Holds for each source function name for call graph analysis. */
|
|
8
|
+
extensible predicate sourceFunction(string name);
|
|
9
|
+
|
|
10
|
+
/** Holds for each target function name for call graph analysis. */
|
|
11
|
+
extensible predicate targetFunction(string name);
|
|
12
|
+
|
|
13
|
+
/** Holds for each selected source file path for AST/CFG printing. */
|
|
14
|
+
extensible predicate selectedSourceFiles(string path);
|
|
@@ -8,18 +8,13 @@
|
|
|
8
8
|
|
|
9
9
|
import javascript
|
|
10
10
|
import semmle.javascript.PrintAst
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Gets the source files to generate AST from.
|
|
14
|
-
* Can be a single file path or comma-separated list of file paths.
|
|
15
|
-
*/
|
|
16
|
-
external string selectedSourceFiles();
|
|
11
|
+
import ExternalPredicates
|
|
17
12
|
|
|
18
13
|
/**
|
|
19
14
|
* Gets a single source file from the comma-separated list.
|
|
20
15
|
*/
|
|
21
16
|
string getSelectedSourceFile() {
|
|
22
|
-
|
|
17
|
+
exists(string s | selectedSourceFiles(s) | result = s.splitAt(",").trim())
|
|
23
18
|
}
|
|
24
19
|
|
|
25
20
|
/**
|
|
@@ -30,11 +25,14 @@ File getSelectedFile() {
|
|
|
30
25
|
selectedFile = getSelectedSourceFile() and
|
|
31
26
|
(
|
|
32
27
|
// Match by exact relative path from source root
|
|
33
|
-
result.getRelativePath() = selectedFile
|
|
28
|
+
result.getRelativePath() = selectedFile
|
|
29
|
+
or
|
|
34
30
|
// Match by file name if no path separators
|
|
35
|
-
|
|
31
|
+
not selectedFile.matches("%/%") and result.getBaseName() = selectedFile
|
|
32
|
+
or
|
|
36
33
|
// Match by ending path component
|
|
37
|
-
result.getAbsolutePath().suffix(result.getAbsolutePath().length() - selectedFile.length()) =
|
|
34
|
+
result.getAbsolutePath().suffix(result.getAbsolutePath().length() - selectedFile.length()) =
|
|
35
|
+
selectedFile
|
|
38
36
|
)
|
|
39
37
|
)
|
|
40
38
|
}
|
|
@@ -46,15 +44,6 @@ File getSelectedFile() {
|
|
|
46
44
|
class Cfg extends PrintAstConfiguration {
|
|
47
45
|
override predicate shouldPrint(Locatable e, Location l) {
|
|
48
46
|
super.shouldPrint(e, l) and
|
|
49
|
-
(
|
|
50
|
-
// Use external predicate if available
|
|
51
|
-
l.getFile() = getSelectedFile()
|
|
52
|
-
or
|
|
53
|
-
// Fallback for unit tests: include test files
|
|
54
|
-
(
|
|
55
|
-
not exists(getSelectedFile()) and
|
|
56
|
-
l.getFile().getParentContainer().getParentContainer().getBaseName() = "test"
|
|
57
|
-
)
|
|
58
|
-
)
|
|
47
|
+
l.getFile() = getSelectedFile()
|
|
59
48
|
}
|
|
60
49
|
}
|
|
@@ -16,6 +16,4 @@ query predicate nodes(ControlFlowNode node, string property, string value) {
|
|
|
16
16
|
value = node.toString()
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
query predicate edges(ControlFlowNode pred, ControlFlowNode succ) {
|
|
20
|
-
pred.getASuccessor() = succ
|
|
21
|
-
}
|
|
19
|
+
query predicate edges(ControlFlowNode pred, ControlFlowNode succ) { pred.getASuccessor() = succ }
|
|
@@ -2,29 +2,29 @@
|
|
|
2
2
|
lockVersion: 1.0.0
|
|
3
3
|
dependencies:
|
|
4
4
|
codeql/concepts:
|
|
5
|
-
version: 0.0.
|
|
5
|
+
version: 0.0.18
|
|
6
6
|
codeql/controlflow:
|
|
7
|
-
version: 2.0.
|
|
7
|
+
version: 2.0.28
|
|
8
8
|
codeql/dataflow:
|
|
9
|
-
version: 2.0
|
|
9
|
+
version: 2.1.0
|
|
10
10
|
codeql/javascript-all:
|
|
11
|
-
version: 2.6.
|
|
11
|
+
version: 2.6.24
|
|
12
12
|
codeql/mad:
|
|
13
|
-
version: 1.0.
|
|
13
|
+
version: 1.0.44
|
|
14
14
|
codeql/regex:
|
|
15
|
-
version: 1.0.
|
|
15
|
+
version: 1.0.44
|
|
16
16
|
codeql/ssa:
|
|
17
|
-
version: 2.0.
|
|
17
|
+
version: 2.0.20
|
|
18
18
|
codeql/threat-models:
|
|
19
|
-
version: 1.0.
|
|
19
|
+
version: 1.0.44
|
|
20
20
|
codeql/tutorial:
|
|
21
|
-
version: 1.0.
|
|
21
|
+
version: 1.0.44
|
|
22
22
|
codeql/typetracking:
|
|
23
|
-
version: 2.0.25
|
|
24
|
-
codeql/util:
|
|
25
23
|
version: 2.0.28
|
|
24
|
+
codeql/util:
|
|
25
|
+
version: 2.0.31
|
|
26
26
|
codeql/xml:
|
|
27
|
-
version: 1.0.
|
|
27
|
+
version: 1.0.44
|
|
28
28
|
codeql/yaml:
|
|
29
|
-
version: 1.0.
|
|
29
|
+
version: 1.0.44
|
|
30
30
|
compiled: false
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
name: advanced-security/ql-mcp-javascript-tools-src
|
|
2
|
-
version: 2.
|
|
2
|
+
version: 2.25.0
|
|
3
3
|
description: 'Queries for codeql-development-mcp-server tools for javascript language'
|
|
4
4
|
library: false
|
|
5
5
|
dependencies:
|
|
6
|
-
codeql/javascript-all: 2.6.
|
|
6
|
+
codeql/javascript-all: 2.6.24
|
|
@@ -8,18 +8,13 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import python
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Gets the source function name for which to generate the call graph.
|
|
14
|
-
* Can be a single function name or comma-separated list of function names.
|
|
15
|
-
*/
|
|
16
|
-
external string sourceFunction();
|
|
11
|
+
import ExternalPredicates
|
|
17
12
|
|
|
18
13
|
/**
|
|
19
14
|
* Gets a single source function name from the comma-separated list.
|
|
20
15
|
*/
|
|
21
16
|
string getSourceFunctionName() {
|
|
22
|
-
|
|
17
|
+
exists(string s | sourceFunction(s) | result = s.splitAt(",").trim())
|
|
23
18
|
}
|
|
24
19
|
|
|
25
20
|
/**
|
|
@@ -35,15 +30,6 @@ Function getSourceFunction() {
|
|
|
35
30
|
from CallNode call, Function source
|
|
36
31
|
where
|
|
37
32
|
call.getScope() = source and
|
|
38
|
-
(
|
|
39
|
-
// Use external predicate if available
|
|
40
|
-
source = getSourceFunction()
|
|
41
|
-
or
|
|
42
|
-
// Fallback for unit tests: include test files
|
|
43
|
-
(
|
|
44
|
-
not exists(getSourceFunction()) and
|
|
45
|
-
call.getLocation().getFile().getParentContainer().getParentContainer().getBaseName() = "test"
|
|
46
|
-
)
|
|
47
|
-
)
|
|
33
|
+
source = getSourceFunction()
|
|
48
34
|
select call.getNode(),
|
|
49
35
|
"Call from `" + source.getName() + "` to `" + call.getNode().(Call).getFunc().(Name).getId() + "`"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# CallGraphFromTo for Python
|
|
2
|
+
|
|
3
|
+
Displays calls on reachable paths from a source function to a target function, showing transitive call graph connectivity.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This query identifies all function calls that lie on any transitive call path from a specified source function to a specified target function. Given both a source and target function name, it reports each call site along the connecting paths, which is useful for understanding indirect call chains, security-relevant data flow paths, and function reachability.
|
|
8
|
+
|
|
9
|
+
The query uses transitive closure (`calls*`) to determine reachability, then reports only the direct call sites that contribute to paths between the source and target. It accepts function names via extensible predicates (`sourceFunction` and `targetFunction`) populated via CodeQL data extensions / model packs (see `ExternalPredicates.qll`).
|
|
10
|
+
|
|
11
|
+
## Use Cases
|
|
12
|
+
|
|
13
|
+
This query is primarily used for:
|
|
14
|
+
|
|
15
|
+
- Determining if a call path exists between two functions
|
|
16
|
+
- Mapping indirect call chains from a source to a target function
|
|
17
|
+
- Analyzing security-relevant paths (e.g., from user input handlers to sensitive operations)
|
|
18
|
+
- Understanding transitive dependencies between functions
|
|
19
|
+
|
|
20
|
+
## Example
|
|
21
|
+
|
|
22
|
+
The following Python code demonstrates a transitive call chain from `source` through `intermediate` to `target`:
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
def target():
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
def intermediate():
|
|
29
|
+
target()
|
|
30
|
+
|
|
31
|
+
def source():
|
|
32
|
+
intermediate()
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Running with `sourceFunction = "source"` and `targetFunction = "target"` produces results showing each call site on the path with a message like: "Reachable call from `source` to `intermediate`".
|
|
36
|
+
|
|
37
|
+
## Output Format
|
|
38
|
+
|
|
39
|
+
The query is a `@kind problem` query producing rows of:
|
|
40
|
+
|
|
41
|
+
- ``select call, "Reachable call from `caller` to `callee`"``
|
|
42
|
+
|
|
43
|
+
## References
|
|
44
|
+
|
|
45
|
+
- [Python Functions](https://docs.python.org/3/tutorial/controlflow.html#defining-functions)
|
|
46
|
+
- [CodeQL Call Graph Analysis](https://codeql.github.com/docs/writing-codeql-queries/about-data-flow-analysis/)
|