From 3acb7a5311d9db643c3beddc95ae867732ac9c04 Mon Sep 17 00:00:00 2001 From: Slavomir Date: Mon, 21 Sep 2020 12:46:58 +0200 Subject: [PATCH] Add taint-tracking for `crypto/tls` package --- ql/src/semmle/go/frameworks/Stdlib.qll | 1 + .../semmle/go/frameworks/stdlib/CryptoTls.qll | 58 ++++++++++++ .../frameworks/StdlibTaintFlow/CryptoTls.go | 94 +++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 ql/src/semmle/go/frameworks/stdlib/CryptoTls.qll create mode 100644 ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/CryptoTls.go diff --git a/ql/src/semmle/go/frameworks/Stdlib.qll b/ql/src/semmle/go/frameworks/Stdlib.qll index a952b141b74..0ad0aa198b7 100644 --- a/ql/src/semmle/go/frameworks/Stdlib.qll +++ b/ql/src/semmle/go/frameworks/Stdlib.qll @@ -16,6 +16,7 @@ import semmle.go.frameworks.stdlib.Fmt import semmle.go.frameworks.stdlib.Crypto import semmle.go.frameworks.stdlib.CryptoCipher import semmle.go.frameworks.stdlib.CryptoRsa +import semmle.go.frameworks.stdlib.CryptoTls import semmle.go.frameworks.stdlib.Mime import semmle.go.frameworks.stdlib.MimeMultipart import semmle.go.frameworks.stdlib.MimeQuotedprintable diff --git a/ql/src/semmle/go/frameworks/stdlib/CryptoTls.qll b/ql/src/semmle/go/frameworks/stdlib/CryptoTls.qll new file mode 100644 index 00000000000..0041c4cab3a --- /dev/null +++ b/ql/src/semmle/go/frameworks/stdlib/CryptoTls.qll @@ -0,0 +1,58 @@ +/** + * Provides classes modeling security-relevant aspects of the `crypto/tls` package. + */ + +import go + +/** Provides models of commonly used functions in the `crypto/tls` package. */ +module CryptoTls { + private class FunctionModels extends TaintTracking::FunctionModel { + FunctionInput inp; + FunctionOutput outp; + + FunctionModels() { + // signature: func Client(conn net.Conn, config *Config) *Conn + hasQualifiedName("crypto/tls", "Client") and + ( + inp.isParameter(0) and outp.isResult() + or + inp.isResult() and outp.isParameter(0) + ) + or + // signature: func NewListener(inner net.Listener, config *Config) net.Listener + hasQualifiedName("crypto/tls", "NewListener") and + (inp.isParameter(0) and outp.isResult()) + or + // signature: func Server(conn net.Conn, config *Config) *Conn + hasQualifiedName("crypto/tls", "Server") and + ( + inp.isParameter(0) and outp.isResult() + or + inp.isResult() and outp.isParameter(0) + ) + } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + input = inp and output = outp + } + } + + private class MethodModels extends TaintTracking::FunctionModel, Method { + FunctionInput inp; + FunctionOutput outp; + + MethodModels() { + // signature: func (*Conn).Read(b []byte) (int, error) + this.hasQualifiedName("crypto/tls", "Conn", "Read") and + (inp.isReceiver() and outp.isParameter(0)) + or + // signature: func (*Conn).Write(b []byte) (int, error) + this.hasQualifiedName("crypto/tls", "Conn", "Write") and + (inp.isParameter(0) and outp.isReceiver()) + } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + input = inp and output = outp + } + } +} diff --git a/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/CryptoTls.go b/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/CryptoTls.go new file mode 100644 index 00000000000..a35f30a1a99 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/CryptoTls.go @@ -0,0 +1,94 @@ +// Code generated by https://github.com/gagliardetto/codebox. DO NOT EDIT. + +package main + +import ( + "crypto/tls" + "net" +) + +func TaintStepTest_CryptoTlsClient_B0I0O0(sourceCQL interface{}) interface{} { + fromConn656 := sourceCQL.(net.Conn) + intoConn414 := tls.Client(fromConn656, nil) + return intoConn414 +} + +func TaintStepTest_CryptoTlsClient_B1I0O0(sourceCQL interface{}) interface{} { + fromConn518 := sourceCQL.(*tls.Conn) + var intoConn650 net.Conn + intermediateCQL := tls.Client(intoConn650, nil) + link(fromConn518, intermediateCQL) + return intoConn650 +} + +func TaintStepTest_CryptoTlsNewListener_B0I0O0(sourceCQL interface{}) interface{} { + fromListener784 := sourceCQL.(net.Listener) + intoListener957 := tls.NewListener(fromListener784, nil) + return intoListener957 +} + +func TaintStepTest_CryptoTlsServer_B0I0O0(sourceCQL interface{}) interface{} { + fromConn520 := sourceCQL.(net.Conn) + intoConn443 := tls.Server(fromConn520, nil) + return intoConn443 +} + +func TaintStepTest_CryptoTlsServer_B1I0O0(sourceCQL interface{}) interface{} { + fromConn127 := sourceCQL.(*tls.Conn) + var intoConn483 net.Conn + intermediateCQL := tls.Server(intoConn483, nil) + link(fromConn127, intermediateCQL) + return intoConn483 +} + +func TaintStepTest_CryptoTlsConnRead_B0I0O0(sourceCQL interface{}) interface{} { + fromConn989 := sourceCQL.(tls.Conn) + var intoByte982 []byte + fromConn989.Read(intoByte982) + return intoByte982 +} + +func TaintStepTest_CryptoTlsConnWrite_B0I0O0(sourceCQL interface{}) interface{} { + fromByte417 := sourceCQL.([]byte) + var intoConn584 tls.Conn + intoConn584.Write(fromByte417) + return intoConn584 +} + +func RunAllTaints_CryptoTls() { + { + source := newSource(0) + out := TaintStepTest_CryptoTlsClient_B0I0O0(source) + sink(0, out) + } + { + source := newSource(1) + out := TaintStepTest_CryptoTlsClient_B1I0O0(source) + sink(1, out) + } + { + source := newSource(2) + out := TaintStepTest_CryptoTlsNewListener_B0I0O0(source) + sink(2, out) + } + { + source := newSource(3) + out := TaintStepTest_CryptoTlsServer_B0I0O0(source) + sink(3, out) + } + { + source := newSource(4) + out := TaintStepTest_CryptoTlsServer_B1I0O0(source) + sink(4, out) + } + { + source := newSource(5) + out := TaintStepTest_CryptoTlsConnRead_B0I0O0(source) + sink(5, out) + } + { + source := newSource(6) + out := TaintStepTest_CryptoTlsConnWrite_B0I0O0(source) + sink(6, out) + } +}