C#: Include CompositeFormat.Parse as Format like method.

This commit is contained in:
Michael Nebel
2025-04-10 14:19:19 +02:00
parent 3838a7b0d6
commit 133e8d4897
3 changed files with 29 additions and 17 deletions

View File

@@ -289,3 +289,31 @@ class FormatCall extends MethodCall {
result = this.getArgument(this.getFirstArgument() + index)
}
}
/**
* A method call to a method that parses a format string, for example a call
* to `string.Format()`.
*/
abstract private class FormatStringParseCallImpl extends MethodCall {
/**
* Gets the expression used as the format string.
*/
abstract Expr getFormatExpr();
}
final class FormatStringParseCall = FormatStringParseCallImpl;
private class OrdinaryFormatCall extends FormatStringParseCallImpl instanceof FormatCall {
override Expr getFormatExpr() { result = FormatCall.super.getFormatExpr() }
}
/**
* A method call to `System.Text.CompositeFormat.Parse`.
*/
class ParseFormatStringCall extends FormatStringParseCallImpl {
ParseFormatStringCall() {
this.getTarget() = any(SystemTextCompositeFormatClass x).getParseMethod()
}
override Expr getFormatExpr() { result = this.getArgument(0) }
}

View File

@@ -16,22 +16,6 @@ import semmle.code.csharp.frameworks.system.Text
import semmle.code.csharp.frameworks.Format
import FormatFlow::PathGraph
abstract class FormatStringParseCall extends MethodCall {
abstract Expr getFormatExpr();
}
class OrdinaryFormatCall extends FormatStringParseCall instanceof FormatCall {
override Expr getFormatExpr() { result = FormatCall.super.getFormatExpr() }
}
class ParseFormatStringCall extends FormatStringParseCall {
ParseFormatStringCall() {
this.getTarget() = any(SystemTextCompositeFormatClass x).getParseMethod()
}
override Expr getFormatExpr() { result = this.getArgument(0) }
}
module FormatInvalidConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node n) { n.asExpr() instanceof StringLiteral }

View File

@@ -20,7 +20,7 @@ module FormatStringConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource }
predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(FormatCall call | call.hasInsertions()).getFormatExpr()
sink.asExpr() = any(FormatStringParseCall call).getFormatExpr()
}
}