From 74fdfba85cff3905ce41ac298c83c165f8d6bab2 Mon Sep 17 00:00:00 2001 From: Slavomir Date: Sun, 6 Sep 2020 18:18:37 +0200 Subject: [PATCH] Add taint-tracking for `encoding/hex` --- ql/src/semmle/go/frameworks/Stdlib.qll | 1 + .../go/frameworks/stdlib/EncodingHex.qll | 51 +++++++++ .../frameworks/StdlibTaintFlow/EncodingHex.go | 105 ++++++++++++++++++ 3 files changed, 157 insertions(+) create mode 100644 ql/src/semmle/go/frameworks/stdlib/EncodingHex.qll create mode 100644 ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/EncodingHex.go diff --git a/ql/src/semmle/go/frameworks/Stdlib.qll b/ql/src/semmle/go/frameworks/Stdlib.qll index 16856ceab6d..942e5fe1da3 100644 --- a/ql/src/semmle/go/frameworks/Stdlib.qll +++ b/ql/src/semmle/go/frameworks/Stdlib.qll @@ -23,6 +23,7 @@ import semmle.go.frameworks.stdlib.EncodingBase64 import semmle.go.frameworks.stdlib.EncodingBinary import semmle.go.frameworks.stdlib.EncodingCsv import semmle.go.frameworks.stdlib.EncodingGob +import semmle.go.frameworks.stdlib.EncodingHex 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/EncodingHex.qll b/ql/src/semmle/go/frameworks/stdlib/EncodingHex.qll new file mode 100644 index 00000000000..17b9dc858b6 --- /dev/null +++ b/ql/src/semmle/go/frameworks/stdlib/EncodingHex.qll @@ -0,0 +1,51 @@ +/** + * Provides classes modeling security-relevant aspects of the `encoding/hex` package. + */ + +import go + +/** Provides models of commonly used functions in the `encoding/hex` package. */ +module EncodingHex { + private class FunctionModels extends TaintTracking::FunctionModel { + FunctionInput inp; + FunctionOutput outp; + + FunctionModels() { + // signature: func Decode(dst []byte, src []byte) (int, error) + hasQualifiedName("encoding/hex", "Decode") and + (inp.isParameter(1) and outp.isParameter(0)) + or + // signature: func DecodeString(s string) ([]byte, error) + hasQualifiedName("encoding/hex", "DecodeString") and + (inp.isParameter(0) and outp.isResult(0)) + or + // signature: func Dump(data []byte) string + hasQualifiedName("encoding/hex", "Dump") and + (inp.isParameter(0) and outp.isResult()) + or + // signature: func Dumper(w io.Writer) io.WriteCloser + hasQualifiedName("encoding/hex", "Dumper") and + (inp.isResult() and outp.isParameter(0)) + or + // signature: func Encode(dst []byte, src []byte) int + hasQualifiedName("encoding/hex", "Encode") and + (inp.isParameter(1) and outp.isParameter(0)) + or + // signature: func EncodeToString(src []byte) string + hasQualifiedName("encoding/hex", "EncodeToString") and + (inp.isParameter(0) and outp.isResult()) + or + // signature: func NewDecoder(r io.Reader) io.Reader + hasQualifiedName("encoding/hex", "NewDecoder") and + (inp.isParameter(0) and outp.isResult()) + or + // signature: func NewEncoder(w io.Writer) io.Writer + hasQualifiedName("encoding/hex", "NewEncoder") and + (inp.isResult() and outp.isParameter(0)) + } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + input = inp and output = outp + } + } +} diff --git a/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/EncodingHex.go b/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/EncodingHex.go new file mode 100644 index 00000000000..38c67ddacf4 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/EncodingHex.go @@ -0,0 +1,105 @@ +// Code generated by https://github.com/gagliardetto/codebox. DO NOT EDIT. + +package main + +import ( + "encoding/hex" + "io" +) + +func TaintStepTest_EncodingHexDecode_B0I0O0(sourceCQL interface{}) interface{} { + fromByte656 := sourceCQL.([]byte) + var intoByte414 []byte + hex.Decode(intoByte414, fromByte656) + return intoByte414 +} + +func TaintStepTest_EncodingHexDecodeString_B0I0O0(sourceCQL interface{}) interface{} { + fromString518 := sourceCQL.(string) + intoByte650, _ := hex.DecodeString(fromString518) + return intoByte650 +} + +func TaintStepTest_EncodingHexDump_B0I0O0(sourceCQL interface{}) interface{} { + fromByte784 := sourceCQL.([]byte) + intoString957 := hex.Dump(fromByte784) + return intoString957 +} + +func TaintStepTest_EncodingHexDumper_B0I0O0(sourceCQL interface{}) interface{} { + fromWriteCloser520 := sourceCQL.(io.WriteCloser) + var intoWriter443 io.Writer + intermediateCQL := hex.Dumper(intoWriter443) + link(fromWriteCloser520, intermediateCQL) + return intoWriter443 +} + +func TaintStepTest_EncodingHexEncode_B0I0O0(sourceCQL interface{}) interface{} { + fromByte127 := sourceCQL.([]byte) + var intoByte483 []byte + hex.Encode(intoByte483, fromByte127) + return intoByte483 +} + +func TaintStepTest_EncodingHexEncodeToString_B0I0O0(sourceCQL interface{}) interface{} { + fromByte989 := sourceCQL.([]byte) + intoString982 := hex.EncodeToString(fromByte989) + return intoString982 +} + +func TaintStepTest_EncodingHexNewDecoder_B0I0O0(sourceCQL interface{}) interface{} { + fromReader417 := sourceCQL.(io.Reader) + intoReader584 := hex.NewDecoder(fromReader417) + return intoReader584 +} + +func TaintStepTest_EncodingHexNewEncoder_B0I0O0(sourceCQL interface{}) interface{} { + fromWriter991 := sourceCQL.(io.Writer) + var intoWriter881 io.Writer + intermediateCQL := hex.NewEncoder(intoWriter881) + link(fromWriter991, intermediateCQL) + return intoWriter881 +} + +func RunAllTaints_EncodingHex() { + { + source := newSource(0) + out := TaintStepTest_EncodingHexDecode_B0I0O0(source) + sink(0, out) + } + { + source := newSource(1) + out := TaintStepTest_EncodingHexDecodeString_B0I0O0(source) + sink(1, out) + } + { + source := newSource(2) + out := TaintStepTest_EncodingHexDump_B0I0O0(source) + sink(2, out) + } + { + source := newSource(3) + out := TaintStepTest_EncodingHexDumper_B0I0O0(source) + sink(3, out) + } + { + source := newSource(4) + out := TaintStepTest_EncodingHexEncode_B0I0O0(source) + sink(4, out) + } + { + source := newSource(5) + out := TaintStepTest_EncodingHexEncodeToString_B0I0O0(source) + sink(5, out) + } + { + source := newSource(6) + out := TaintStepTest_EncodingHexNewDecoder_B0I0O0(source) + sink(6, out) + } + { + source := newSource(7) + out := TaintStepTest_EncodingHexNewEncoder_B0I0O0(source) + sink(7, out) + } +}