diff --git a/ql/src/semmle/go/frameworks/Stdlib.qll b/ql/src/semmle/go/frameworks/Stdlib.qll index 3b1aa94969f..bd765449389 100644 --- a/ql/src/semmle/go/frameworks/Stdlib.qll +++ b/ql/src/semmle/go/frameworks/Stdlib.qll @@ -32,6 +32,7 @@ import semmle.go.frameworks.stdlib.HtmlTemplate import semmle.go.frameworks.stdlib.Net import semmle.go.frameworks.stdlib.NetHttp import semmle.go.frameworks.stdlib.NetHttpHttputil +import semmle.go.frameworks.stdlib.NetMail import semmle.go.frameworks.stdlib.Path import semmle.go.frameworks.stdlib.PathFilepath import semmle.go.frameworks.stdlib.Reflect diff --git a/ql/src/semmle/go/frameworks/stdlib/NetMail.qll b/ql/src/semmle/go/frameworks/stdlib/NetMail.qll new file mode 100644 index 00000000000..a036f296d10 --- /dev/null +++ b/ql/src/semmle/go/frameworks/stdlib/NetMail.qll @@ -0,0 +1,54 @@ +/** + * Provides classes modeling security-relevant aspects of the `net/mail` package. + */ + +import go + +/** Provides models of commonly used functions in the `net/mail` package. */ +module NetMail { + private class FunctionModels extends TaintTracking::FunctionModel { + FunctionInput inp; + FunctionOutput outp; + + FunctionModels() { + // signature: func ParseAddress(address string) (*Address, error) + hasQualifiedName("net/mail", "ParseAddress") and + (inp.isParameter(0) and outp.isResult(0)) + or + // signature: func ParseAddressList(list string) ([]*Address, error) + hasQualifiedName("net/mail", "ParseAddressList") and + (inp.isParameter(0) and outp.isResult(0)) + or + // signature: func ReadMessage(r io.Reader) (msg *Message, err error) + hasQualifiedName("net/mail", "ReadMessage") and + (inp.isParameter(0) and outp.isResult(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 (*AddressParser).Parse(address string) (*Address, error) + this.hasQualifiedName("net/mail", "AddressParser", "Parse") and + (inp.isParameter(0) and outp.isResult(0)) + or + // signature: func (*AddressParser).ParseList(list string) ([]*Address, error) + this.hasQualifiedName("net/mail", "AddressParser", "ParseList") and + (inp.isParameter(0) and outp.isResult(0)) + or + // signature: func (Header).Get(key string) string + this.hasQualifiedName("net/mail", "Header", "Get") and + (inp.isReceiver() and outp.isResult()) + } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + input = inp and output = outp + } + } +} diff --git a/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/NetMail.go b/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/NetMail.go new file mode 100644 index 00000000000..595f71dac75 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/NetMail.go @@ -0,0 +1,79 @@ +// Code generated by https://github.com/gagliardetto/codebox. DO NOT EDIT. + +package main + +import ( + "io" + "net/mail" +) + +func TaintStepTest_NetMailParseAddress_B0I0O0(sourceCQL interface{}) interface{} { + fromString656 := sourceCQL.(string) + intoAddress414, _ := mail.ParseAddress(fromString656) + return intoAddress414 +} + +func TaintStepTest_NetMailParseAddressList_B0I0O0(sourceCQL interface{}) interface{} { + fromString518 := sourceCQL.(string) + intoAddress650, _ := mail.ParseAddressList(fromString518) + return intoAddress650 +} + +func TaintStepTest_NetMailReadMessage_B0I0O0(sourceCQL interface{}) interface{} { + fromReader784 := sourceCQL.(io.Reader) + intoMessage957, _ := mail.ReadMessage(fromReader784) + return intoMessage957 +} + +func TaintStepTest_NetMailAddressParserParse_B0I0O0(sourceCQL interface{}) interface{} { + fromString520 := sourceCQL.(string) + var mediumObjCQL mail.AddressParser + intoAddress443, _ := mediumObjCQL.Parse(fromString520) + return intoAddress443 +} + +func TaintStepTest_NetMailAddressParserParseList_B0I0O0(sourceCQL interface{}) interface{} { + fromString127 := sourceCQL.(string) + var mediumObjCQL mail.AddressParser + intoAddress483, _ := mediumObjCQL.ParseList(fromString127) + return intoAddress483 +} + +func TaintStepTest_NetMailHeaderGet_B0I0O0(sourceCQL interface{}) interface{} { + fromHeader989 := sourceCQL.(mail.Header) + intoString982 := fromHeader989.Get("") + return intoString982 +} + +func RunAllTaints_NetMail() { + { + source := newSource(0) + out := TaintStepTest_NetMailParseAddress_B0I0O0(source) + sink(0, out) + } + { + source := newSource(1) + out := TaintStepTest_NetMailParseAddressList_B0I0O0(source) + sink(1, out) + } + { + source := newSource(2) + out := TaintStepTest_NetMailReadMessage_B0I0O0(source) + sink(2, out) + } + { + source := newSource(3) + out := TaintStepTest_NetMailAddressParserParse_B0I0O0(source) + sink(3, out) + } + { + source := newSource(4) + out := TaintStepTest_NetMailAddressParserParseList_B0I0O0(source) + sink(4, out) + } + { + source := newSource(5) + out := TaintStepTest_NetMailHeaderGet_B0I0O0(source) + sink(5, out) + } +}