Merge branch 'main' into psscriptanalyzer-port

This commit is contained in:
Mathias Vorreiter Pedersen
2025-04-22 16:42:23 +01:00
committed by GitHub
24 changed files with 4052 additions and 104 deletions

27
.github/workflows/sync-main-tags.yml vendored Normal file
View File

@@ -0,0 +1,27 @@
name: Sync Main Tags
on:
pull_request:
types:
- closed
branches:
- main
jobs:
sync-main-tags:
name: Sync Main Tags
runs-on: ubuntu-latest
if: github.repository == 'microsoft/codeql' && github.event.pull_request.merged == true && github.event.pull_request.head.ref == 'auto/sync-main-pr'
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Push Tags
run: |
git fetch upstream --tags --force
git push --force origin --tags
env:
GH_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}

View File

@@ -41,10 +41,6 @@ containerparent(
unique int child: @container ref
);
is_in_psmodule_path(
int file: @file ref
);
/* Comments */
comment_entity(
unique int id: @comment_entity,
@@ -68,15 +64,15 @@ extractor_messages(
);
parent(
int child: @ast ref,
int parent: @ast ref
int parent: @ast ref,
int child: @ast ref
);
/* AST Nodes */
// This is all the kinds of nodes that can inherit from Ast
// https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.language.ast?view=powershellsdk-7.3.0
@ast = @not_implemented | @attribute_base | @catch_clause | @command_element |
@member | @named_block | @param_block | @parameter | @redirection | @script_block | @statement | @statement_block | @named_attribute_argument;
@member | @named_block | @param_block | @parameter | @redirection | @script_block | @statement | @statement_block;
// https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.language.attributebaseast?view=powershellsdk-7.2.0
@attribute_base = @attribute | @type_constraint;
@@ -86,7 +82,7 @@ parent(
// https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.language.commandbaseast?view=powershellsdk-7.3.0
@command_base = @command | @command_expression;
// https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.language.chainableast?view=powershellsdk-7.3.0
@chainable = @command_base | @pipeline | @pipeline_chain;
@chainable = @pipeline | @pipeline_chain;
//https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.language.pipelinebaseast?view=powershellsdk-7.3.0
@pipeline_base = @chainable | @error_statement | @assignment_statement;
// https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.language.statementast?view=powershellsdk-7.3.0
@@ -413,13 +409,13 @@ if_statement(
if_statement_clause(
int id: @if_statement ref,
int index: int ref,
int item1: @pipeline_base ref,
int item2: @statement_block ref
int item1: @ast ref,
int item2: @ast ref
)
if_statement_else(
int id: @if_statement ref,
int elseItem: @statement_block ref
int elseItem: @ast ref
)
if_statement_location(
@@ -471,7 +467,7 @@ statement_block_trap(
// https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.language.subexpressionast?view=powershellsdk-7.3.0
sub_expression(
unique int id: @sub_expression,
int subExpression: @statement_block ref
int subExpression: @ast ref
)
sub_expression_location(
@@ -631,7 +627,7 @@ exit_statement(
exit_statement_pipeline(
int id: @exit_statement ref,
int expression: @pipeline_base ref
int expression: @ast ref
)
exit_statement_location(
@@ -818,7 +814,7 @@ continue_statement_location(
statement_label(
int id: @labelled_statement ref,
int label: @expression ref
int label: @ast ref
)
// ReturnStatementAst
@@ -829,7 +825,7 @@ return_statement(
return_statement_pipeline(
int id: @return_statement ref,
int pipeline: @pipeline_base ref
int pipeline: @ast ref
)
return_statement_location(
@@ -841,12 +837,12 @@ return_statement_location(
// https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.language.dowhilestatementast?view=powershellsdk-7.3.0
do_while_statement(
unique int id: @do_while_statement,
int body: @statement_block ref
int body: @ast ref
)
do_while_statement_condition(
int id: @do_while_statement ref,
int condition: @pipeline_base ref
int condition: @ast ref
)
do_while_statement_location(
@@ -858,12 +854,12 @@ do_while_statement_location(
// https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.language.dountilstatementast?view=powershellsdk-7.3.0
do_until_statement(
unique int id: @do_until_statement,
int body: @statement_block ref
int body: @ast ref
)
do_until_statement_condition(
int id: @do_until_statement ref,
int condition: @pipeline_base ref
int condition: @ast ref
)
do_until_statement_location(
@@ -875,12 +871,12 @@ do_until_statement_location(
// https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.language.whilestatementast?view=powershellsdk-7.3.0
while_statement(
unique int id: @while_statement,
int body: @statement_block ref
int body: @ast ref
)
while_statement_condition(
int id: @while_statement ref,
int condition: @pipeline_base ref
int condition: @ast ref
)
while_statement_location(
@@ -892,9 +888,9 @@ while_statement_location(
// https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.language.foreachstatementast?view=powershellsdk-7.3.0
foreach_statement(
unique int id: @foreach_statement,
int variable: @variable_expression ref,
int condition: @pipeline_base ref,
int body: @statement_block ref,
int variable: @ast ref,
int condition: @ast ref,
int body: @ast ref,
int flags: int ref
)
@@ -907,7 +903,7 @@ foreach_statement_location(
// https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.language.forstatementast?view=powershellsdk-7.3.0
for_statement(
unique int id: @for_statement,
int body: @statement_block ref
int body: @ast ref
)
for_statement_location(
@@ -917,17 +913,17 @@ for_statement_location(
for_statement_condition(
int id: @for_statement ref,
int condition: @pipeline_base ref
int condition: @ast ref
)
for_statement_initializer(
int id: @for_statement ref,
int initializer: @pipeline_base ref
int initializer: @ast ref
)
for_statement_iterator(
int id: @for_statement ref,
int iterator: @pipeline_base ref
int iterator: @ast ref
)
// ExpandableStringExpressionAst
@@ -992,14 +988,14 @@ unary_expression_location(
// https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.language.catchclauseast?view=powershellsdk-7.3.0
catch_clause(
unique int id: @catch_clause,
int body: @statement_block ref,
int body: @ast ref,
boolean isCatchAll: boolean ref
)
catch_clause_catch_type(
int id: @catch_clause ref,
int index: int ref,
int catch_type: @type_constraint ref
int catch_type: @ast ref
)
catch_clause_location(
@@ -1028,7 +1024,7 @@ throw_statement_pipeline(
// https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.language.trystatementast?view=powershellsdk-7.3.0
try_statement(
unique int id: @try_statement,
int body: @statement_block ref
int body: @ast ref
)
try_statement_catch_clause(
@@ -1103,9 +1099,9 @@ token_location(
// https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.language.configurationdefinitionast?view=powershellsdk-7.3.0
configuration_definition(
unique int id: @configuration_definition,
int body: @script_block_expression ref,
int body: @ast ref,
int configurationType: int ref,
int name: @expression ref
int name: @ast ref
)
configuration_definition_location(
@@ -1117,7 +1113,7 @@ configuration_definition_location(
// https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.language.datastatementast?view=powershellsdk-7.3.0
data_statement(
unique int id: @data_statement,
int body: @statement_block ref
int body: @ast ref
)
data_statement_variable(

View File

@@ -0,0 +1,2 @@
description: Unknown changes
compatibility: partial

View File

@@ -1,4 +1,5 @@
private import AstImport
private import codeql.util.Boolean
private newtype TConstantValue =
TConstInteger(int value) {
@@ -12,15 +13,7 @@ private newtype TConstantValue =
)
} or
TConstString(string value) { exists(Raw::StringLiteral sl | sl.getValue() = value) } or
TConstBoolean(boolean value) {
exists(Raw::VarAccess va |
value = true and
va.getUserPath() = "true"
or
value = false and
va.getUserPath() = "false"
)
} or
TConstBoolean(Boolean b) or
TNull()
/** A constant value. */
@@ -61,9 +54,7 @@ class ConstInteger extends ConstantValue, TConstInteger {
final override string serialize() { result = this.getValue() }
final override ConstExpr getAnExpr() {
result.getValueString() = this.getValue()
}
final override ConstExpr getAnExpr() { result.getValueString() = this.getValue() }
}
/** A constant floating point value. */

View File

@@ -29,22 +29,26 @@ class MemberExpr extends Expr, TMemberExpr {
/** Gets the name of the member being looked up, if any. */
string getMemberName() {
result = getRawAst(this).(Raw::MemberExpr).getMember().(Raw::StringConstExpr).getValue().getValue()
result =
getRawAst(this).(Raw::MemberExpr).getMember().(Raw::StringConstExpr).getValue().getValue()
}
predicate isNullConditional() { getRawAst(this).(Raw::MemberExpr).isNullConditional() }
predicate isStatic() { getRawAst(this).(Raw::MemberExpr).isStatic() }
final override string toString() { result = this.getMemberName() }
final override string toString() {
result = this.getMemberName()
or
not exists(this.getMemberName()) and
result = "..."
}
predicate isExplicitWrite(Ast assignment) {
explicitAssignment(getRawAst(this), getRawAst(assignment))
}
predicate isImplicitWrite() {
implicitAssignment(getRawAst(this))
}
predicate isImplicitWrite() { implicitAssignment(getRawAst(this)) }
}
/** A `MemberExpr` that is being written to. */

View File

@@ -53,9 +53,15 @@ class Cmd extends @command, CmdBase {
Redirection getARedirection() { result = this.getRedirection(_) }
Expr getArgument(int i) {
/**
* Gets the `i`th argument to this command.
*
* This is either an expression, or a CmdParameter with no expression.
* The latter is only used to denote switch parameters.
*/
CmdElement getArgument(int i) {
result =
rank[i + 1](CmdElement e, Expr r, int j |
rank[i + 1](CmdElement e, CmdElement r, int j |
(
// For most commands the 0'th element is the command name ...
j > 0
@@ -71,7 +77,25 @@ class Cmd extends @command, CmdBase {
not e instanceof CmdParameter and
r = e
or
r = e.(CmdParameter).getExpr()
exists(CmdParameter p | e = p |
// If it has an expression, use that
p.getExpr() = r
or
// Otherwise, if it doesn't have an expression it's either
// because it's of the form (1) `-Name x`, (2) `-Name -SomethingElse`,
// or (3) `-Name` (with no other elements).
// In (1) we use `x` as the argument, and in (2) and (3) we use
// `-Name` as the argument.
not exists(p.getExpr()) and
(
this.getElement(j + 1) instanceof CmdParameter and
p = r
or
// Case 3
not exists(this.getElement(j + 1)) and
r = p
)
)
)
|
r order by j
@@ -80,16 +104,23 @@ class Cmd extends @command, CmdBase {
Expr getNamedArgument(string name) {
exists(CmdParameter p, int index |
result = this.getArgument(index) and
p.getName() = name
p = this.getElement(index) and
p.getName().toLowerCase() = name
|
p.getExpr() = result
result = p.getExpr()
or
exists(int jndex |
not exists(p.getExpr()) and
this.getElement(jndex) = p and
this.getElement(jndex + 1) = result
)
not exists(p.getExpr()) and
// `not result instanceof CmdParameter` is implied
result = this.getElement(index + 1)
)
}
CmdParameter getSwitchArgument(string name) {
not exists(this.getNamedArgument(name)) and
exists(int index |
result = this.getElement(index) and
result.getName().toLowerCase() = name and
not exists(result.getExpr())
)
}
}

View File

@@ -550,13 +550,18 @@ private module CmdExprRemoval {
private module CmdArguments {
private class CmdParameterRemoval extends Synthesis {
override predicate child(Raw::Ast parent, ChildIndex i, Child child) {
exists(Raw::Expr e |
this.rawChild(parent, i, e) and
child = childRef(getResultAst(e))
exists(Raw::CmdElement elem | this.rawChild(parent, i, elem) |
elem instanceof Raw::Expr and
child = childRef(getResultAst(elem))
or
// By construction of `Cmd::getArgument` this `CmdParameter` does not
// have an expression attached to it.
elem instanceof Raw::CmdParameter and
child = SynthChild(BoolLiteralKind(true))
)
}
private predicate rawChild(Raw::Cmd cmd, ChildIndex i, Raw::Expr child) {
private predicate rawChild(Raw::Cmd cmd, ChildIndex i, Raw::CmdElement child) {
exists(int index |
i = cmdArgument(index) and
child = cmd.getArgument(index)
@@ -564,19 +569,30 @@ private module CmdArguments {
}
override predicate isNamedArgument(CmdCall call, int i, string name) {
exists(Raw::Cmd cmd, Raw::Expr e, Raw::CmdParameter p |
this.rawChild(cmd, cmdArgument(i), e) and
exists(Raw::Cmd cmd, Raw::CmdElement elem |
call = getResultAst(cmd) and
p.getName().toLowerCase() = name
cmd.getArgument(i) = elem
|
p.getExpr() = e
or
exists(ChildIndex j, int jndex |
j = cmdElement_(jndex) and
not exists(p.getExpr()) and
cmd.getChild(toRawChildIndex(j)) = p and
cmd.getChild(toRawChildIndex(cmdElement_(jndex + 1))) = e
)
elem = cmd.getNamedArgument(name) or cmd.getSwitchArgument(name) = elem
)
}
final override predicate isRelevant(Raw::Ast a) {
a instanceof Raw::CmdParameter and
this.rawChild(_, _, a)
}
final override Expr getResultAstImpl(Raw::Ast r) {
exists(Raw::Cmd cmd, ChildIndex i |
this.rawChild(cmd, i, r) and
result = TBoolLiteral(cmd, i)
)
}
final override predicate booleanValue(BoolLiteral b, boolean value) {
exists(Raw::Ast parent, ChildIndex i |
b = TBoolLiteral(parent, i) and
this.child(parent, i, SynthChild(BoolLiteralKind(value)))
)
}
}

View File

@@ -5,6 +5,7 @@
*/
private import semmle.code.powershell.dataflow.DataFlow
import semmle.code.powershell.ApiGraphs
private import semmle.code.powershell.dataflow.flowsources.FlowSources
private import semmle.code.powershell.Cfg
@@ -20,7 +21,9 @@ module CommandInjection {
/**
* A data flow sink for command-injection vulnerabilities.
*/
abstract class Sink extends DataFlow::Node { }
abstract class Sink extends DataFlow::Node {
abstract string getSinkType();
}
/**
* A sanitizer for command-injection vulnerabilities.
@@ -39,13 +42,16 @@ module CommandInjection {
SystemCommandExecutionSink() {
// An argument to a call
exists(DataFlow::CallNode call |
call.getName() = "Invoke-Expression" and
call.getName() = ["Invoke-Expression", "iex"] and
call.getAnArgument() = this
)
or
// Or the call command itself in case it's a use of operator &.
any(DataFlow::CallOperatorNode call).getCommand() = this
}
override string getSinkType() {
result = "call to Invoke-Expression"
}
}
class AddTypeSink extends Sink {
@@ -55,11 +61,171 @@ module CommandInjection {
call.getAnArgument() = this
)
}
override string getSinkType() {
result = "call to Add-Type"
}
}
class InvokeScriptSink extends Sink {
InvokeScriptSink() {
exists(API::Node call |
API::getTopLevelMember("executioncontext").getMember("invokecommand").getMethod("invokescript") = call and
this = call.getArgument(_).asSink()
)
}
override string getSinkType(){
result = "call to InvokeScript"
}
}
class CreateNestedPipelineSink extends Sink {
CreateNestedPipelineSink() {
exists(API::Node call |
API::getTopLevelMember("host").getMember("runspace").getMethod("createnestedpipeline") = call and
this = call.getArgument(_).asSink()
)
}
override string getSinkType(){
result = "call to CreateNestedPipeline"
}
}
class AddScriptInvokeSink extends Sink {
AddScriptInvokeSink() {
exists(InvokeMemberExpr addscript, InvokeMemberExpr create |
this.asExpr().getExpr() = addscript.getAnArgument() and
addscript.getName() = "AddScript" and
create.getName() = "Create" and
addscript.getQualifier().(InvokeMemberExpr) = create and
create.getQualifier().(TypeNameExpr).getName() = "PowerShell"
)
}
override string getSinkType(){
result = "call to AddScript"
}
}
class PowershellSink extends Sink {
PowershellSink() {
exists( CmdCall c |
c.getName() = "powershell" |
(
this.asExpr().getExpr() = c.getArgument(1) and
c.getArgument(0).getValue().asString() = "-command"
) or
(
this.asExpr().getExpr() = c.getArgument(0)
)
)
}
override string getSinkType(){
result = "call to Powershell"
}
}
class CmdSink extends Sink {
CmdSink() {
exists(CmdCall c |
this.asExpr().getExpr() = c.getArgument(1) and
c.getName() = "cmd" and
c.getArgument(0).getValue().asString() = "/c"
)
}
override string getSinkType(){
result = "call to Cmd"
}
}
class ForEachObjectSink extends Sink {
ForEachObjectSink() {
exists(CmdCall c |
this.asExpr().getExpr() = c.getAnArgument() and
c.getName() = "Foreach-Object"
)
}
override string getSinkType(){
result = "call to ForEach-Object"
}
}
class InvokeSink extends Sink {
InvokeSink() {
exists(InvokeMemberExpr ie |
this.asExpr().getExpr() = ie.getCallee() or
this.asExpr().getExpr() = ie.getQualifier().getAChild*()
)
}
override string getSinkType(){
result = "call to Invoke"
}
}
class CreateScriptBlockSink extends Sink {
CreateScriptBlockSink() {
exists(InvokeMemberExpr ie |
this.asExpr().getExpr() = ie.getAnArgument() and
ie.getName() = "Create" and
ie.getQualifier().(TypeNameExpr).getName() = "ScriptBlock"
)
}
override string getSinkType(){
result = "call to CreateScriptBlock"
}
}
class NewScriptBlockSink extends Sink {
NewScriptBlockSink() {
exists(API::Node call |
API::getTopLevelMember("executioncontext").getMember("invokecommand").getMethod("newscriptblock") = call and
this = call.getArgument(_).asSink()
)
}
override string getSinkType(){
result = "call to NewScriptBlock"
}
}
class ExpandStringSink extends Sink {
ExpandStringSink() {
exists(API::Node call | this = call.getArgument(_).asSink() |
API::getTopLevelMember("executioncontext").getMember("invokecommand").getMethod("expandstring") = call or
API::getTopLevelMember("executioncontext").getMember("sessionstate").getMember("invokecommand").getMethod("expandstring") = call
)
}
override string getSinkType(){
result = "call to ExpandString"
}
}
private class ExternalCommandInjectionSink extends Sink {
ExternalCommandInjectionSink() {
this = ModelOutput::getASinkNode("command-injection").asSink()
}
override string getSinkType() {
result = "external command injection"
}
}
class TypedParameterSanitizer extends Sanitizer {
TypedParameterSanitizer() {
exists(Function f, Parameter p |
p = f.getAParameter() and
p.getStaticType() != "Object" and
this.asParameter() = p
)
}
}
class SingleQuoteSanitizer extends Sanitizer {
SingleQuoteSanitizer() {
exists(ExpandableStringExpr e, VarReadAccess v |
v = this.asExpr().getExpr() and
e.getUnexpandedValue().matches("%'$" + v.getVariable().getName() + "'%") and
e.getAnExpr() = v
)
}
}
}

View File

@@ -1,3 +0,0 @@
description: Remove psmodule file extraction
compatibility: full
is_in_psmodule_path.rel: delete

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Unknown changes
compatibility: partial

View File

@@ -8,6 +8,21 @@
routine that executes a command, allows the user to execute malicious
code.</p>
<p>The following are considered dangerous sinks: </p>
<ul>
<li>Invoke-Expression</li>
<li>InvokeScript</li>
<li>CreateNestedPipeline</li>
<li>AddScript</li>
<li>powershell</li>
<li>cmd</li>
<li>Foreach-Object</li>
<li>Invoke</li>
<li>CreateScriptBlock</li>
<li>NewScriptBlock</li>
<li>ExpandString</li>
</ul>
</overview>
<recommendation>
@@ -36,7 +51,10 @@ without examining it first.</p>
OWASP:
<a href="https://www.owasp.org/index.php/Command_Injection">Command Injection</a>.
</li>
<li>
Injection Hunter:
<a href="https://devblogs.microsoft.com/powershell/powershell-injection-hunter-security-auditing-for-powershell-scripts/">PowerShell Injection Hunter: Security Auditing for PowerShell Scripts</a>.
</li>
<!-- LocalWords: CWE untrusted unsanitized Runtime
-->

View File

@@ -0,0 +1,12 @@
positionalArguments
| arguments.ps1:1:5:1:5 | 1 | 0 |
namedArguments
| arguments.ps1:2:8:2:8 | 1 | x |
| arguments.ps1:3:8:3:8 | 1 | x |
| arguments.ps1:4:5:4:6 | true | x |
| arguments.ps1:6:5:6:6 | true | x |
| arguments.ps1:6:8:6:9 | true | y |
| arguments.ps1:7:8:7:8 | 1 | x |
| arguments.ps1:7:13:7:13 | 2 | y |
| arguments.ps1:8:8:8:8 | 1 | x |
| arguments.ps1:8:13:8:13 | 2 | y |

View File

@@ -0,0 +1,8 @@
Foo 1
Foo -x 1
Foo -x:1
Foo -x
Bar -x -y
Bar -x 1 -y 2
Bar -x:1 -y:2

View File

@@ -0,0 +1,5 @@
import powershell
query predicate positionalArguments(Argument a, int p) { p = a.getPosition() }
query predicate namedArguments(Argument a, string name) { name = a.getName() }

View File

@@ -0,0 +1,2 @@
param($x)
[DateTime]::$x

View File

@@ -5,6 +5,7 @@ cmdExpr
| BinaryExpression.ps1:4:1:4:7 | [Stmt] result | BinaryExpression.ps1:4:1:4:7 | result |
| ExpandableString.ps1:1:1:1:39 | [Stmt] Date: $([DateTime]::Now)\nName: $name | ExpandableString.ps1:1:1:1:39 | Date: $([DateTime]::Now)\nName: $name |
| ExpandableString.ps1:1:23:1:37 | [Stmt] Now | ExpandableString.ps1:1:23:1:37 | Now |
| MemberExpression.ps1:2:1:2:14 | [Stmt] ... | MemberExpression.ps1:2:1:2:14 | ... |
| SubExpression.ps1:1:1:1:23 | [Stmt] Call to AddDays | SubExpression.ps1:1:1:1:23 | Call to AddDays |
| SubExpression.ps1:1:3:1:10 | [Stmt] Call to Get-Date | SubExpression.ps1:1:3:1:10 | Call to Get-Date |
| SubExpression.ps1:2:1:2:21 | [Stmt] Call to AddDays | SubExpression.ps1:2:1:2:21 | Call to AddDays |
@@ -13,3 +14,6 @@ invokeMemoryExpression
| SubExpression.ps1:1:1:1:23 | Call to AddDays | SubExpression.ps1:1:1:1:11 | $(...) | 0 | SubExpression.ps1:1:21:1:22 | 10 |
expandableString
| ExpandableString.ps1:1:1:1:39 | Date: $([DateTime]::Now)\nName: $name | 1 | ExpandableString.ps1:1:21:1:38 | $(...) |
memberExpr
| ExpandableString.ps1:1:23:1:37 | Now | ExpandableString.ps1:1:23:1:32 | DateTime |
| MemberExpression.ps1:2:1:2:14 | ... | MemberExpression.ps1:2:1:2:10 | DateTime |

View File

@@ -1,19 +1,19 @@
import powershell
query predicate binaryExpr(BinaryExpr e, Expr e1, Expr e2) {
e1 = e.getLeft() and
e2 = e.getRight()
e1 = e.getLeft() and
e2 = e.getRight()
}
query predicate cmdExpr(ExprStmt exprStmt, Expr e) {
e = exprStmt.getExpr()
}
query predicate cmdExpr(ExprStmt exprStmt, Expr e) { e = exprStmt.getExpr() }
query predicate invokeMemoryExpression(InvokeMemberExpr invoke, Expr e, int i, Expr arg) {
e = invoke.getQualifier() and
arg = invoke.getArgument(i)
e = invoke.getQualifier() and
arg = invoke.getArgument(i)
}
query predicate expandableString(ExpandableStringExpr expandable, int i, Expr e) {
e = expandable.getExpr(i)
e = expandable.getExpr(i)
}
query predicate memberExpr(MemberExpr expr, Expr e) { e = expr.getQualifier() }

View File

@@ -1,3 +1,36 @@
| Arguments/arguments.ps1:1:1:1:3 | Foo | Arguments/arguments.ps1:1:1:1:5 | Call to Foo |
| Arguments/arguments.ps1:1:1:1:5 | Call to Foo | Arguments/arguments.ps1:1:1:1:5 | [Stmt] Call to Foo |
| Arguments/arguments.ps1:1:1:1:5 | [Stmt] Call to Foo | Arguments/arguments.ps1:1:1:8:13 | {...} |
| Arguments/arguments.ps1:1:1:8:13 | {...} | Arguments/arguments.ps1:1:1:8:13 | toplevel function for arguments.ps1 |
| Arguments/arguments.ps1:1:1:8:13 | {...} | Arguments/arguments.ps1:1:1:8:13 | {...} |
| Arguments/arguments.ps1:1:5:1:5 | 1 | Arguments/arguments.ps1:1:1:1:5 | Call to Foo |
| Arguments/arguments.ps1:2:1:2:3 | Foo | Arguments/arguments.ps1:2:1:2:8 | Call to Foo |
| Arguments/arguments.ps1:2:1:2:8 | Call to Foo | Arguments/arguments.ps1:2:1:2:8 | [Stmt] Call to Foo |
| Arguments/arguments.ps1:2:1:2:8 | [Stmt] Call to Foo | Arguments/arguments.ps1:1:1:8:13 | {...} |
| Arguments/arguments.ps1:2:8:2:8 | 1 | Arguments/arguments.ps1:2:1:2:8 | Call to Foo |
| Arguments/arguments.ps1:3:1:3:3 | Foo | Arguments/arguments.ps1:3:1:3:8 | Call to Foo |
| Arguments/arguments.ps1:3:1:3:8 | Call to Foo | Arguments/arguments.ps1:3:1:3:8 | [Stmt] Call to Foo |
| Arguments/arguments.ps1:3:1:3:8 | [Stmt] Call to Foo | Arguments/arguments.ps1:1:1:8:13 | {...} |
| Arguments/arguments.ps1:3:8:3:8 | 1 | Arguments/arguments.ps1:3:1:3:8 | Call to Foo |
| Arguments/arguments.ps1:4:1:4:3 | Foo | Arguments/arguments.ps1:4:1:4:6 | Call to Foo |
| Arguments/arguments.ps1:4:1:4:6 | Call to Foo | Arguments/arguments.ps1:4:1:4:6 | [Stmt] Call to Foo |
| Arguments/arguments.ps1:4:1:4:6 | [Stmt] Call to Foo | Arguments/arguments.ps1:1:1:8:13 | {...} |
| Arguments/arguments.ps1:4:5:4:6 | true | Arguments/arguments.ps1:4:1:4:6 | Call to Foo |
| Arguments/arguments.ps1:6:1:6:3 | Bar | Arguments/arguments.ps1:6:1:6:9 | Call to Bar |
| Arguments/arguments.ps1:6:1:6:9 | Call to Bar | Arguments/arguments.ps1:6:1:6:9 | [Stmt] Call to Bar |
| Arguments/arguments.ps1:6:1:6:9 | [Stmt] Call to Bar | Arguments/arguments.ps1:1:1:8:13 | {...} |
| Arguments/arguments.ps1:6:5:6:6 | true | Arguments/arguments.ps1:6:1:6:9 | Call to Bar |
| Arguments/arguments.ps1:6:8:6:9 | true | Arguments/arguments.ps1:6:1:6:9 | Call to Bar |
| Arguments/arguments.ps1:7:1:7:3 | Bar | Arguments/arguments.ps1:7:1:7:13 | Call to Bar |
| Arguments/arguments.ps1:7:1:7:13 | Call to Bar | Arguments/arguments.ps1:7:1:7:13 | [Stmt] Call to Bar |
| Arguments/arguments.ps1:7:1:7:13 | [Stmt] Call to Bar | Arguments/arguments.ps1:1:1:8:13 | {...} |
| Arguments/arguments.ps1:7:8:7:8 | 1 | Arguments/arguments.ps1:7:1:7:13 | Call to Bar |
| Arguments/arguments.ps1:7:13:7:13 | 2 | Arguments/arguments.ps1:7:1:7:13 | Call to Bar |
| Arguments/arguments.ps1:8:1:8:3 | Bar | Arguments/arguments.ps1:8:1:8:13 | Call to Bar |
| Arguments/arguments.ps1:8:1:8:13 | Call to Bar | Arguments/arguments.ps1:8:1:8:13 | [Stmt] Call to Bar |
| Arguments/arguments.ps1:8:1:8:13 | [Stmt] Call to Bar | Arguments/arguments.ps1:1:1:8:13 | {...} |
| Arguments/arguments.ps1:8:8:8:8 | 1 | Arguments/arguments.ps1:8:1:8:13 | Call to Bar |
| Arguments/arguments.ps1:8:13:8:13 | 2 | Arguments/arguments.ps1:8:1:8:13 | Call to Bar |
| Arrays/Arrays.ps1:0:0:0:-1 | {...} | Arrays/Arrays.ps1:14:41:14:43 | @(...) |
| Arrays/Arrays.ps1:1:1:1:7 | array1 | Arrays/Arrays.ps1:1:1:1:36 | ...=... |
| Arrays/Arrays.ps1:1:1:1:7 | array1 | Arrays/Arrays.ps1:1:1:15:14 | {...} |
@@ -189,6 +222,8 @@
| Expressions/ConvertWithSecureString.ps1:2:19:2:40 | ConvertTo-SecureString | Expressions/ConvertWithSecureString.ps1:2:19:2:79 | Call to ConvertTo-SecureString |
| Expressions/ConvertWithSecureString.ps1:2:19:2:79 | Call to ConvertTo-SecureString | Expressions/ConvertWithSecureString.ps1:2:1:2:79 | ...=... |
| Expressions/ConvertWithSecureString.ps1:2:50:2:59 | UserInput | Expressions/ConvertWithSecureString.ps1:2:19:2:79 | Call to ConvertTo-SecureString |
| Expressions/ConvertWithSecureString.ps1:2:61:2:72 | true | Expressions/ConvertWithSecureString.ps1:2:19:2:79 | Call to ConvertTo-SecureString |
| Expressions/ConvertWithSecureString.ps1:2:74:2:79 | true | Expressions/ConvertWithSecureString.ps1:2:19:2:79 | Call to ConvertTo-SecureString |
| Expressions/ExpandableString.ps1:1:1:1:39 | Date: $([DateTime]::Now)\nName: $name | Expressions/ExpandableString.ps1:1:1:1:39 | [Stmt] Date: $([DateTime]::Now)\nName: $name |
| Expressions/ExpandableString.ps1:1:1:1:39 | [Stmt] Date: $([DateTime]::Now)\nName: $name | Expressions/ExpandableString.ps1:1:1:1:39 | {...} |
| Expressions/ExpandableString.ps1:1:1:1:39 | {...} | Expressions/ExpandableString.ps1:1:1:1:39 | toplevel function for ExpandableString.ps1 |
@@ -199,6 +234,14 @@
| Expressions/ExpandableString.ps1:1:23:1:37 | [Stmt] Now | Expressions/ExpandableString.ps1:1:23:1:37 | {...} |
| Expressions/ExpandableString.ps1:1:23:1:37 | {...} | Expressions/ExpandableString.ps1:1:21:1:38 | $(...) |
| Expressions/ExpandableString.ps1:1:35:1:37 | Now | Expressions/ExpandableString.ps1:1:23:1:37 | Now |
| Expressions/MemberExpression.ps1:1:1:2:14 | [synth] pipeline | Expressions/MemberExpression.ps1:1:1:2:14 | {...} |
| Expressions/MemberExpression.ps1:1:1:2:14 | {...} | Expressions/MemberExpression.ps1:1:1:2:14 | toplevel function for MemberExpression.ps1 |
| Expressions/MemberExpression.ps1:1:1:2:14 | {...} | Expressions/MemberExpression.ps1:1:1:2:14 | {...} |
| Expressions/MemberExpression.ps1:1:7:1:8 | x | Expressions/MemberExpression.ps1:1:1:2:14 | {...} |
| Expressions/MemberExpression.ps1:2:1:2:10 | DateTime | Expressions/MemberExpression.ps1:2:1:2:14 | ... |
| Expressions/MemberExpression.ps1:2:1:2:14 | ... | Expressions/MemberExpression.ps1:2:1:2:14 | [Stmt] ... |
| Expressions/MemberExpression.ps1:2:1:2:14 | [Stmt] ... | Expressions/MemberExpression.ps1:1:1:2:14 | {...} |
| Expressions/MemberExpression.ps1:2:13:2:14 | x | Expressions/MemberExpression.ps1:2:1:2:14 | ... |
| Expressions/SubExpression.ps1:1:1:1:11 | $(...) | Expressions/SubExpression.ps1:1:1:1:23 | Call to AddDays |
| Expressions/SubExpression.ps1:1:1:1:23 | Call to AddDays | Expressions/SubExpression.ps1:1:1:1:23 | [Stmt] Call to AddDays |
| Expressions/SubExpression.ps1:1:1:1:23 | [Stmt] Call to AddDays | Expressions/SubExpression.ps1:1:1:2:21 | {...} |

View File

@@ -1,12 +1,137 @@
edges
| test.ps1:1:8:1:9 | x | test.ps1:3:28:3:47 | Get-Process -Id $x | provenance | |
| test.ps1:5:10:5:20 | my_var | test.ps1:7:3:7:19 | $code --enabled | provenance | |
| test.ps1:3:11:3:20 | UserInput | test.ps1:4:23:4:52 | Get-Process -Name $UserInput | provenance | |
| test.ps1:9:11:9:20 | UserInput | test.ps1:10:9:10:38 | Get-Process -Name $UserInput | provenance | |
| test.ps1:15:11:15:20 | UserInput | test.ps1:16:50:16:79 | Get-Process -Name $UserInput | provenance | |
| test.ps1:21:11:21:20 | UserInput | test.ps1:22:41:22:70 | Get-Process -Name $UserInput | provenance | |
| test.ps1:21:11:21:20 | UserInput | test.ps1:22:60:22:69 | UserInput | provenance | |
| test.ps1:27:11:27:20 | UserInput | test.ps1:28:38:28:67 | Get-Process -Name $UserInput | provenance | |
| test.ps1:27:11:27:20 | UserInput | test.ps1:28:57:28:66 | UserInput | provenance | |
| test.ps1:33:11:33:20 | UserInput | test.ps1:34:14:34:46 | public class Foo { $UserInput } | provenance | |
| test.ps1:39:11:39:20 | UserInput | test.ps1:40:30:40:62 | public class Foo { $UserInput } | provenance | |
| test.ps1:45:11:45:20 | UserInput | test.ps1:48:30:48:34 | code | provenance | |
| test.ps1:73:11:73:20 | UserInput | test.ps1:75:25:75:54 | Get-Process -Name $UserInput | provenance | |
| test.ps1:80:11:80:20 | UserInput | test.ps1:82:16:82:45 | Get-Process -Name $UserInput | provenance | |
| test.ps1:87:11:87:20 | UserInput | test.ps1:89:12:89:28 | ping $UserInput | provenance | |
| test.ps1:94:11:94:20 | UserInput | test.ps1:98:33:98:62 | Get-Process -Name $UserInput | provenance | |
| test.ps1:104:11:104:20 | UserInput | test.ps1:108:58:108:87 | Get-Process -Name $UserInput | provenance | |
| test.ps1:114:11:114:20 | UserInput | test.ps1:116:34:116:43 | UserInput | provenance | |
| test.ps1:121:11:121:20 | UserInput | test.ps1:123:28:123:37 | UserInput | provenance | |
| test.ps1:128:11:128:20 | UserInput | test.ps1:130:28:130:37 | UserInput | provenance | |
| test.ps1:136:11:136:20 | UserInput | test.ps1:139:50:139:59 | UserInput | provenance | |
| test.ps1:144:11:144:20 | UserInput | test.ps1:147:63:147:72 | UserInput | provenance | |
| test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:154:46:154:51 | input | provenance | Src:MaD:11464 |
| test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:155:46:155:51 | input | provenance | Src:MaD:11464 |
| test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:156:46:156:51 | input | provenance | Src:MaD:11464 |
| test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:157:46:157:51 | input | provenance | Src:MaD:11464 |
| test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:158:46:158:51 | input | provenance | Src:MaD:11464 |
| test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:159:46:159:51 | input | provenance | Src:MaD:11464 |
| test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:160:46:160:51 | input | provenance | Src:MaD:11464 |
| test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:161:46:161:51 | input | provenance | Src:MaD:11464 |
| test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:163:48:163:53 | input | provenance | Src:MaD:11464 |
| test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:164:48:164:53 | input | provenance | Src:MaD:11464 |
| test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:165:48:165:53 | input | provenance | Src:MaD:11464 |
| test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:166:41:166:46 | input | provenance | Src:MaD:11464 |
| test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:167:41:167:46 | input | provenance | Src:MaD:11464 |
| test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:168:36:168:41 | input | provenance | Src:MaD:11464 |
| test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:169:36:169:41 | input | provenance | Src:MaD:11464 |
| test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:170:36:170:41 | input | provenance | Src:MaD:11464 |
| test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:172:42:172:47 | input | provenance | Src:MaD:11464 |
| test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:173:42:173:47 | input | provenance | Src:MaD:11464 |
| test.ps1:154:46:154:51 | input | test.ps1:3:11:3:20 | UserInput | provenance | |
| test.ps1:155:46:155:51 | input | test.ps1:9:11:9:20 | UserInput | provenance | |
| test.ps1:156:46:156:51 | input | test.ps1:15:11:15:20 | UserInput | provenance | |
| test.ps1:157:46:157:51 | input | test.ps1:21:11:21:20 | UserInput | provenance | |
| test.ps1:158:46:158:51 | input | test.ps1:27:11:27:20 | UserInput | provenance | |
| test.ps1:159:46:159:51 | input | test.ps1:33:11:33:20 | UserInput | provenance | |
| test.ps1:160:46:160:51 | input | test.ps1:39:11:39:20 | UserInput | provenance | |
| test.ps1:161:46:161:51 | input | test.ps1:45:11:45:20 | UserInput | provenance | |
| test.ps1:163:48:163:53 | input | test.ps1:73:11:73:20 | UserInput | provenance | |
| test.ps1:164:48:164:53 | input | test.ps1:80:11:80:20 | UserInput | provenance | |
| test.ps1:165:48:165:53 | input | test.ps1:87:11:87:20 | UserInput | provenance | |
| test.ps1:166:41:166:46 | input | test.ps1:94:11:94:20 | UserInput | provenance | |
| test.ps1:167:41:167:46 | input | test.ps1:104:11:104:20 | UserInput | provenance | |
| test.ps1:168:36:168:41 | input | test.ps1:114:11:114:20 | UserInput | provenance | |
| test.ps1:169:36:169:41 | input | test.ps1:121:11:121:20 | UserInput | provenance | |
| test.ps1:170:36:170:41 | input | test.ps1:128:11:128:20 | UserInput | provenance | |
| test.ps1:172:42:172:47 | input | test.ps1:136:11:136:20 | UserInput | provenance | |
| test.ps1:173:42:173:47 | input | test.ps1:144:11:144:20 | UserInput | provenance | |
nodes
| test.ps1:1:8:1:9 | x | semmle.label | x |
| test.ps1:3:28:3:47 | Get-Process -Id $x | semmle.label | Get-Process -Id $x |
| test.ps1:5:10:5:20 | my_var | semmle.label | my_var |
| test.ps1:7:3:7:19 | $code --enabled | semmle.label | $code --enabled |
| test.ps1:3:11:3:20 | UserInput | semmle.label | UserInput |
| test.ps1:4:23:4:52 | Get-Process -Name $UserInput | semmle.label | Get-Process -Name $UserInput |
| test.ps1:9:11:9:20 | UserInput | semmle.label | UserInput |
| test.ps1:10:9:10:38 | Get-Process -Name $UserInput | semmle.label | Get-Process -Name $UserInput |
| test.ps1:15:11:15:20 | UserInput | semmle.label | UserInput |
| test.ps1:16:50:16:79 | Get-Process -Name $UserInput | semmle.label | Get-Process -Name $UserInput |
| test.ps1:21:11:21:20 | UserInput | semmle.label | UserInput |
| test.ps1:22:41:22:70 | Get-Process -Name $UserInput | semmle.label | Get-Process -Name $UserInput |
| test.ps1:22:60:22:69 | UserInput | semmle.label | UserInput |
| test.ps1:27:11:27:20 | UserInput | semmle.label | UserInput |
| test.ps1:28:38:28:67 | Get-Process -Name $UserInput | semmle.label | Get-Process -Name $UserInput |
| test.ps1:28:57:28:66 | UserInput | semmle.label | UserInput |
| test.ps1:33:11:33:20 | UserInput | semmle.label | UserInput |
| test.ps1:34:14:34:46 | public class Foo { $UserInput } | semmle.label | public class Foo { $UserInput } |
| test.ps1:39:11:39:20 | UserInput | semmle.label | UserInput |
| test.ps1:40:30:40:62 | public class Foo { $UserInput } | semmle.label | public class Foo { $UserInput } |
| test.ps1:45:11:45:20 | UserInput | semmle.label | UserInput |
| test.ps1:48:30:48:34 | code | semmle.label | code |
| test.ps1:73:11:73:20 | UserInput | semmle.label | UserInput |
| test.ps1:75:25:75:54 | Get-Process -Name $UserInput | semmle.label | Get-Process -Name $UserInput |
| test.ps1:80:11:80:20 | UserInput | semmle.label | UserInput |
| test.ps1:82:16:82:45 | Get-Process -Name $UserInput | semmle.label | Get-Process -Name $UserInput |
| test.ps1:87:11:87:20 | UserInput | semmle.label | UserInput |
| test.ps1:89:12:89:28 | ping $UserInput | semmle.label | ping $UserInput |
| test.ps1:94:11:94:20 | UserInput | semmle.label | UserInput |
| test.ps1:98:33:98:62 | Get-Process -Name $UserInput | semmle.label | Get-Process -Name $UserInput |
| test.ps1:104:11:104:20 | UserInput | semmle.label | UserInput |
| test.ps1:108:58:108:87 | Get-Process -Name $UserInput | semmle.label | Get-Process -Name $UserInput |
| test.ps1:114:11:114:20 | UserInput | semmle.label | UserInput |
| test.ps1:116:34:116:43 | UserInput | semmle.label | UserInput |
| test.ps1:121:11:121:20 | UserInput | semmle.label | UserInput |
| test.ps1:123:28:123:37 | UserInput | semmle.label | UserInput |
| test.ps1:128:11:128:20 | UserInput | semmle.label | UserInput |
| test.ps1:130:28:130:37 | UserInput | semmle.label | UserInput |
| test.ps1:136:11:136:20 | UserInput | semmle.label | UserInput |
| test.ps1:139:50:139:59 | UserInput | semmle.label | UserInput |
| test.ps1:144:11:144:20 | UserInput | semmle.label | UserInput |
| test.ps1:147:63:147:72 | UserInput | semmle.label | UserInput |
| test.ps1:152:10:152:32 | Call to Read-Host | semmle.label | Call to Read-Host |
| test.ps1:154:46:154:51 | input | semmle.label | input |
| test.ps1:155:46:155:51 | input | semmle.label | input |
| test.ps1:156:46:156:51 | input | semmle.label | input |
| test.ps1:157:46:157:51 | input | semmle.label | input |
| test.ps1:158:46:158:51 | input | semmle.label | input |
| test.ps1:159:46:159:51 | input | semmle.label | input |
| test.ps1:160:46:160:51 | input | semmle.label | input |
| test.ps1:161:46:161:51 | input | semmle.label | input |
| test.ps1:163:48:163:53 | input | semmle.label | input |
| test.ps1:164:48:164:53 | input | semmle.label | input |
| test.ps1:165:48:165:53 | input | semmle.label | input |
| test.ps1:166:41:166:46 | input | semmle.label | input |
| test.ps1:167:41:167:46 | input | semmle.label | input |
| test.ps1:168:36:168:41 | input | semmle.label | input |
| test.ps1:169:36:169:41 | input | semmle.label | input |
| test.ps1:170:36:170:41 | input | semmle.label | input |
| test.ps1:172:42:172:47 | input | semmle.label | input |
| test.ps1:173:42:173:47 | input | semmle.label | input |
subpaths
#select
| test.ps1:3:28:3:47 | Get-Process -Id $x | test.ps1:1:8:1:9 | x | test.ps1:3:28:3:47 | Get-Process -Id $x | This command depends on a $@. | test.ps1:1:8:1:9 | x | user-provided value |
| test.ps1:7:3:7:19 | $code --enabled | test.ps1:5:10:5:20 | my_var | test.ps1:7:3:7:19 | $code --enabled | This command depends on a $@. | test.ps1:5:10:5:20 | my_var | user-provided value |
| test.ps1:4:23:4:52 | Get-Process -Name $UserInput | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:4:23:4:52 | Get-Process -Name $UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:10:9:10:38 | Get-Process -Name $UserInput | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:10:9:10:38 | Get-Process -Name $UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:16:50:16:79 | Get-Process -Name $UserInput | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:16:50:16:79 | Get-Process -Name $UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:22:41:22:70 | Get-Process -Name $UserInput | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:22:41:22:70 | Get-Process -Name $UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:22:60:22:69 | UserInput | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:22:60:22:69 | UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:28:38:28:67 | Get-Process -Name $UserInput | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:28:38:28:67 | Get-Process -Name $UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:28:57:28:66 | UserInput | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:28:57:28:66 | UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:34:14:34:46 | public class Foo { $UserInput } | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:34:14:34:46 | public class Foo { $UserInput } | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:40:30:40:62 | public class Foo { $UserInput } | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:40:30:40:62 | public class Foo { $UserInput } | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:48:30:48:34 | code | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:48:30:48:34 | code | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:75:25:75:54 | Get-Process -Name $UserInput | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:75:25:75:54 | Get-Process -Name $UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:82:16:82:45 | Get-Process -Name $UserInput | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:82:16:82:45 | Get-Process -Name $UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:89:12:89:28 | ping $UserInput | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:89:12:89:28 | ping $UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:98:33:98:62 | Get-Process -Name $UserInput | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:98:33:98:62 | Get-Process -Name $UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:108:58:108:87 | Get-Process -Name $UserInput | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:108:58:108:87 | Get-Process -Name $UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:116:34:116:43 | UserInput | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:116:34:116:43 | UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:123:28:123:37 | UserInput | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:123:28:123:37 | UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:130:28:130:37 | UserInput | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:130:28:130:37 | UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:139:50:139:59 | UserInput | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:139:50:139:59 | UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |
| test.ps1:147:63:147:72 | UserInput | test.ps1:152:10:152:32 | Call to Read-Host | test.ps1:147:63:147:72 | UserInput | This command depends on a $@. | test.ps1:152:10:152:32 | Call to Read-Host | user-provided value |

View File

@@ -1,7 +1,210 @@
param ($x)
function Invoke-InvokeExpressionInjection1
{
param($UserInput)
Invoke-Expression "Get-Process -Name $UserInput"
}
Invoke-Expression -Command "Get-Process -Id $x" # BAD
function Invoke-InvokeExpressionInjection2
{
param($UserInput)
iex "Get-Process -Name $UserInput"
}
$code = "$Env:MY_VAR"
function Invoke-InvokeExpressionInjection3
{
param($UserInput)
$executionContext.InvokeCommand.InvokeScript("Get-Process -Name $UserInput")
}
& "$code --enabled" # BAD
function Invoke-InvokeExpressionInjection4
{
param($UserInput)
$host.Runspace.CreateNestedPipeline("Get-Process -Name $UserInput", $false).Invoke()
}
function Invoke-InvokeExpressionInjection5
{
param($UserInput)
[PowerShell]::Create().AddScript("Get-Process -Name $UserInput").Invoke()
}
function Invoke-InvokeExpressionInjection6
{
param($UserInput)
Add-Type "public class Foo { $UserInput }"
}
function Invoke-InvokeExpressionInjection7
{
param($UserInput)
Add-Type -TypeDefinition "public class Foo { $UserInput }"
}
function Invoke-InvokeExpressionInjection8
{
param($UserInput)
$code = "public class Foo { $UserInput }"
Add-Type -TypeDefinition $code
}
function Invoke-InvokeExpressionInjectionFP
{
param($UserInput)
$code = @"
public class BasicTest
{
public static int Add(int a, int b)
{
return (a + b);
}
public int Multiply(int a, int b)
{
return (a * b);
}
}
"@
Add-Type -TypeDefinition $code
}
function Invoke-ExploitableCommandInjection1
{
param($UserInput)
powershell -command "Get-Process -Name $UserInput"
}
function Invoke-ExploitableCommandInjection2
{
param($UserInput)
powershell "Get-Process -Name $UserInput"
}
function Invoke-ExploitableCommandInjection3
{
param($UserInput)
cmd /c "ping $UserInput"
}
function Invoke-ScriptBlockInjection1
{
param($UserInput)
## Often used when making remote connections
$sb = [ScriptBlock]::Create("Get-Process -Name $UserInput")
Invoke-Command RemoteServer $sb
}
function Invoke-ScriptBlockInjection2
{
param($UserInput)
## Often used when making remote connections
$sb = $executionContext.InvokeCommand.NewScriptBlock("Get-Process -Name $UserInput")
Invoke-Command RemoteServer $sb
}
function Invoke-MethodInjection1
{
param($UserInput)
Get-Process | Foreach-Object $UserInput
}
function Invoke-MethodInjection2
{
param($UserInput)
(Get-Process -Id $pid).$UserInput()
}
function Invoke-MethodInjection3
{
param($UserInput)
(Get-Process -Id $pid).$UserInput.Invoke()
}
#TODO: currently a FN
function Invoke-ExpandStringInjection1
{
param($UserInput)
## Used to attempt a variable resolution
$executionContext.InvokeCommand.ExpandString($UserInput)
}
function Invoke-ExpandStringInjection2
{
param($UserInput)
## Used to attempt a variable resolution
$executionContext.SessionState.InvokeCommand.ExpandString($UserInput)
}
$input = Read-Host "enter input"
Invoke-InvokeExpressionInjection1 -UserInput $input
Invoke-InvokeExpressionInjection2 -UserInput $input
Invoke-InvokeExpressionInjection3 -UserInput $input
Invoke-InvokeExpressionInjection4 -UserInput $input
Invoke-InvokeExpressionInjection5 -UserInput $input
Invoke-InvokeExpressionInjection6 -UserInput $input
Invoke-InvokeExpressionInjection7 -UserInput $input
Invoke-InvokeExpressionInjection8 -UserInput $input
Invoke-InvokeExpressionInjectionFP -UserInput $input
Invoke-ExploitableCommandInjection1 -UserInput $input
Invoke-ExploitableCommandInjection2 -UserInput $input
Invoke-ExploitableCommandInjection3 -UserInput $input
Invoke-ScriptBlockInjection1 -UserInput $input
Invoke-ScriptBlockInjection2 -UserInput $input
Invoke-MethodInjection1 -UserInput $input
Invoke-MethodInjection2 -UserInput $input
Invoke-MethodInjection3 -UserInput $input
Invoke-PropertyInjection -UserInput $input
Invoke-ExpandStringInjection1 -UserInput $input
Invoke-ExpandStringInjection2 -UserInput $input
#typed input
function Invoke-InvokeExpressionInjectionSafe1
{
param([int] $UserInput)
Invoke-Expression "Get-Process -Name $UserInput"
}
#single quotes to treat them as string literal
function Invoke-InvokeExpressionInjectionSafe2
{
param($UserInput)
Invoke-Expression "Get-Process -Name '$UserInput'"
}
#EscapeSingleQuotedStringContent API
function Invoke-InvokeExpressionInjectionSafe3
{
param([int] $UserInput)
$UserInputClean = [System.Management.Automation.Language.CodeGeneration]::
EscapeSingleQuotedStringContent("$UserInput")
Invoke-Expression "Get-Process -Name $UserInputClean"
}
#EscapeSingleQuotedStringContent API 2
function Invoke-InvokeExpressionInjectionSafe4
{
param([int] $UserInput)
$UserInputClean = [System.Management.Automation.Language.CodeGeneration]::EscapeSingleQuotedStringContent("$UserInput")
Invoke-Expression "Get-Process -Name $UserInputClean"
}
Invoke-InvokeExpressionInjectionSafe1 -UserInput $input
Invoke-InvokeExpressionInjectionSafe2 -UserInput $input
Invoke-InvokeExpressionInjectionSafe3 -UserInput $input
Invoke-InvokeExpressionInjectionSafe4 -UserInput $input

View File

@@ -95,7 +95,7 @@ final class DataFlowCall extends TDataFlowCall {
//** TODO JB1: Move to subclass, monkey patching for #153 */
DataFlowCallable getARuntimeTarget(){ none() }
Node::ArgumentNode getAnArgumentNode(){ none() }
ArgumentNode getAnArgumentNode(){ none() }
int totalorder(){ none() }
//** TODO JB1: end stubs for #153 */
}