Skip to content

Commit

Permalink
Check replacer will replace \r or \n
Browse files Browse the repository at this point in the history
Implementation copied from string break.
  • Loading branch information
owen-mc committed Jan 17, 2023
1 parent b8417e0 commit 6282385
Showing 1 changed file with 48 additions and 7 deletions.
55 changes: 48 additions & 7 deletions go/ql/lib/semmle/go/security/LogInjectionCustomizations.qll
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,52 @@ module LogInjection {
}
}

/**
* A call to `strings.NewReplacer`.
*/
class StringsNewReplacerCall extends DataFlow::CallNode {
StringsNewReplacerCall() { this.getTarget().hasQualifiedName("strings", "NewReplacer") }

/**
* Gets an argument to this call corresponding to a string that will be
* replaced.
*/
DataFlow::Node getAReplacedArgument() { exists(int n | n % 2 = 0 and result = getArgument(n)) }
}

/**
* A configuration for tracking flow from a call to `strings.NewReplacer` to
* the receiver of a call to `strings.Replacer.Replace` or
* `strings.Replacer.WriteString`.
*/
class StringsNewReplacerConfiguration extends DataFlow2::Configuration {
StringsNewReplacerConfiguration() { this = "StringsNewReplacerConfiguration" }

override predicate isSource(DataFlow::Node source) { source instanceof StringsNewReplacerCall }

override predicate isSink(DataFlow::Node sink) {
exists(DataFlow::MethodCallNode call |
sink = call.getReceiver() and
call.getTarget().hasQualifiedName("strings", "Replacer", ["Replace", "WriteString"])
)
}
}

/**
* A call to `strings.Replacer.Replace`, considered as a sanitizer for log
* injection.
*/
class ReplacerReplaceSanitizer extends Sanitizer {
ReplacerReplaceSanitizer() {
exists(DataFlow::MethodCallNode call |
call.(DataFlow::MethodCallNode)
.getTarget()
.hasQualifiedName("strings", "Replacer", "Replace") and
this = call.getResult()
exists(
StringsNewReplacerConfiguration config, DataFlow::Node source, DataFlow::Node sink,
DataFlow::MethodCallNode call
|
config.hasFlow(source, sink) and
call.getTarget().hasQualifiedName("strings", "Replacer", "Replace") and
sink = call.getReceiver() and
this = call.getResult() and
source.(StringsNewReplacerCall).getAReplacedArgument().getStringValue() = ["\r", "\n"]
)
}
}
Expand All @@ -80,9 +115,15 @@ module LogInjection {
*/
class ReplacerWriteStringSanitizer extends Sanitizer {
ReplacerWriteStringSanitizer() {
exists(DataFlow::MethodCallNode call |
exists(
StringsNewReplacerConfiguration config, DataFlow::Node source, DataFlow::Node sink,
DataFlow::MethodCallNode call
|
config.hasFlow(source, sink) and
call.getTarget().hasQualifiedName("strings", "Replacer", "WriteString") and
this = call.getArgument(1)
sink = call.getReceiver() and
this = call.getArgument(1) and
source.(StringsNewReplacerCall).getAReplacedArgument().getStringValue() = ["\r", "\n"]
)
}
}
Expand Down

0 comments on commit 6282385

Please sign in to comment.