Merge pull request #375 from owen-mc/spew

Model Spew logging framework
This commit is contained in:
Owen Mansel-Chan
2020-10-16 13:20:13 +01:00
committed by GitHub
9 changed files with 219 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* Added support for the Spew deep pretty-printing framework. This may cause the `go/clear-text-logging` query to return more results when sensitive data is exposed using this library.

View File

@@ -39,6 +39,7 @@ import semmle.go.frameworks.Macaron
import semmle.go.frameworks.Mux
import semmle.go.frameworks.NoSQL
import semmle.go.frameworks.Protobuf
import semmle.go.frameworks.Spew
import semmle.go.frameworks.SQL
import semmle.go.frameworks.Stdlib
import semmle.go.frameworks.SystemCommandExecutors

View File

@@ -0,0 +1,39 @@
/**
* Provides models of commonly used functions in the `github.com/davecgh/go-spew/spew` package.
*/
import go
/**
* Provides models of commonly used functions in the `github.com/davecgh/go-spew/spew` package.
*/
module Spew {
private string packagePath() { result = "github.com/davecgh/go-spew/spew" }
private class SpewCall extends LoggerCall::Range, DataFlow::CallNode {
int firstPrintedArg;
SpewCall() {
exists(string fn |
fn in ["Dump", "Errorf", "Print", "Printf", "Println"] and firstPrintedArg = 0
or
fn in ["Fdump", "Fprint", "Fprintf", "Fprintln"] and firstPrintedArg = 1
|
this.getTarget().hasQualifiedName(packagePath(), fn)
)
}
override DataFlow::Node getAMessageComponent() {
result = this.getArgument(any(int i | i >= firstPrintedArg))
}
}
/** The `Sprint` function or one of its variants. */
class Sprinter extends TaintTracking::FunctionModel {
Sprinter() { hasQualifiedName(packagePath(), ["Sdump", "Sprint", "Sprintln", "Sprintf"]) }
override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) {
inp.isParameter(_) and outp.isResult()
}
}
}

View File

@@ -0,0 +1,17 @@
| test.go:26:16:26:35 | call to getUntrustedString : string | test.go:33:14:33:23 | sUntrusted |
| test.go:26:16:26:35 | call to getUntrustedString : string | test.go:35:14:35:23 | sUntrusted |
| test.go:26:16:26:35 | call to getUntrustedString : string | test.go:41:18:41:27 | sUntrusted |
| test.go:26:16:26:35 | call to getUntrustedString : string | test.go:51:13:51:16 | str3 |
| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:30:12:30:21 | pUntrusted |
| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:31:13:31:22 | pUntrusted |
| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:32:15:32:24 | pUntrusted |
| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:34:17:34:26 | pUntrusted |
| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:36:17:36:26 | pUntrusted |
| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:38:16:38:25 | pUntrusted |
| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:39:17:39:26 | pUntrusted |
| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:40:19:40:28 | pUntrusted |
| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:42:21:42:30 | pUntrusted |
| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:45:13:45:16 | str1 |
| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:48:13:48:16 | str2 |
| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:54:13:54:16 | str4 |
| test.go:28:16:28:35 | call to getUntrustedStruct : Person | test.go:57:13:57:16 | str5 |

View File

@@ -0,0 +1,28 @@
import go
class UntrustedFunction extends Function {
UntrustedFunction() { this.getName() = ["getUntrustedString", "getUntrustedStruct"] }
}
class UntrustedSource extends DataFlow::Node, UntrustedFlowSource::Range {
UntrustedSource() { this = any(UntrustedFunction f).getACall() }
}
class SinkFunction extends Function {
SinkFunction() { this.getName() = "sinkString" }
}
class TestConfig extends TaintTracking::Configuration {
TestConfig() { this = "testconfig" }
override predicate isSource(DataFlow::Node source) { source instanceof UntrustedFlowSource }
override predicate isSink(DataFlow::Node sink) {
sink = any(SinkFunction f).getACall().getAnArgument() or
sink = any(LoggerCall log).getAMessageComponent()
}
}
from TaintTracking::Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select source, sink

