Add taint-tracking for strconv package; rename module StrConv to Strconv and move into stdlib

This commit is contained in:
Slavomir
2020-09-01 13:40:52 +02:00
committed by Chris Smowton
parent b8d36b936e
commit 42c7f8cc0d
4 changed files with 352 additions and 36 deletions

View File

@@ -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()
)

View File

@@ -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. */

View File

@@ -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
}
}
}

View File

@@ -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)
}
}