diff --git a/ql/src/semmle/go/frameworks/Stdlib.qll b/ql/src/semmle/go/frameworks/Stdlib.qll index a5cfabfa3a9..9fa8a6cf73e 100644 --- a/ql/src/semmle/go/frameworks/Stdlib.qll +++ b/ql/src/semmle/go/frameworks/Stdlib.qll @@ -13,6 +13,7 @@ import semmle.go.frameworks.stdlib.CompressGzip import semmle.go.frameworks.stdlib.CompressLzw import semmle.go.frameworks.stdlib.CompressZlib import semmle.go.frameworks.stdlib.Mime +import semmle.go.frameworks.stdlib.MimeMultipart import semmle.go.frameworks.stdlib.Path import semmle.go.frameworks.stdlib.PathFilepath diff --git a/ql/src/semmle/go/frameworks/stdlib/MimeMultipart.qll b/ql/src/semmle/go/frameworks/stdlib/MimeMultipart.qll new file mode 100644 index 00000000000..f3f9ad51683 --- /dev/null +++ b/ql/src/semmle/go/frameworks/stdlib/MimeMultipart.qll @@ -0,0 +1,74 @@ +/** + * Provides classes modeling security-relevant aspects of the `mime/multipart` package. + */ + +import go + +/** Provides models of commonly used functions in the `mime/multipart` package. */ +module MimeMultipart { + private class FunctionModels extends TaintTracking::FunctionModel { + FunctionInput inp; + FunctionOutput outp; + + FunctionModels() { + // signature: func NewReader(r io.Reader, boundary string) *Reader + hasQualifiedName("mime/multipart", "NewReader") and + (inp.isParameter(0) and outp.isResult()) + or + // signature: func NewWriter(w io.Writer) *Writer + hasQualifiedName("mime/multipart", "NewWriter") and + (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 (*FileHeader).Open() (File, error) + this.hasQualifiedName("mime/multipart", "FileHeader", "Open") and + (inp.isReceiver() and outp.isResult(0)) + or + // signature: func (*Part).Read(d []byte) (n int, err error) + this.hasQualifiedName("mime/multipart", "Part", "Read") and + (inp.isReceiver() and outp.isParameter(0)) + or + // signature: func (*Reader).NextPart() (*Part, error) + this.hasQualifiedName("mime/multipart", "Reader", "NextPart") and + (inp.isReceiver() and outp.isResult(0)) + or + // signature: func (*Reader).NextRawPart() (*Part, error) + this.hasQualifiedName("mime/multipart", "Reader", "NextRawPart") and + (inp.isReceiver() and outp.isResult(0)) + or + // signature: func (*Reader).ReadForm(maxMemory int64) (*Form, error) + this.hasQualifiedName("mime/multipart", "Reader", "ReadForm") and + (inp.isReceiver() and outp.isResult(0)) + or + // signature: func (*Writer).CreateFormField(fieldname string) (io.Writer, error) + this.hasQualifiedName("mime/multipart", "Writer", "CreateFormField") and + (inp.isResult(0) and outp.isReceiver()) + or + // signature: func (*Writer).CreateFormFile(fieldname string, filename string) (io.Writer, error) + this.hasQualifiedName("mime/multipart", "Writer", "CreateFormFile") and + (inp.isResult(0) and outp.isReceiver()) + or + // signature: func (*Writer).CreatePart(header net/textproto.MIMEHeader) (io.Writer, error) + this.hasQualifiedName("mime/multipart", "Writer", "CreatePart") and + (inp.isResult(0) and outp.isReceiver()) + or + // signature: func (*Writer).WriteField(fieldname string, value string) error + this.hasQualifiedName("mime/multipart", "Writer", "WriteField") and + (inp.isParameter(_) 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/MimeMultipart.go b/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/MimeMultipart.go new file mode 100644 index 00000000000..ffa6659638a --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/MimeMultipart.go @@ -0,0 +1,154 @@ +// Code generated by https://github.com/gagliardetto/codebox. DO NOT EDIT. + +package main + +import ( + "io" + "mime/multipart" +) + +func TaintStepTest_MimeMultipartNewReader_B0I0O0(sourceCQL interface{}) interface{} { + fromReader656 := sourceCQL.(io.Reader) + intoReader414 := multipart.NewReader(fromReader656, "") + return intoReader414 +} + +func TaintStepTest_MimeMultipartNewWriter_B0I0O0(sourceCQL interface{}) interface{} { + fromWriter518 := sourceCQL.(*multipart.Writer) + var intoWriter650 io.Writer + intermediateCQL := multipart.NewWriter(intoWriter650) + link(fromWriter518, intermediateCQL) + return intoWriter650 +} + +func TaintStepTest_MimeMultipartFileHeaderOpen_B0I0O0(sourceCQL interface{}) interface{} { + fromFileHeader784 := sourceCQL.(multipart.FileHeader) + intoFile957, _ := fromFileHeader784.Open() + return intoFile957 +} + +func TaintStepTest_MimeMultipartPartRead_B0I0O0(sourceCQL interface{}) interface{} { + fromPart520 := sourceCQL.(multipart.Part) + var intoByte443 []byte + fromPart520.Read(intoByte443) + return intoByte443 +} + +func TaintStepTest_MimeMultipartReaderNextPart_B0I0O0(sourceCQL interface{}) interface{} { + fromReader127 := sourceCQL.(multipart.Reader) + intoPart483, _ := fromReader127.NextPart() + return intoPart483 +} + +func TaintStepTest_MimeMultipartReaderNextRawPart_B0I0O0(sourceCQL interface{}) interface{} { + fromReader989 := sourceCQL.(multipart.Reader) + intoPart982, _ := fromReader989.NextRawPart() + return intoPart982 +} + +func TaintStepTest_MimeMultipartReaderReadForm_B0I0O0(sourceCQL interface{}) interface{} { + fromReader417 := sourceCQL.(multipart.Reader) + intoForm584, _ := fromReader417.ReadForm(0) + return intoForm584 +} + +func TaintStepTest_MimeMultipartWriterCreateFormField_B0I0O0(sourceCQL interface{}) interface{} { + fromWriter991 := sourceCQL.(io.Writer) + var intoWriter881 multipart.Writer + intermediateCQL, _ := intoWriter881.CreateFormField("") + link(fromWriter991, intermediateCQL) + return intoWriter881 +} + +func TaintStepTest_MimeMultipartWriterCreateFormFile_B0I0O0(sourceCQL interface{}) interface{} { + fromWriter186 := sourceCQL.(io.Writer) + var intoWriter284 multipart.Writer + intermediateCQL, _ := intoWriter284.CreateFormFile("", "") + link(fromWriter186, intermediateCQL) + return intoWriter284 +} + +func TaintStepTest_MimeMultipartWriterCreatePart_B0I0O0(sourceCQL interface{}) interface{} { + fromWriter908 := sourceCQL.(io.Writer) + var intoWriter137 multipart.Writer + intermediateCQL, _ := intoWriter137.CreatePart(nil) + link(fromWriter908, intermediateCQL) + return intoWriter137 +} + +func TaintStepTest_MimeMultipartWriterWriteField_B0I0O0(sourceCQL interface{}) interface{} { + fromString494 := sourceCQL.(string) + var intoWriter873 multipart.Writer + intoWriter873.WriteField(fromString494, "") + return intoWriter873 +} + +func TaintStepTest_MimeMultipartWriterWriteField_B0I1O0(sourceCQL interface{}) interface{} { + fromString599 := sourceCQL.(string) + var intoWriter409 multipart.Writer + intoWriter409.WriteField("", fromString599) + return intoWriter409 +} + +func RunAllTaints_MimeMultipart() { + { + source := newSource(0) + out := TaintStepTest_MimeMultipartNewReader_B0I0O0(source) + sink(0, out) + } + { + source := newSource(1) + out := TaintStepTest_MimeMultipartNewWriter_B0I0O0(source) + sink(1, out) + } + { + source := newSource(2) + out := TaintStepTest_MimeMultipartFileHeaderOpen_B0I0O0(source) + sink(2, out) + } + { + source := newSource(3) + out := TaintStepTest_MimeMultipartPartRead_B0I0O0(source) + sink(3, out) + } + { + source := newSource(4) + out := TaintStepTest_MimeMultipartReaderNextPart_B0I0O0(source) + sink(4, out) + } + { + source := newSource(5) + out := TaintStepTest_MimeMultipartReaderNextRawPart_B0I0O0(source) + sink(5, out) + } + { + source := newSource(6) + out := TaintStepTest_MimeMultipartReaderReadForm_B0I0O0(source) + sink(6, out) + } + { + source := newSource(7) + out := TaintStepTest_MimeMultipartWriterCreateFormField_B0I0O0(source) + sink(7, out) + } + { + source := newSource(8) + out := TaintStepTest_MimeMultipartWriterCreateFormFile_B0I0O0(source) + sink(8, out) + } + { + source := newSource(9) + out := TaintStepTest_MimeMultipartWriterCreatePart_B0I0O0(source) + sink(9, out) + } + { + source := newSource(10) + out := TaintStepTest_MimeMultipartWriterWriteField_B0I0O0(source) + sink(10, out) + } + { + source := newSource(11) + out := TaintStepTest_MimeMultipartWriterWriteField_B0I1O0(source) + sink(11, out) + } +}