Merge pull request #125 from microsoft/global-parameters

PS: Global parameter support
This commit is contained in:
Mathias Vorreiter Pedersen
2024-10-16 20:17:16 +01:00
committed by GitHub
8 changed files with 86 additions and 30 deletions

View File

@@ -69,6 +69,8 @@ abstract private class AbstractFunction extends Ast {
EntryBasicBlock getEntryBasicBlock() { result.getScope() = this.getBody() }
}
final class Function = AbstractFunction;
/**
* A function definition.
*/
@@ -114,4 +116,12 @@ class Constructor extends Method {
Constructor() { this.isConstructor() }
}
final class Function = FunctionBase;
class TopLevel extends AbstractFunction instanceof TopLevelScriptBlock {
final override string getName() { result = "toplevel" }
final override ScriptBlock getBody() { result = this }
final override Parameter getFunctionParameter(int i) { none() }
final override Type getDeclaringType() { none() }
}

View File

@@ -10,7 +10,7 @@ class ScriptBlock extends @script_block, Ast {
else result = "{...}"
}
override SourceLocation getLocation() { script_block_location(this, result) }
override Location getLocation() { script_block_location(this, result) }
int getNumUsings() { script_block(this, result, _, _, _, _) }
@@ -51,6 +51,42 @@ class ScriptBlock extends @script_block, Ast {
ModuleSpecification getAModuleSpecification() { result = this.getModuleSpecification(_) }
final override Scope getEnclosingScope() { result = this }
/**
* Gets the `i`'th paramter in this scope.
*
* This may be both function paramters and parameter block parameters.
*/
Parameter getParameter(int i) {
exists(Function func |
func.getBody() = this and
result = func.getParameter(i)
)
or
this.isTopLevel() and
result = this.getParamBlock().getParameter(i)
}
/**
* Gets a paramter in this scope.
*
* This may be both function parameters and parameter block parameters.
*/
Parameter getAParameter() { result = this.getParameter(_) }
Parameter getThisParameter() {
exists(Function func |
func.getBody() = this and
result = func.getThisParameter()
)
}
/** Gets the number of function parameters. */
final int getNumberOfParameters() { result = count(this.getAParameter()) }
final Parameter getParameterExcludingPiplines(int i) {
result = this.getParamBlock().getParameterExcludingPiplines(i)
}
}
/** A `process` block. */
@@ -69,3 +105,7 @@ class ProcessBlock extends NamedBlock {
result = scriptBlock.getEnclosingFunction().getAParameter()
}
}
class TopLevelScriptBlock extends ScriptBlock {
TopLevelScriptBlock() { this.isTopLevel() }
}

View File

@@ -14,33 +14,7 @@ Scope scopeOf(Ast n) {
* A variable scope. This is either a top-level (file), a module, a class,
* or a callable.
*/
class Scope extends Ast, @script_block {
class Scope extends Ast, ScriptBlock {
/** Gets the outer scope, if any. */
Scope getOuterScope() { result = scopeOf(this) }
/**
* Gets the `i`'th paramter in this scope.
*
* This may be both function paramters and parameter block parameters.
*/
Parameter getParameter(int i) {
exists(Function func |
func.getBody() = this and
result = func.getParameter(i)
)
}
/**
* Gets a paramter in this scope.
*
* This may be both function paramters and parameter block parameters.
*/
Parameter getAParameter() { result = this.getParameter(_) }
Parameter getThisParameter() {
exists(Function func |
func.getBody() = this and
result = func.getThisParameter()
)
}
}

View File

@@ -0,0 +1,12 @@
/**
* Provides classes for performing local (intra-procedural) and
* global (inter-procedural) taint-tracking analyses.
*/
module TaintTracking {
import semmle.code.powershell.dataflow.internal.TaintTrackingImpl::Public
private import semmle.code.powershell.dataflow.internal.DataFlowImplSpecific
private import semmle.code.powershell.dataflow.internal.TaintTrackingImplSpecific
private import codeql.dataflow.TaintTracking
private import powershell
import TaintFlowMake<Location, PowershellDataFlow, PowershellTaintTracking>
}

View File

@@ -0,0 +1,7 @@
import semmle.code.powershell.dataflow.internal.TaintTrackingPublic as Public
module Private {
import semmle.code.powershell.dataflow.DataFlow::DataFlow as DataFlow
import semmle.code.powershell.dataflow.internal.DataFlowImpl as DataFlowInternal
import semmle.code.powershell.dataflow.internal.TaintTrackingPrivate
}

View File

@@ -7,6 +7,8 @@ import semmle.code.powershell.dataflow.DataFlow
predicate defaultSource(DataFlow::Node src) {
src.asStmt().getStmt().(Cmd).getCommandName() = ["Source", "Taint"]
or
src.asParameter().getName().matches(["Source%", "Taint%"])
}
predicate defaultSink(DataFlow::Node sink) {
@@ -15,5 +17,9 @@ predicate defaultSink(DataFlow::Node sink) {
string getSourceArgString(DataFlow::Node src) {
defaultSource(src) and
src.asStmt().getStmt().(Cmd).getAnArgument().(StringConstExpr).getValue().getValue() = result
(
src.asStmt().getStmt().(Cmd).getAnArgument().(StringConstExpr).getValue().getValue() = result
or
src.asParameter().getName().regexpCapture(["Source(.+)", "Taint(.+)"], 1) = result
)
}

View File

@@ -0,0 +1,3 @@
param([string]$Source)
Sink $Source # $ hasValueFlow

View File

@@ -1,5 +1,6 @@
models
edges
| global.ps1:1:7:1:22 | Source | global.ps1:3:6:3:13 | Source | provenance | |
| test.ps1:1:14:1:16 | a | test.ps1:2:10:2:12 | a | provenance | |
| test.ps1:5:6:5:16 | Source | test.ps1:6:5:6:7 | x | provenance | |
| test.ps1:6:5:6:7 | x | test.ps1:1:14:1:16 | a | provenance | |
@@ -139,6 +140,8 @@ edges
| test.ps1:39:24:39:31 | second | test.ps1:8:24:8:26 | y | provenance | |
| test.ps1:39:32:39:38 | first | test.ps1:8:20:8:22 | x | provenance | |
nodes
| global.ps1:1:7:1:22 | Source | semmle.label | Source |
| global.ps1:3:6:3:13 | Source | semmle.label | Source |
| test.ps1:1:14:1:16 | a | semmle.label | a |
| test.ps1:2:10:2:12 | a | semmle.label | a |
| test.ps1:5:6:5:16 | Source | semmle.label | Source |
@@ -221,6 +224,7 @@ nodes
subpaths
testFailures
#select
| global.ps1:3:6:3:13 | Source | global.ps1:1:7:1:22 | Source | global.ps1:3:6:3:13 | Source | $@ | global.ps1:1:7:1:22 | Source | Source |
| test.ps1:2:10:2:12 | a | test.ps1:5:6:5:16 | Source | test.ps1:2:10:2:12 | a | $@ | test.ps1:5:6:5:16 | Source | Source |
| test.ps1:9:10:9:12 | x | test.ps1:14:10:14:20 | Source | test.ps1:9:10:9:12 | x | $@ | test.ps1:14:10:14:20 | Source | Source |
| test.ps1:10:10:10:12 | y | test.ps1:15:11:15:21 | Source | test.ps1:10:10:10:12 | y | $@ | test.ps1:15:11:15:21 | Source | Source |