View File

@@ -0,0 +1,8 @@
module codeql-go-tests/frameworks/Spew
go 1.14
require (
github.com/davecgh/go-spew v1.1.1
github.com/github/depstubber v0.0.0-20200916130315-f3217697abd4 // indirect
)

View File

@@ -0,0 +1,58 @@
package main
//go:generate depstubber -vendor github.com/davecgh/go-spew/spew "" Dump,Print,Println,Fdump,Fprint,Fprintln,Errorf,Fprintf,Printf,Sdump,Sprint,Sprintf,Sprintln
import (
"io"
"github.com/davecgh/go-spew/spew"
)
func main() {}
type Person struct {
Name string
Address string
}
func getUntrustedString() string { return "%v" }
func getUntrustedStruct() Person { return Person{} }
func sinkString(s string) {}
func testSpew(w io.Writer) {
s := "%v"
sUntrusted := getUntrustedString()
p := Person{}
pUntrusted := getUntrustedStruct()
spew.Dump(pUntrusted) // NOT OK
spew.Print(pUntrusted) // NOT OK
spew.Println(pUntrusted) // NOT OK
spew.Errorf(sUntrusted, p) // NOT OK
spew.Errorf(s, pUntrusted) // NOT OK
spew.Printf(sUntrusted, p) // NOT OK
spew.Printf(s, pUntrusted) // NOT OK
spew.Fdump(w, pUntrusted) // NOT OK
spew.Fprint(w, pUntrusted) // NOT OK
spew.Fprintln(w, pUntrusted) // NOT OK
spew.Fprintf(w, sUntrusted, p) // NOT OK
spew.Fprintf(w, s, pUntrusted) // NOT OK
str1 := spew.Sdump(pUntrusted)
sinkString(str1) // NOT OK
str2 := spew.Sprint(pUntrusted)
sinkString(str2) // NOT OK
str3 := spew.Sprintf(sUntrusted, p)
sinkString(str3) // NOT OK
str4 := spew.Sprintf(s, pUntrusted)
sinkString(str4) // NOT OK
str5 := spew.Sprintln(pUntrusted)
sinkString(str5) // NOT OK
}

View File

@@ -0,0 +1,60 @@
// Code generated by depstubber. DO NOT EDIT.
// This is a simple stub for github.com/davecgh/go-spew/spew, strictly for use in testing.
// See the LICENSE file for information about the licensing of the original library.
// Source: github.com/davecgh/go-spew/spew (exports: ; functions: Dump,Print,Println,Fdump,Fprint,Fprintln,Errorf,Fprintf,Printf,Sdump,Sprint,Sprintf,Sprintln)
// Package spew is a stub of github.com/davecgh/go-spew/spew, generated by depstubber.
package spew
import (
io "io"
)
func Dump(_ ...interface{}) {}
func Errorf(_ string, _ ...interface{}) error {
return nil
}
func Fdump(_ io.Writer, _ ...interface{}) {}
func Fprint(_ io.Writer, _ ...interface{}) (int, error) {
return 0, nil
}
func Fprintf(_ io.Writer, _ string, _ ...interface{}) (int, error) {
return 0, nil
}
func Fprintln(_ io.Writer, _ ...interface{}) (int, error) {
return 0, nil
}
func Print(_ ...interface{}) (int, error) {
return 0, nil
}
func Printf(_ string, _ ...interface{}) (int, error) {
return 0, nil
}
func Println(_ ...interface{}) (int, error) {
return 0, nil
}
func Sdump(_ ...interface{}) string {
return ""
}
func Sprint(_ ...interface{}) string {
return ""
}
func Sprintf(_ string, _ ...interface{}) string {
return ""
}
func Sprintln(_ ...interface{}) string {
return ""
}

View File

@@ -0,0 +1,6 @@
# github.com/davecgh/go-spew v1.1.1
## explicit
github.com/davecgh/go-spew
# github.com/github/depstubber v0.0.0-20200916130315-f3217697abd4
## explicit
github.com/github/depstubber