diff --git a/ql/src/Security/CWE-681/IncorrectIntegerConversion.ql b/ql/src/Security/CWE-681/IncorrectIntegerConversion.ql index 6a68c41501b..1be03e9ec93 100644 --- a/ql/src/Security/CWE-681/IncorrectIntegerConversion.ql +++ b/ql/src/Security/CWE-681/IncorrectIntegerConversion.ql @@ -101,7 +101,7 @@ class ConversionWithoutBoundsCheckConfig extends TaintTracking::Configuration { // If we are reading a variable, check if it is // `strconv.IntSize`, and use 0 if it is. exists(DataFlow::Node rawBitSize | rawBitSize = ip.getTargetBitSizeInput().getNode(c) | - if rawBitSize = any(StrConv::IntSize intSize).getARead() + if rawBitSize = any(Strconv::IntSize intSize).getARead() then apparentBitSize = 0 else apparentBitSize = rawBitSize.getIntValue() ) diff --git a/ql/src/semmle/go/frameworks/Stdlib.qll b/ql/src/semmle/go/frameworks/Stdlib.qll index 73e1bb0240e..1ca8f1eccc1 100644 --- a/ql/src/semmle/go/frameworks/Stdlib.qll +++ b/ql/src/semmle/go/frameworks/Stdlib.qll @@ -18,6 +18,8 @@ import semmle.go.frameworks.stdlib.MimeQuotedprintable import semmle.go.frameworks.stdlib.Path import semmle.go.frameworks.stdlib.PathFilepath import semmle.go.frameworks.stdlib.Reflect +import semmle.go.frameworks.stdlib.Strconv +import semmle.go.frameworks.stdlib.Strings import semmle.go.frameworks.stdlib.TextScanner import semmle.go.frameworks.stdlib.TextTabwriter import semmle.go.frameworks.stdlib.TextTemplate @@ -483,41 +485,6 @@ module IntegerParser { } } -/** - * Provides classes for some functions in the `strconv` package for - * converting strings to numbers. - */ -module StrConv { - /** The `Atoi` function. */ - class Atoi extends IntegerParser::Range { - Atoi() { this.hasQualifiedName("strconv", "Atoi") } - - override int getTargetBitSize() { result = 0 } - } - - /** The `ParseInt` function. */ - class ParseInt extends IntegerParser::Range { - ParseInt() { this.hasQualifiedName("strconv", "ParseInt") } - - override FunctionInput getTargetBitSizeInput() { result.isParameter(2) } - } - - /** The `ParseUint` function. */ - class ParseUint extends IntegerParser::Range { - ParseUint() { this.hasQualifiedName("strconv", "ParseUint") } - - override FunctionInput getTargetBitSizeInput() { result.isParameter(2) } - } - - /** - * The `IntSize` constant, that gives the size in bits of an `int` or - * `uint` value on the current architecture (32 or 64). - */ - class IntSize extends DeclaredConstant { - IntSize() { this.hasQualifiedName("strconv", "IntSize") } - } -} - /** Provides models of commonly used functions in the `strings` package. */ module Strings { /** The `Join` function. */ diff --git a/ql/src/semmle/go/frameworks/stdlib/Strconv.qll b/ql/src/semmle/go/frameworks/stdlib/Strconv.qll new file mode 100644 index 00000000000..73ae2a2acde --- /dev/null +++ b/ql/src/semmle/go/frameworks/stdlib/Strconv.qll @@ -0,0 +1,107 @@ +/** + * Provides classes modeling security-relevant aspects of the `strconv` package. + */ + +import go + +/** Provides models of commonly used functions in the `strconv` package. */ +module Strconv { + /** The `Atoi` function. */ + class Atoi extends IntegerParser::Range { + Atoi() { this.hasQualifiedName("strconv", "Atoi") } + + override int getTargetBitSize() { result = 0 } + } + + /** The `ParseInt` function. */ + class ParseInt extends IntegerParser::Range { + ParseInt() { this.hasQualifiedName("strconv", "ParseInt") } + + override FunctionInput getTargetBitSizeInput() { result.isParameter(2) } + } + + /** The `ParseUint` function. */ + class ParseUint extends IntegerParser::Range { + ParseUint() { this.hasQualifiedName("strconv", "ParseUint") } + + override FunctionInput getTargetBitSizeInput() { result.isParameter(2) } + } + + /** + * The `IntSize` constant, that gives the size in bits of an `int` or + * `uint` value on the current architecture (32 or 64). + */ + class IntSize extends DeclaredConstant { + IntSize() { this.hasQualifiedName("strconv", "IntSize") } + } + + private class FunctionModels extends TaintTracking::FunctionModel { + FunctionInput inp; + FunctionOutput outp; + + FunctionModels() { + // signature: func AppendQuote(dst []byte, s string) []byte + hasQualifiedName("strconv", "AppendQuote") and + ( + inp.isParameter(_) and outp.isResult() + or + inp.isParameter(1) and + (outp.isParameter(0) or outp.isResult()) + ) + or + // signature: func AppendQuoteToASCII(dst []byte, s string) []byte + hasQualifiedName("strconv", "AppendQuoteToASCII") and + ( + inp.isParameter(_) and outp.isResult() + or + inp.isParameter(1) and + (outp.isParameter(0) or outp.isResult()) + ) + or + // signature: func AppendQuoteToGraphic(dst []byte, s string) []byte + hasQualifiedName("strconv", "AppendQuoteToGraphic") and + ( + inp.isParameter(_) and outp.isResult() + or + inp.isParameter(1) and + (outp.isParameter(0) or outp.isResult()) + ) + or + // signature: func Quote(s string) string + hasQualifiedName("strconv", "Quote") and + (inp.isParameter(0) and outp.isResult()) + or + // signature: func QuoteRune(r rune) string + hasQualifiedName("strconv", "QuoteRune") and + (inp.isParameter(0) and outp.isResult()) + or + // signature: func QuoteRuneToASCII(r rune) string + hasQualifiedName("strconv", "QuoteRuneToASCII") and + (inp.isParameter(0) and outp.isResult()) + or + // signature: func QuoteRuneToGraphic(r rune) string + hasQualifiedName("strconv", "QuoteRuneToGraphic") and + (inp.isParameter(0) and outp.isResult()) + or + // signature: func QuoteToASCII(s string) string + hasQualifiedName("strconv", "QuoteToASCII") and + (inp.isParameter(0) and outp.isResult()) + or + // signature: func QuoteToGraphic(s string) string + hasQualifiedName("strconv", "QuoteToGraphic") and + (inp.isParameter(0) and outp.isResult()) + or + // signature: func Unquote(s string) (string, error) + hasQualifiedName("strconv", "Unquote") and + (inp.isParameter(0) and outp.isResult(0)) + or + // signature: func UnquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err error) + hasQualifiedName("strconv", "UnquoteChar") and + (inp.isParameter(0) and outp.isResult([0, 2])) + } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + input = inp and output = outp + } + } +} diff --git a/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Strconv.go b/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Strconv.go new file mode 100644 index 00000000000..51f2d7e4838 --- /dev/null +++ b/ql/test/library-tests/semmle/go/frameworks/StdlibTaintFlow/Strconv.go @@ -0,0 +1,242 @@ +// Code generated by https://github.com/gagliardetto/codebox. DO NOT EDIT. + +package main + +import "strconv" + +func TaintStepTest_StrconvAppendQuote_B0I0O0(sourceCQL interface{}) interface{} { + fromByte656 := sourceCQL.([]byte) + intoByte414 := strconv.AppendQuote(fromByte656, "") + return intoByte414 +} + +func TaintStepTest_StrconvAppendQuote_B0I1O0(sourceCQL interface{}) interface{} { + fromString518 := sourceCQL.(string) + intoByte650 := strconv.AppendQuote(nil, fromString518) + return intoByte650 +} + +func TaintStepTest_StrconvAppendQuote_B1I0O0(sourceCQL interface{}) interface{} { + fromString784 := sourceCQL.(string) + var intoByte957 []byte + strconv.AppendQuote(intoByte957, fromString784) + return intoByte957 +} + +func TaintStepTest_StrconvAppendQuote_B1I0O1(sourceCQL interface{}) interface{} { + fromString520 := sourceCQL.(string) + intoByte443 := strconv.AppendQuote(nil, fromString520) + return intoByte443 +} + +func TaintStepTest_StrconvAppendQuoteToASCII_B0I0O0(sourceCQL interface{}) interface{} { + fromByte127 := sourceCQL.([]byte) + intoByte483 := strconv.AppendQuoteToASCII(fromByte127, "") + return intoByte483 +} + +func TaintStepTest_StrconvAppendQuoteToASCII_B0I1O0(sourceCQL interface{}) interface{} { + fromString989 := sourceCQL.(string) + intoByte982 := strconv.AppendQuoteToASCII(nil, fromString989) + return intoByte982 +} + +func TaintStepTest_StrconvAppendQuoteToASCII_B1I0O0(sourceCQL interface{}) interface{} { + fromString417 := sourceCQL.(string) + var intoByte584 []byte + strconv.AppendQuoteToASCII(intoByte584, fromString417) + return intoByte584 +} + +func TaintStepTest_StrconvAppendQuoteToASCII_B1I0O1(sourceCQL interface{}) interface{} { + fromString991 := sourceCQL.(string) + intoByte881 := strconv.AppendQuoteToASCII(nil, fromString991) + return intoByte881 +} + +func TaintStepTest_StrconvAppendQuoteToGraphic_B0I0O0(sourceCQL interface{}) interface{} { + fromByte186 := sourceCQL.([]byte) + intoByte284 := strconv.AppendQuoteToGraphic(fromByte186, "") + return intoByte284 +} + +func TaintStepTest_StrconvAppendQuoteToGraphic_B0I1O0(sourceCQL interface{}) interface{} { + fromString908 := sourceCQL.(string) + intoByte137 := strconv.AppendQuoteToGraphic(nil, fromString908) + return intoByte137 +} + +func TaintStepTest_StrconvAppendQuoteToGraphic_B1I0O0(sourceCQL interface{}) interface{} { + fromString494 := sourceCQL.(string) + var intoByte873 []byte + strconv.AppendQuoteToGraphic(intoByte873, fromString494) + return intoByte873 +} + +func TaintStepTest_StrconvAppendQuoteToGraphic_B1I0O1(sourceCQL interface{}) interface{} { + fromString599 := sourceCQL.(string) + intoByte409 := strconv.AppendQuoteToGraphic(nil, fromString599) + return intoByte409 +} + +func TaintStepTest_StrconvQuote_B0I0O0(sourceCQL interface{}) interface{} { + fromString246 := sourceCQL.(string) + intoString898 := strconv.Quote(fromString246) + return intoString898 +} + +func TaintStepTest_StrconvQuoteRune_B0I0O0(sourceCQL interface{}) interface{} { + fromRune598 := sourceCQL.(rune) + intoString631 := strconv.QuoteRune(fromRune598) + return intoString631 +} + +func TaintStepTest_StrconvQuoteRuneToASCII_B0I0O0(sourceCQL interface{}) interface{} { + fromRune165 := sourceCQL.(rune) + intoString150 := strconv.QuoteRuneToASCII(fromRune165) + return intoString150 +} + +func TaintStepTest_StrconvQuoteRuneToGraphic_B0I0O0(sourceCQL interface{}) interface{} { + fromRune340 := sourceCQL.(rune) + intoString471 := strconv.QuoteRuneToGraphic(fromRune340) + return intoString471 +} + +func TaintStepTest_StrconvQuoteToASCII_B0I0O0(sourceCQL interface{}) interface{} { + fromString290 := sourceCQL.(string) + intoString758 := strconv.QuoteToASCII(fromString290) + return intoString758 +} + +func TaintStepTest_StrconvQuoteToGraphic_B0I0O0(sourceCQL interface{}) interface{} { + fromString396 := sourceCQL.(string) + intoString707 := strconv.QuoteToGraphic(fromString396) + return intoString707 +} + +func TaintStepTest_StrconvUnquote_B0I0O0(sourceCQL interface{}) interface{} { + fromString912 := sourceCQL.(string) + intoString718, _ := strconv.Unquote(fromString912) + return intoString718 +} + +func TaintStepTest_StrconvUnquoteChar_B0I0O0(sourceCQL interface{}) interface{} { + fromString972 := sourceCQL.(string) + intoRune633, _, _, _ := strconv.UnquoteChar(fromString972, 0) + return intoRune633 +} + +func TaintStepTest_StrconvUnquoteChar_B0I0O1(sourceCQL interface{}) interface{} { + fromString316 := sourceCQL.(string) + _, _, intoString145, _ := strconv.UnquoteChar(fromString316, 0) + return intoString145 +} + +func RunAllTaints_Strconv() { + { + source := newSource(0) + out := TaintStepTest_StrconvAppendQuote_B0I0O0(source) + sink(0, out) + } + { + source := newSource(1) + out := TaintStepTest_StrconvAppendQuote_B0I1O0(source) + sink(1, out) + } + { + source := newSource(2) + out := TaintStepTest_StrconvAppendQuote_B1I0O0(source) + sink(2, out) + } + { + source := newSource(3) + out := TaintStepTest_StrconvAppendQuote_B1I0O1(source) + sink(3, out) + } + { + source := newSource(4) + out := TaintStepTest_StrconvAppendQuoteToASCII_B0I0O0(source) + sink(4, out) + } + { + source := newSource(5) + out := TaintStepTest_StrconvAppendQuoteToASCII_B0I1O0(source) + sink(5, out) + } + { + source := newSource(6) + out := TaintStepTest_StrconvAppendQuoteToASCII_B1I0O0(source) + sink(6, out) + } + { + source := newSource(7) + out := TaintStepTest_StrconvAppendQuoteToASCII_B1I0O1(source) + sink(7, out) + } + { + source := newSource(8) + out := TaintStepTest_StrconvAppendQuoteToGraphic_B0I0O0(source) + sink(8, out) + } + { + source := newSource(9) + out := TaintStepTest_StrconvAppendQuoteToGraphic_B0I1O0(source) + sink(9, out) + } + { + source := newSource(10) + out := TaintStepTest_StrconvAppendQuoteToGraphic_B1I0O0(source) + sink(10, out) + } + { + source := newSource(11) + out := TaintStepTest_StrconvAppendQuoteToGraphic_B1I0O1(source) + sink(11, out) + } + { + source := newSource(12) + out := TaintStepTest_StrconvQuote_B0I0O0(source) + sink(12, out) + } + { + source := newSource(13) + out := TaintStepTest_StrconvQuoteRune_B0I0O0(source) + sink(13, out) + } + { + source := newSource(14) + out := TaintStepTest_StrconvQuoteRuneToASCII_B0I0O0(source) + sink(14, out) + } + { + source := newSource(15) + out := TaintStepTest_StrconvQuoteRuneToGraphic_B0I0O0(source) + sink(15, out) + } + { + source := newSource(16) + out := TaintStepTest_StrconvQuoteToASCII_B0I0O0(source) + sink(16, out) + } + { + source := newSource(17) + out := TaintStepTest_StrconvQuoteToGraphic_B0I0O0(source) + sink(17, out) + } + { + source := newSource(18) + out := TaintStepTest_StrconvUnquote_B0I0O0(source) + sink(18, out) + } + { + source := newSource(19) + out := TaintStepTest_StrconvUnquoteChar_B0I0O0(source) + sink(19, out) + } + { + source := newSource(20) + out := TaintStepTest_StrconvUnquoteChar_B0I0O1(source) + sink(20, out) + } +}