Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
71b1850
unified: Restrict taint reach metric to local and remote sources
asgerf Nov 7, 2026
55cbe32
unified: Add inferBaseType and inferVariableType
asgerf Oct 30, 2026
00cfc7f
unified: Initial support for properties in MaD
asgerf Nov 6, 2026
293652e
unified: Remove TODO comment from CommandInjection
asgerf Nov 6, 2026
e460c3b
unified: Add test without stub declarations
asgerf Nov 6, 2026
62e936a
unified: Restrict injection queries to local/remote sources
asgerf Nov 3, 2026
67426cd
unified: Track types from models in static name binding
asgerf Nov 4, 2026
dbf8de7
unified: Track references to model types in type inference
asgerf Nov 4, 2026
b810abe
unified: Include references to class declaration
asgerf Nov 6, 2026
27230e9
unified: Update test output after rebasing
asgerf Nov 6, 2026
26f0dc4
unified: Use TypeSelector for constructor matching
asgerf Nov 6, 2026
0eda8ed
unified: Match property base using type selectors
asgerf Nov 6, 2026
8655d25
unified: Make ExprPositions aware of types from models
asgerf Nov 6, 2026
c2d9498
unified: Seed type inference with constructor calls from model
asgerf Nov 6, 2026
e835afc
unified: Ensure unique type representative
asgerf Nov 6, 2026
323c3e9
unified: Update path injection results
asgerf Nov 6, 2026
ede7888
unified: Add regression test for extension targeting model type
asgerf Nov 7, 2026
2aafb65
unified: Do not return extensions in getDeclaration()
asgerf Nov 7, 2026
e8082e7
unified: Add regression tests for implicit 'self' access
asgerf Nov 7, 2026
a41f207
unified: Avoid setting type context if expr resolves to a value
asgerf Nov 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ module TaintReach {
}

module TaintReachConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { Models::isSource(node, _) }
predicate isSource(DataFlow::Node node) { Models::isSource(node, ["local", "remote"]) }

predicate isSink(DataFlow::Node node) { node instanceof Candidate }
}
Expand Down
2 changes: 1 addition & 1 deletion unified/ql/lib/codeql/unified/internal/ExprPositions.qll
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ predicate isInSyntacticTypeContext(Expr expr) {
}

private predicate isInTypeContext0(Expr expr) {
exists(NameBinding::getTypeFromRef(expr))
NameBinding::isTypeRef(expr)
or
isInTypeContext0(expr.getEnclosingExpr())
}
Expand Down
38 changes: 37 additions & 1 deletion unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module;
private import unified
private import codeql.unified.internal.LocalNameBinding
private import codeql.unified.internal.NameBindingPlugin
private import codeql.unified.internal.mad.LegacyMaD as MaD

cached
private newtype TNameBindingNode =
Expand All @@ -21,7 +22,8 @@ private newtype TNameBindingNode =
} or
TModuleScope(ModuleScopeRepr repr) or
TFolderScope(Folder folder) or
TModuleRoot()
TModuleRoot() or
TTypeSelector(MaD::TypeSelector type)

/**
* A node in a graph, in which name-binding rules are represented as edges between nodes.
Expand Down Expand Up @@ -61,6 +63,8 @@ class NameBindingNode extends TNameBindingNode {
/** Holds if this represents the root namespace in which all named modules are members. */
predicate isModuleRoot() { this = TModuleRoot() }

predicate isTypeSelector(MaD::TypeSelector type) { this = TTypeSelector(type) }

/**
* Gets an AST node wrapped by this name-binding node, if such a node exists.
*
Expand Down Expand Up @@ -104,6 +108,10 @@ class NameBindingNode extends TNameBindingNode {
exists(Folder folder | this.isFolderScope(folder) and result = "FolderScope(" + folder + ")")
or
this.isModuleRoot() and result = "ModuleRoot"
or
exists(MaD::TypeSelector type |
this.isTypeSelector(type) and result = "TypeSelector(" + type + ")"
)
}

Location getLocation() {
Expand Down Expand Up @@ -224,6 +232,11 @@ predicate storeStep(NameBindingNode node1, string name, NameBindingNode node2) {
)
or
FolderHeuristic::storeStep(node1, name, node2)
or
exists(MaD::TypeSelector type |
node1.isTypeSelector(type.append(name)) and
node2.isTypeSelector(type)
)
}

predicate valueStep(NameBindingNode node1, NameBindingNode node2) {
Expand Down Expand Up @@ -290,6 +303,11 @@ predicate valueStep(NameBindingNode node1, NameBindingNode node2) {
node2.isLocalName(self) and
self.hasNameAndScope(any(NameBindingPlugin p).getStaticSelfName(cls), cls)
)
or
exists(TopLevel top |
node1.isTypeSelector("") and
node2.isLocalNamespace(top.getBody())
)
}

private predicate isImportPrefix(Expr e) {
Expand Down Expand Up @@ -529,6 +547,8 @@ private module TrackNameBindingInput implements TrackInputSig {
node.isIdentifier(decl) and
not isTrivialNameAlias(decl)
)
or
node.isTypeSelector(_)
}
}

Expand All @@ -542,6 +562,14 @@ private NameBindingNode trackNameBinding(NameBinding decl) {
)
}

/** Gets a name-binding node that may refer to the given type from a model. */
NameBindingNode trackTypeSelector(MaD::TypeSelector type) {
exists(NameBindingNode start |
start.isTypeSelector(type) and
result = TrackNameBinding::track(start)
)
}

/** Holds if `node` should be included in the debug view. */
private signature predicate relevantNodeSig(AstNode node);

Expand Down Expand Up @@ -842,6 +870,14 @@ Identifier getTypeFromRef(AstNode access) {
)
}

/** Holds if `access` is a reference to a type. */
predicate isTypeRef(AstNode access) {
exists(getTypeFromRef(access))
or
not exists(getStaticBindingTargetFromRef(access)) and
trackTypeSelector(_) = getNodeFromRef(access)
}

/**
* Gets the name of the implicit receiver parameter in scope at `callable` (possibly declared by an outer callable).
*
Expand Down
Loading
Loading