From dd8e1243a2e180df9d06f24be09e96cf58628630 Mon Sep 17 00:00:00 2001 From: Slavomir Date: Tue, 4 Aug 2020 14:11:00 +0300 Subject: [PATCH] Add bufio taint-tracking --- ql/src/semmle/go/frameworks/Stdlib.qll | 12 +- ql/src/semmle/go/frameworks/stdlib/Bufio.qll | 145 ++++++++ .../go/frameworks/StdlibTaintFlow/Bufio.go | 345 ++++++++++++++++++ 3 files changed, 491 insertions(+), 11 deletions(-) create mode 100644 ql/src/semmle/go/frameworks/stdlib/Bufio.qll create mode 100644 ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Bufio.go diff --git a/ql/src/semmle/go/frameworks/Stdlib.qll b/ql/src/semmle/go/frameworks/Stdlib.qll index 44a24ff6771..db111b760c8 100644 --- a/ql/src/semmle/go/frameworks/Stdlib.qll +++ b/ql/src/semmle/go/frameworks/Stdlib.qll @@ -5,6 +5,7 @@ import go import semmle.go.frameworks.stdlib.ArchiveTar import semmle.go.frameworks.stdlib.ArchiveZip +import semmle.go.frameworks.stdlib.Bufio /** A `String()` method. */ class StringMethod extends TaintTracking::FunctionModel, Method { @@ -384,17 +385,6 @@ module Io { } } -/** Provides models of commonly used functions in the `bufio` package. */ -module Bufio { - private class NewWriter extends TaintTracking::FunctionModel { - NewWriter() { this.hasQualifiedName("bufio", "NewWriter") } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isResult() and output.isParameter(0) - } - } -} - /** Provides models of commonly used functions in the `io/ioutil` package. */ module IoUtil { private class IoUtilFileSystemAccess extends FileSystemAccess::Range, DataFlow::CallNode { diff --git a/ql/src/semmle/go/frameworks/stdlib/Bufio.qll b/ql/src/semmle/go/frameworks/stdlib/Bufio.qll new file mode 100644 index 00000000000..f025be68065 --- /dev/null +++ b/ql/src/semmle/go/frameworks/stdlib/Bufio.qll @@ -0,0 +1,145 @@ +/** + * Provides classes modeling security-relevant aspects of the `bufio` package. + */ + +import go + +/** Provides models of commonly used functions in the `bufio` package. */ +module Bufio { + private class FunctionModels extends TaintTracking::FunctionModel { + FunctionInput inp; + FunctionOutput outp; + + FunctionModels() { + // signature: func NewReadWriter(r *Reader, w *Writer) *ReadWriter + hasQualifiedName("bufio", "NewReadWriter") and + (inp.isParameter(0) and outp.isResult()) + or + inp.isResult() and outp.isParameter(1) + or + // signature: func NewReader(rd io.Reader) *Reader + hasQualifiedName("bufio", "NewReader") and + (inp.isParameter(0) and outp.isResult()) + or + // signature: func NewReaderSize(rd io.Reader, size int) *Reader + hasQualifiedName("bufio", "NewReaderSize") and + (inp.isParameter(0) and outp.isResult()) + or + // signature: func NewScanner(r io.Reader) *Scanner + hasQualifiedName("bufio", "NewScanner") and + (inp.isParameter(0) and outp.isResult()) + or + // signature: func NewWriter(w io.Writer) *Writer + hasQualifiedName("bufio", "NewWriter") and + (inp.isResult() and outp.isParameter(0)) + or + // signature: func NewWriterSize(w io.Writer, size int) *Writer + hasQualifiedName("bufio", "NewWriterSize") and + (inp.isResult() and outp.isParameter(0)) + or + // signature: func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) + hasQualifiedName("bufio", "ScanBytes") and + (inp.isParameter(0) and outp.isResult(1)) + or + // signature: func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) + hasQualifiedName("bufio", "ScanLines") and + (inp.isParameter(0) and outp.isResult(1)) + or + // signature: func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) + hasQualifiedName("bufio", "ScanRunes") and + (inp.isParameter(0) and outp.isResult(1)) + or + // signature: func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) + hasQualifiedName("bufio", "ScanWords") and + (inp.isParameter(0) and outp.isResult(1)) + } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + input = inp and output = outp + } + } + + private class MethodModels extends TaintTracking::FunctionModel, Method { + FunctionInput inp; + FunctionOutput outp; + + MethodModels() { + // Methods: + // signature: func (*Reader).Peek(n int) ([]byte, error) + this.(Method).hasQualifiedName("bufio", "Reader", "Peek") and + (inp.isReceiver() and outp.isResult(0)) + or + // signature: func (*Reader).Read(p []byte) (n int, err error) + this.(Method).hasQualifiedName("bufio", "Reader", "Read") and + (inp.isReceiver() and outp.isParameter(0)) + or + // signature: func (*Reader).ReadByte() (byte, error) + this.(Method).hasQualifiedName("bufio", "Reader", "ReadByte") and + (inp.isReceiver() and outp.isResult(0)) + or + // signature: func (*Reader).ReadBytes(delim byte) ([]byte, error) + this.(Method).hasQualifiedName("bufio", "Reader", "ReadBytes") and + (inp.isReceiver() and outp.isResult(0)) + or + // signature: func (*Reader).ReadLine() (line []byte, isPrefix bool, err error) + this.(Method).hasQualifiedName("bufio", "Reader", "ReadLine") and + (inp.isReceiver() and outp.isResult(0)) + or + // signature: func (*Reader).ReadRune() (r rune, size int, err error) + this.(Method).hasQualifiedName("bufio", "Reader", "ReadRune") and + (inp.isReceiver() and outp.isResult(0)) + or + // signature: func (*Reader).ReadSlice(delim byte) (line []byte, err error) + this.(Method).hasQualifiedName("bufio", "Reader", "ReadSlice") and + (inp.isReceiver() and outp.isResult(0)) + or + // signature: func (*Reader).ReadString(delim byte) (string, error) + this.(Method).hasQualifiedName("bufio", "Reader", "ReadString") and + (inp.isReceiver() and outp.isResult(0)) + or + // signature: func (*Reader).Reset(r io.Reader) + this.(Method).hasQualifiedName("bufio", "Reader", "Reset") and + (inp.isParameter(0) and outp.isReceiver()) + or + // signature: func (*Reader).WriteTo(w io.Writer) (n int64, err error) + this.(Method).hasQualifiedName("bufio", "Reader", "WriteTo") and + (inp.isReceiver() and outp.isParameter(0)) + or + // signature: func (*Scanner).Bytes() []byte + this.(Method).hasQualifiedName("bufio", "Scanner", "Bytes") and + (inp.isReceiver() and outp.isResult()) + or + // signature: func (*Scanner).Text() string + this.(Method).hasQualifiedName("bufio", "Scanner", "Text") and + (inp.isReceiver() and outp.isResult()) + or + // signature: func (*Writer).ReadFrom(r io.Reader) (n int64, err error) + this.(Method).hasQualifiedName("bufio", "Writer", "ReadFrom") and + (inp.isParameter(0) and outp.isReceiver()) + or + // signature: func (*Writer).Reset(w io.Writer) + this.(Method).hasQualifiedName("bufio", "Writer", "Reset") and + (inp.isReceiver() and outp.isParameter(0)) + or + // signature: func (*Writer).Write(p []byte) (nn int, err error) + this.(Method).hasQualifiedName("bufio", "Writer", "Write") and + (inp.isParameter(0) and outp.isReceiver()) + or + // signature: func (*Writer).WriteByte(c byte) error + this.(Method).hasQualifiedName("bufio", "Writer", "WriteByte") and + (inp.isParameter(0) and outp.isReceiver()) + or + // signature: func (*Writer).WriteRune(r rune) (size int, err error) + this.(Method).hasQualifiedName("bufio", "Writer", "WriteRune") and + (inp.isParameter(0) and outp.isReceiver()) + or + // signature: func (*Writer).WriteString(s string) (int, error) + this.(Method).hasQualifiedName("bufio", "Writer", "WriteString") 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/Bufio.go b/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Bufio.go new file mode 100644 index 00000000000..1b2bfd948c3 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Bufio.go @@ -0,0 +1,345 @@ +// Code generated by https://github.com/gagliardetto/codebox. DO NOT EDIT. + +package main + +import ( + "bufio" + "io" +) + +func TaintStepTest_BufioNewReadWriter_B0I0O0(sourceCQL interface{}) interface{} { + fromReader656 := sourceCQL.(*bufio.Reader) + intoReadWriter414 := bufio.NewReadWriter(fromReader656, nil) + return intoReadWriter414 +} + +func TaintStepTest_BufioNewReadWriter_B1I0O0(sourceCQL interface{}) interface{} { + fromReadWriter518 := sourceCQL.(*bufio.ReadWriter) + var intoWriter650 *bufio.Writer + intermediateCQL := bufio.NewReadWriter(nil, intoWriter650) + link(fromReadWriter518, intermediateCQL) + return intoWriter650 +} + +func TaintStepTest_BufioNewReader_B0I0O0(sourceCQL interface{}) interface{} { + fromReader784 := sourceCQL.(io.Reader) + intoReader957 := bufio.NewReader(fromReader784) + return intoReader957 +} + +func TaintStepTest_BufioNewReaderSize_B0I0O0(sourceCQL interface{}) interface{} { + fromReader520 := sourceCQL.(io.Reader) + intoReader443 := bufio.NewReaderSize(fromReader520, 0) + return intoReader443 +} + +func TaintStepTest_BufioNewScanner_B0I0O0(sourceCQL interface{}) interface{} { + fromReader127 := sourceCQL.(io.Reader) + intoScanner483 := bufio.NewScanner(fromReader127) + return intoScanner483 +} + +func TaintStepTest_BufioNewWriter_B0I0O0(sourceCQL interface{}) interface{} { + fromWriter989 := sourceCQL.(*bufio.Writer) + var intoWriter982 io.Writer + intermediateCQL := bufio.NewWriter(intoWriter982) + link(fromWriter989, intermediateCQL) + return intoWriter982 +} + +func TaintStepTest_BufioNewWriterSize_B0I0O0(sourceCQL interface{}) interface{} { + fromWriter417 := sourceCQL.(*bufio.Writer) + var intoWriter584 io.Writer + intermediateCQL := bufio.NewWriterSize(intoWriter584, 0) + link(fromWriter417, intermediateCQL) + return intoWriter584 +} + +func TaintStepTest_BufioScanBytes_B0I0O0(sourceCQL interface{}) interface{} { + fromByte991 := sourceCQL.([]byte) + _, intoByte881, _ := bufio.ScanBytes(fromByte991, false) + return intoByte881 +} + +func TaintStepTest_BufioScanLines_B0I0O0(sourceCQL interface{}) interface{} { + fromByte186 := sourceCQL.([]byte) + _, intoByte284, _ := bufio.ScanLines(fromByte186, false) + return intoByte284 +} + +func TaintStepTest_BufioScanRunes_B0I0O0(sourceCQL interface{}) interface{} { + fromByte908 := sourceCQL.([]byte) + _, intoByte137, _ := bufio.ScanRunes(fromByte908, false) + return intoByte137 +} + +func TaintStepTest_BufioScanWords_B0I0O0(sourceCQL interface{}) interface{} { + fromByte494 := sourceCQL.([]byte) + _, intoByte873, _ := bufio.ScanWords(fromByte494, false) + return intoByte873 +} + +func TaintStepTest_BufioReaderPeek_B0I0O0(sourceCQL interface{}) interface{} { + fromReader599 := sourceCQL.(bufio.Reader) + intoByte409, _ := fromReader599.Peek(0) + return intoByte409 +} + +func TaintStepTest_BufioReaderRead_B0I0O0(sourceCQL interface{}) interface{} { + fromReader246 := sourceCQL.(bufio.Reader) + var intoByte898 []byte + fromReader246.Read(intoByte898) + return intoByte898 +} + +func TaintStepTest_BufioReaderReadByte_B0I0O0(sourceCQL interface{}) interface{} { + fromReader598 := sourceCQL.(bufio.Reader) + intoByte631, _ := fromReader598.ReadByte() + return intoByte631 +} + +func TaintStepTest_BufioReaderReadBytes_B0I0O0(sourceCQL interface{}) interface{} { + fromReader165 := sourceCQL.(bufio.Reader) + intoByte150, _ := fromReader165.ReadBytes(0) + return intoByte150 +} + +func TaintStepTest_BufioReaderReadLine_B0I0O0(sourceCQL interface{}) interface{} { + fromReader340 := sourceCQL.(bufio.Reader) + intoByte471, _, _ := fromReader340.ReadLine() + return intoByte471 +} + +func TaintStepTest_BufioReaderReadRune_B0I0O0(sourceCQL interface{}) interface{} { + fromReader290 := sourceCQL.(bufio.Reader) + intoRune758, _, _ := fromReader290.ReadRune() + return intoRune758 +} + +func TaintStepTest_BufioReaderReadSlice_B0I0O0(sourceCQL interface{}) interface{} { + fromReader396 := sourceCQL.(bufio.Reader) + intoByte707, _ := fromReader396.ReadSlice(0) + return intoByte707 +} + +func TaintStepTest_BufioReaderReadString_B0I0O0(sourceCQL interface{}) interface{} { + fromReader912 := sourceCQL.(bufio.Reader) + intoString718, _ := fromReader912.ReadString(0) + return intoString718 +} + +func TaintStepTest_BufioReaderReset_B0I0O0(sourceCQL interface{}) interface{} { + fromReader972 := sourceCQL.(io.Reader) + var intoReader633 bufio.Reader + intoReader633.Reset(fromReader972) + return intoReader633 +} + +func TaintStepTest_BufioReaderWriteTo_B0I0O0(sourceCQL interface{}) interface{} { + fromReader316 := sourceCQL.(bufio.Reader) + var intoWriter145 io.Writer + fromReader316.WriteTo(intoWriter145) + return intoWriter145 +} + +func TaintStepTest_BufioScannerBytes_B0I0O0(sourceCQL interface{}) interface{} { + fromScanner817 := sourceCQL.(bufio.Scanner) + intoByte474 := fromScanner817.Bytes() + return intoByte474 +} + +func TaintStepTest_BufioScannerText_B0I0O0(sourceCQL interface{}) interface{} { + fromScanner832 := sourceCQL.(bufio.Scanner) + intoString378 := fromScanner832.Text() + return intoString378 +} + +func TaintStepTest_BufioWriterReadFrom_B0I0O0(sourceCQL interface{}) interface{} { + fromReader541 := sourceCQL.(io.Reader) + var intoWriter139 bufio.Writer + intoWriter139.ReadFrom(fromReader541) + return intoWriter139 +} + +func TaintStepTest_BufioWriterReset_B0I0O0(sourceCQL interface{}) interface{} { + fromWriter814 := sourceCQL.(bufio.Writer) + var intoWriter768 io.Writer + fromWriter814.Reset(intoWriter768) + return intoWriter768 +} + +func TaintStepTest_BufioWriterWrite_B0I0O0(sourceCQL interface{}) interface{} { + fromByte468 := sourceCQL.([]byte) + var intoWriter736 bufio.Writer + intoWriter736.Write(fromByte468) + return intoWriter736 +} + +func TaintStepTest_BufioWriterWriteByte_B0I0O0(sourceCQL interface{}) interface{} { + fromByte516 := sourceCQL.(byte) + var intoWriter246 bufio.Writer + intoWriter246.WriteByte(fromByte516) + return intoWriter246 +} + +func TaintStepTest_BufioWriterWriteRune_B0I0O0(sourceCQL interface{}) interface{} { + fromRune679 := sourceCQL.(rune) + var intoWriter736 bufio.Writer + intoWriter736.WriteRune(fromRune679) + return intoWriter736 +} + +func TaintStepTest_BufioWriterWriteString_B0I0O0(sourceCQL interface{}) interface{} { + fromString839 := sourceCQL.(string) + var intoWriter273 bufio.Writer + intoWriter273.WriteString(fromString839) + return intoWriter273 +} + +func RunAllTaints_Bufio() { + { + source := newSource(0) + out := TaintStepTest_BufioNewReadWriter_B0I0O0(source) + sink(0, out) + } + { + source := newSource(1) + out := TaintStepTest_BufioNewReadWriter_B1I0O0(source) + sink(1, out) + } + { + source := newSource(2) + out := TaintStepTest_BufioNewReader_B0I0O0(source) + sink(2, out) + } + { + source := newSource(3) + out := TaintStepTest_BufioNewReaderSize_B0I0O0(source) + sink(3, out) + } + { + source := newSource(4) + out := TaintStepTest_BufioNewScanner_B0I0O0(source) + sink(4, out) + } + { + source := newSource(5) + out := TaintStepTest_BufioNewWriter_B0I0O0(source) + sink(5, out) + } + { + source := newSource(6) + out := TaintStepTest_BufioNewWriterSize_B0I0O0(source) + sink(6, out) + } + { + source := newSource(7) + out := TaintStepTest_BufioScanBytes_B0I0O0(source) + sink(7, out) + } + { + source := newSource(8) + out := TaintStepTest_BufioScanLines_B0I0O0(source) + sink(8, out) + } + { + source := newSource(9) + out := TaintStepTest_BufioScanRunes_B0I0O0(source) + sink(9, out) + } + { + source := newSource(10) + out := TaintStepTest_BufioScanWords_B0I0O0(source) + sink(10, out) + } + { + source := newSource(11) + out := TaintStepTest_BufioReaderPeek_B0I0O0(source) + sink(11, out) + } + { + source := newSource(12) + out := TaintStepTest_BufioReaderRead_B0I0O0(source) + sink(12, out) + } + { + source := newSource(13) + out := TaintStepTest_BufioReaderReadByte_B0I0O0(source) + sink(13, out) + } + { + source := newSource(14) + out := TaintStepTest_BufioReaderReadBytes_B0I0O0(source) + sink(14, out) + } + { + source := newSource(15) + out := TaintStepTest_BufioReaderReadLine_B0I0O0(source) + sink(15, out) + } + { + source := newSource(16) + out := TaintStepTest_BufioReaderReadRune_B0I0O0(source) + sink(16, out) + } + { + source := newSource(17) + out := TaintStepTest_BufioReaderReadSlice_B0I0O0(source) + sink(17, out) + } + { + source := newSource(18) + out := TaintStepTest_BufioReaderReadString_B0I0O0(source) + sink(18, out) + } + { + source := newSource(19) + out := TaintStepTest_BufioReaderReset_B0I0O0(source) + sink(19, out) + } + { + source := newSource(20) + out := TaintStepTest_BufioReaderWriteTo_B0I0O0(source) + sink(20, out) + } + { + source := newSource(21) + out := TaintStepTest_BufioScannerBytes_B0I0O0(source) + sink(21, out) + } + { + source := newSource(22) + out := TaintStepTest_BufioScannerText_B0I0O0(source) + sink(22, out) + } + { + source := newSource(23) + out := TaintStepTest_BufioWriterReadFrom_B0I0O0(source) + sink(23, out) + } + { + source := newSource(24) + out := TaintStepTest_BufioWriterReset_B0I0O0(source) + sink(24, out) + } + { + source := newSource(25) + out := TaintStepTest_BufioWriterWrite_B0I0O0(source) + sink(25, out) + } + { + source := newSource(26) + out := TaintStepTest_BufioWriterWriteByte_B0I0O0(source) + sink(26, out) + } + { + source := newSource(27) + out := TaintStepTest_BufioWriterWriteRune_B0I0O0(source) + sink(27, out) + } + { + source := newSource(28) + out := TaintStepTest_BufioWriterWriteString_B0I0O0(source) + sink(28, out) + } +}