Declassify fmt.Fprintf as a log sink

In future we could try harder to find out whether you're Fprintf'ing to stdout, a file named xyz.log etc, but for now this causes Fprintf'ing to an HTTP writer to be mistaken for log-injection rather than just XSS.
This commit is contained in:
Chris Smowton
2021-12-17 17:07:58 +00:00
parent da8f8e2eef
commit 92d3da5e56
2 changed files with 9 additions and 17 deletions

View File

@@ -29,19 +29,11 @@ module Fmt {
Printer() { this.hasQualifiedName("fmt", ["Print", "Printf", "Println"]) }
}
/** A call to `Print`, `Fprint`, or similar. */
/** A call to `Print` or similar. */
private class PrintCall extends LoggerCall::Range, DataFlow::CallNode {
int firstPrintedArg;
PrintCall() { this.getTarget() instanceof Printer }
PrintCall() {
this.getTarget() instanceof Printer and firstPrintedArg = 0
or
this.getTarget() instanceof Fprinter and firstPrintedArg = 1
}
override DataFlow::Node getAMessageComponent() {
result = this.getArgument(any(int i | i >= firstPrintedArg))
}
override DataFlow::Node getAMessageComponent() { result = this.getAnArgument() }
}
/** The `Fprint` function or one of its variants. */

View File

@@ -32,12 +32,12 @@ func handler(req *http.Request, ctx *goproxy.ProxyCtx) {
testFlag := req.URL.Query()["testFlag"][0]
{
fmt.Print(username) // $ hasTaintFlow="username"
fmt.Printf(username) // $ hasTaintFlow="username"
fmt.Println(username) // $ hasTaintFlow="username"
fmt.Fprint(nil, username) // $ hasTaintFlow="username"
fmt.Fprintf(nil, username) // $ hasTaintFlow="username"
fmt.Fprintln(nil, username) // $ hasTaintFlow="username"
fmt.Print(username) // $ hasTaintFlow="username"
fmt.Printf(username) // $ hasTaintFlow="username"
fmt.Println(username) // $ hasTaintFlow="username"
fmt.Fprint(nil, username) // Fprint functions are only loggers if they target stdout/stderr
fmt.Fprintf(nil, username)
fmt.Fprintln(nil, username)
}
// log
{