Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/microsoft-codeql-pack-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
language: ['csharp', 'cpp', 'java', 'javascript', 'python', 'ruby', 'go', 'rust', 'swift', 'powershell']
language: ['csharp', 'cpp', 'java', 'javascript', 'python', 'ruby', 'go', 'rust', 'swift', 'powershell', 'iac']
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "iac"]
path = iac
url = https://github.com/advanced-security/codeql-extractor-iac
1 change: 1 addition & 0 deletions iac
Submodule iac added at 1709e3
4 changes: 2 additions & 2 deletions powershell/ql/lib/semmle/code/powershell/ApiGraphs.qll
Original file line number Diff line number Diff line change
Expand Up @@ -563,15 +563,15 @@ module API {
)
or
exists(DataFlow::AutomaticVariableNode automatic |
automatic.getName() = name and
automatic.getLowerCaseName() = name and
succ = getForwardStartNode(automatic)
)
or
succ = getAnImplicitRootMember(name)
)
or
exists(DataFlow::QualifiedTypeNameNode typeName |
typeName.getName() = name and
typeName.getLowerCaseName() = name and
pred = MkNamespaceOfTypeNameNode(typeName) and
succ = getForwardStartNode(typeName)
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
private import AstImport

class AutomaticVariable extends Expr, TAutomaticVariable {
final override string toString() { result = this.getName() }
final override string toString() { result = this.getLowerCaseName() }

string getName() { any(Synthesis s).automaticVariableName(this, result) }
string getLowerCaseName() { any(Synthesis s).automaticVariableName(this, result) }

bindingset[result]
pragma[inline_late]
string getAName() { result.toLowerCase() = this.getLowerCaseName() }
}

class MyInvocation extends AutomaticVariable {
MyInvocation() { this.getName() = "myinvocation" }
MyInvocation() { this.getLowerCaseName() = "myinvocation" }
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,16 @@ newtype ChildIndex =
ExprRedirection(int i) { exists(any(Raw::Cmd cmdExpr).getRedirection(i)) } or
FunDefFun() or
TypeDefType() or
TypeMember(int i) {
exists(any(Raw::TypeStmt typedef).getMember(i))
// or
// hasMemberInType(_, _, i, _)
} or
TypeMember(int i) { exists(any(Raw::TypeStmt typedef).getMember(i)) } or
ThisVar() or
PipelineIteratorVar() or
PipelineByPropertyNameIteratorVar(Raw::PipelineByPropertyNameParameter p) or
RealVar(string name) { name = variableNameInScope(_, _) } or
ProcessBlockPipelineVarReadAccess() or
ProcessBlockPipelineByPropertyNameVarReadAccess(string name) {
name = any(Raw::PipelineByPropertyNameParameter p).getLowerCaseName()
}
} or
EnvVar(string var) { Raw::isEnvVariableAccess(_, var) }

int synthPipelineParameterChildIndex(Raw::ScriptBlock sb) {
// If there is a parameter block, but no pipeline parameter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@ class CmdCall extends CallExpr, TCmd {
class CallOperator extends CmdCall {
CallOperator() { getRawAst(this) instanceof Raw::CallOperator }

Expr getCommand() { result = this.getArgument(0) }
Expr getCommand() { result = this.getCallee() }
}

/** A call to the dot-sourcing `.`. */
class DotSourcingOperator extends CmdCall {
DotSourcingOperator() { getRawAst(this) instanceof Raw::DotSourcingOperator }

Expr getPath() { result = this.getArgument(0) }
Expr getCommand() { result = this.getCallee() }
}

class JoinPath extends CmdCall {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
private import AstImport

class EnvVariable extends Expr, TEnvVariable {
final override string toString() { result = this.getName() }
class EnvVariable extends Variable instanceof EnvVariableImpl {
string getLowerCaseName() { result = super.getLowerCaseNameImpl() }

string getName() { any(Synthesis s).envVariableName(this, result) }
}
bindingset[name]
pragma[inline_late]
final predicate matchesName(string name) { this.getLowerCaseName() = name.toLowerCase() }

bindingset[result]
pragma[inline_late]
final string getAName() { result.toLowerCase() = this.getLowerCaseName() }

class SystemDrive extends EnvVariable {
SystemDrive() { this.getName() = "systemdrive" }
}
override Ast getChild(ChildIndex childIndex) { none() }
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,13 @@ class ConstructorCall extends InvokeMemberExpr {
this.isStatic() and typename = this.getQualifier() and this.getLowerCaseName() = "new"
}

/** Gets a name of the type being constructed by this constructor call. */
bindingset[result]
pragma[inline_late]
string getAConstructedTypeName() { result = typename.getAName() }

/** Gets the name of the type being constructed by this constructor call. */
string getConstructedTypeName() { result = typename.getName() }
string getLowerCaseConstructedTypeName() { result = typename.getLowerCaseName() }
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import powershell

abstract private class AbstractObjectCreation extends CallExpr {
/** The name of the type of the object being constructed. */
abstract string getConstructedTypeName();
bindingset[result]
pragma[inline_late]
string getAConstructedTypeName() { result.toLowerCase() = this.getLowerCaseConstructedTypeName() }

abstract string getLowerCaseConstructedTypeName();

abstract Expr getConstructedTypeExpr();
}
Expand All @@ -14,8 +18,14 @@ abstract private class AbstractObjectCreation extends CallExpr {
* ```
*/
class NewObjectCreation extends AbstractObjectCreation, ConstructorCall {
final override string getConstructedTypeName() {
result = ConstructorCall.super.getConstructedTypeName()
final override string getLowerCaseConstructedTypeName() {
result = ConstructorCall.super.getLowerCaseConstructedTypeName()
}

bindingset[result]
pragma[inline_late]
final override string getAConstructedTypeName() {
result = ConstructorCall.super.getAConstructedTypeName()
}

final override Expr getConstructedTypeExpr() { result = typename }
Expand All @@ -30,8 +40,8 @@ class NewObjectCreation extends AbstractObjectCreation, ConstructorCall {
class DotNetObjectCreation extends AbstractObjectCreation, CmdCall {
DotNetObjectCreation() { this.getLowerCaseName() = "new-object" }

final override string getConstructedTypeName() {
result = this.getConstructedTypeExpr().(StringConstExpr).getValueString()
final override string getLowerCaseConstructedTypeName() {
result = this.getConstructedTypeExpr().(StringConstExpr).getValueString().toLowerCase()
}

final override Expr getConstructedTypeExpr() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ class NamedAttributeArgument extends @named_attribute_argument, Ast {
}

class ValueFromPipelineAttribute extends NamedAttributeArgument {
ValueFromPipelineAttribute() { this.getName() = "ValueFromPipeline" }
ValueFromPipelineAttribute() { this.getName().toLowerCase() = "valuefrompipeline" }
}

class ValueFromPipelineByPropertyName extends NamedAttributeArgument {
ValueFromPipelineByPropertyName() { this.getName() = "ValueFromPipelineByPropertyName" }
ValueFromPipelineByPropertyName() {
this.getName().toLowerCase() = "valuefrompipelinebypropertyname"
}
}
94 changes: 74 additions & 20 deletions powershell/ql/lib/semmle/code/powershell/ast/internal/Synthesis.qll
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ private import Type
private import Scopes
private import BoolLiteral
private import Member
private import EnvVariable
private import Raw.Raw as Raw
private import codeql.util.Boolean
private import AutomaticVariable

newtype VarKind =
ThisVarKind() or
EnvVarKind(string var) { Raw::isEnvVariableAccess(_, var) } or
ParamVarRealKind() or
PipelineIteratorKind() or
PipelineByPropertyNameIteratorKind(string name) {
Expand All @@ -39,7 +39,6 @@ newtype SynthKind =
TypeSynthKind() or
BoolLiteralKind(Boolean b) or
NullLiteralKind() or
EnvVariableKind(string var) { Raw::isEnvVariableAccess(_, var) } or
AutomaticVariableKind(string var) { Raw::isAutomaticVariableAccess(_, var) } or
VarSynthKind(VarKind k)

Expand Down Expand Up @@ -96,8 +95,6 @@ class Synthesis extends TSynthesis {

predicate booleanValue(BoolLiteral b, boolean value) { none() }

predicate envVariableName(EnvVariable var, string name) { none() }

predicate automaticVariableName(AutomaticVariable var, string name) { none() }

final string toString() { none() }
Expand Down Expand Up @@ -152,6 +149,77 @@ private module ThisSynthesis {
}
}

private module EnvironmentVariables {
bindingset[var]
private Raw::TopLevelScriptBlock getScope(string var) {
result =
min(Raw::TopLevelScriptBlock scriptBlock, Raw::VarAccess va, Location loc |
Raw::isEnvVariableAccess(va, var) and
va.getParent+() = scriptBlock and
loc = scriptBlock.getLocation()
|
scriptBlock order by loc.getFile().getAbsolutePath()
)
}

private class EnvironmentVariables extends Synthesis {
final override predicate child(Raw::Ast parent, ChildIndex i, Child child) {
exists(Raw::VarAccess va, string s0 |
parent = getScope(s0) and
va.getUserPath().toLowerCase() = "env:" + s0 and
Raw::isEnvVariableAccess(va, s0) and
child = SynthChild(VarSynthKind(EnvVarKind(s0))) and
i = EnvVar(s0)
)
}

override predicate variableSynthName(VariableSynth v, string name) {
exists(string name0 |
v = TVariableSynth(_, EnvVar(name0)) and
name = "env:" + name0
)
}
}
}

private module EnvironmentVariableAccessSynth {
private class EnvVarAccessSynthesis extends Synthesis {
final override predicate isRelevant(Raw::Ast a) { Raw::isEnvVariableAccess(a, _) }

final override VarAccess getResultAstImpl(Raw::Ast r) {
exists(Raw::Ast parent, ChildIndex i |
this.envVarAccess(parent, i, _, r, _) and
result = TVarAccessSynth(parent, i)
)
}

private predicate envVarAccess(Raw::Ast parent, ChildIndex i, Child child, Raw::VarAccess va, string var) {
va = parent.getChild(toRawChildIndex(i)) and
Raw::isEnvVariableAccess(va, var) and
child = SynthChild(VarAccessSynthKind(TVariableSynth(_, EnvVar(var))))
}

override predicate child(Raw::Ast parent, ChildIndex i, Child child) {
this.envVarAccess(parent, i, child, _, _)
}

final override predicate getAnAccess(VarAccessSynth va, Variable v) {
exists(Raw::Ast parent, ChildIndex i, string var |
this.envVarAccess(parent, i, _, _, var) and
v = TVariableSynth(_, EnvVar(var)) and
va = TVarAccessSynth(parent, i)
)
}

override Location getLocation(Ast n) {
exists(Raw::Ast scope |
n = TVariableSynth(scope, EnvVar(_)) and
result = scope.getLocation()
)
}
}
}

private module SetVariableAssignment {
private class SetVariableAssignment extends Synthesis {
override predicate explicitAssignment(Raw::Ast dest, string name, Raw::Ast assignment) {
Expand Down Expand Up @@ -277,7 +345,7 @@ private module ParameterSynth {
// has a static type.
this.parameter(parent, i, p, _) and
n = TVariableSynth(parent, i) and
type = p.getStaticType()
type = p.getStaticType().toLowerCase()
)
}
}
Expand Down Expand Up @@ -462,7 +530,7 @@ private module TypeSynth {
override predicate typeName(Type t, string name) {
exists(Raw::TypeStmt typeStmt |
t = TTypeSynth(typeStmt, _) and
typeStmt.getName() = name
typeStmt.getName().toLowerCase() = name
)
}

Expand Down Expand Up @@ -673,7 +741,6 @@ private module LiteralSynth {
exists(Raw::Ast parent, ChildIndex i | this.child(parent, i, _, r) |
result = TBoolLiteral(parent, i) or
result = TNullLiteral(parent, i) or
result = TEnvVariable(parent, i) or
result = TAutomaticVariable(parent, i)
)
}
Expand All @@ -692,12 +759,6 @@ private module LiteralSynth {
s = "null" and
child = SynthChild(NullLiteralKind())
or
exists(string s0 |
s = "env:" + s0 and
Raw::isEnvVariableAccess(va, s0) and
child = SynthChild(EnvVariableKind(s0))
)
or
isAutomaticVariableAccess(va, s) and
child = SynthChild(AutomaticVariableKind(s))
)
Expand All @@ -714,13 +775,6 @@ private module LiteralSynth {
)
}

final override predicate envVariableName(EnvVariable var, string name) {
exists(Raw::Ast parent, ChildIndex i |
var = TEnvVariable(parent, i) and
this.child(parent, i, SynthChild(EnvVariableKind(name)))
)
}

final override predicate automaticVariableName(AutomaticVariable var, string name) {
exists(Raw::Ast parent, ChildIndex i |
var = TAutomaticVariable(parent, i) and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ private module Cached {
TUsingExpr(Raw::UsingExpr u) or
TBoolLiteral(Raw::Ast parent, ChildIndex i) { mkSynthChild(BoolLiteralKind(_), parent, i) } or
TNullLiteral(Raw::Ast parent, ChildIndex i) { mkSynthChild(NullLiteralKind(), parent, i) } or
TEnvVariable(Raw::Ast parent, ChildIndex i) { mkSynthChild(EnvVariableKind(_), parent, i) } or
TAutomaticVariable(Raw::Ast parent, ChildIndex i) {
mkSynthChild(AutomaticVariableKind(_), parent, i)
}
Expand All @@ -180,15 +179,15 @@ private module Cached {

class TAstSynth =
TExprStmtSynth or TFunctionSynth or TBoolLiteral or TNullLiteral or TVarAccessSynth or
TEnvVariable or TTypeSynth or TAutomaticVariable or TVariableSynth;
TTypeSynth or TAutomaticVariable or TVariableSynth;

class TExpr =
TArrayExpr or TArrayLiteral or TOperation or TConstExpr or TConvertExpr or TErrorExpr or
THashTableExpr or TIndexExpr or TInvokeMemberExpr or TCmd or TMemberExpr or TPipeline or
TPipelineChain or TStringConstExpr or TConditionalExpr or TVarAccess or
TExpandableStringExpr or TScriptBlockExpr or TExpandableSubExpr or TTypeNameExpr or
TUsingExpr or TAttributedExpr or TIf or TBoolLiteral or TNullLiteral or TThisExpr or
TEnvVariable or TAutomaticVariable or TParenExpr;
TAutomaticVariable or TParenExpr;

class TStmt =
TAssignStmt or TBreakStmt or TContinueStmt or TDataStmt or TDoUntilStmt or TDoWhileStmt or
Expand Down Expand Up @@ -308,7 +307,6 @@ private module Cached {
result = TBoolLiteral(parent, i) or
result = TNullLiteral(parent, i) or
result = TVarAccessSynth(parent, i) or
result = TEnvVariable(parent, i) or
result = TTypeSynth(parent, i) or
result = TAutomaticVariable(parent, i) or
result = TVariableSynth(parent, i)
Expand Down
Loading
Loading