Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit 42c7f8c

Browse files
gagliardettosmowton
authored andcommitted
Add taint-tracking for strconv package; rename module StrConv to Strconv and move into stdlib
1 parent b8d36b9 commit 42c7f8c

File tree

4 files changed

+352
-36
lines changed

4 files changed

+352
-36
lines changed

ql/src/Security/CWE-681/IncorrectIntegerConversion.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class ConversionWithoutBoundsCheckConfig extends TaintTracking::Configuration {
101101
// If we are reading a variable, check if it is
102102
// `strconv.IntSize`, and use 0 if it is.
103103
exists(DataFlow::Node rawBitSize | rawBitSize = ip.getTargetBitSizeInput().getNode(c) |
104-
if rawBitSize = any(StrConv::IntSize intSize).getARead()
104+
if rawBitSize = any(Strconv::IntSize intSize).getARead()
105105
then apparentBitSize = 0
106106
else apparentBitSize = rawBitSize.getIntValue()
107107
)

ql/src/semmle/go/frameworks/Stdlib.qll

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import semmle.go.frameworks.stdlib.MimeQuotedprintable
1818
import semmle.go.frameworks.stdlib.Path
1919
import semmle.go.frameworks.stdlib.PathFilepath
2020
import semmle.go.frameworks.stdlib.Reflect
21+
import semmle.go.frameworks.stdlib.Strconv
22+
import semmle.go.frameworks.stdlib.Strings
2123
import semmle.go.frameworks.stdlib.TextScanner
2224
import semmle.go.frameworks.stdlib.TextTabwriter
2325
import semmle.go.frameworks.stdlib.TextTemplate
@@ -483,41 +485,6 @@ module IntegerParser {
483485
}
484486
}
485487

486-
/**
487-
* Provides classes for some functions in the `strconv` package for
488-
* converting strings to numbers.
489-
*/
490-
module StrConv {
491-
/** The `Atoi` function. */
492-
class Atoi extends IntegerParser::Range {
493-
Atoi() { this.hasQualifiedName("strconv", "Atoi") }
494-
495-
override int getTargetBitSize() { result = 0 }
496-
}
497-
498-
/** The `ParseInt` function. */
499-
class ParseInt extends IntegerParser::Range {
500-
ParseInt() { this.hasQualifiedName("strconv", "ParseInt") }
501-
502-
override FunctionInput getTargetBitSizeInput() { result.isParameter(2) }
503-
}
504-
505-
/** The `ParseUint` function. */
506-
class ParseUint extends IntegerParser::Range {
507-
ParseUint() { this.hasQualifiedName("strconv", "ParseUint") }
508-
509-
override FunctionInput getTargetBitSizeInput() { result.isParameter(2) }
510-
}
511-
512-
/**
513-
* The `IntSize` constant, that gives the size in bits of an `int` or
514-
* `uint` value on the current architecture (32 or 64).
515-
*/
516-
class IntSize extends DeclaredConstant {
517-
IntSize() { this.hasQualifiedName("strconv", "IntSize") }
518-
}
519-
}
520-
521488
/** Provides models of commonly used functions in the `strings` package. */
522489
module Strings {
523490
/** The `Join` function. */
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/**
2+
* Provides classes modeling security-relevant aspects of the `strconv` package.
3+
*/
4+
5+
import go
6+
7+
/** Provides models of commonly used functions in the `strconv` package. */
8+
module Strconv {
9+
/** The `Atoi` function. */
10+
class Atoi extends IntegerParser::Range {
11+
Atoi() { this.hasQualifiedName("strconv", "Atoi") }
12+
13+
override int getTargetBitSize() { result = 0 }
14+
}
15+
16+
/** The `ParseInt` function. */
17+
class ParseInt extends IntegerParser::Range {
18+
ParseInt() { this.hasQualifiedName("strconv", "ParseInt") }
19+
20+
override FunctionInput getTargetBitSizeInput() { result.isParameter(2) }
21+
}
22+
23+
/** The `ParseUint` function. */
24+
class ParseUint extends IntegerParser::Range {
25+
ParseUint() { this.hasQualifiedName("strconv", "ParseUint") }
26+
27+
override FunctionInput getTargetBitSizeInput() { result.isParameter(2) }
28+
}
29+
30+
/**
31+
* The `IntSize` constant, that gives the size in bits of an `int` or
32+
* `uint` value on the current architecture (32 or 64).
33+
*/
34+
class IntSize extends DeclaredConstant {
35+
IntSize() { this.hasQualifiedName("strconv", "IntSize") }
36+
}
37+
38+
private class FunctionModels extends TaintTracking::FunctionModel {
39+
FunctionInput inp;
40+
FunctionOutput outp;
41+
42+
FunctionModels() {
43+
// signature: func AppendQuote(dst []byte, s string) []byte
44+
hasQualifiedName("strconv", "AppendQuote") and
45+
(
46+
inp.isParameter(_) and outp.isResult()
47+
or
48+
inp.isParameter(1) and
49+
(outp.isParameter(0) or outp.isResult())
50+
)
51+
or
52+
// signature: func AppendQuoteToASCII(dst []byte, s string) []byte
53+
hasQualifiedName("strconv", "AppendQuoteToASCII") and
54+
(
55+
inp.isParameter(_) and outp.isResult()
56+
or
57+
inp.isParameter(1) and
58+
(outp.isParameter(0) or outp.isResult())
59+
)
60+
or
61+
// signature: func AppendQuoteToGraphic(dst []byte, s string) []byte
62+
hasQualifiedName("strconv", "AppendQuoteToGraphic") and
63+
(
64+
inp.isParameter(_) and outp.isResult()
65+
or
66+
inp.isParameter(1) and
67+
(outp.isParameter(0) or outp.isResult())
68+
)
69+
or
70+
// signature: func Quote(s string) string
71+
hasQualifiedName("strconv", "Quote") and
72+
(inp.isParameter(0) and outp.isResult())
73+
or
74+
// signature: func QuoteRune(r rune) string
75+
hasQualifiedName("strconv", "QuoteRune") and
76+
(inp.isParameter(0) and outp.isResult())
77+
or
78+
// signature: func QuoteRuneToASCII(r rune) string
79+
hasQualifiedName("strconv", "QuoteRuneToASCII") and
80+
(inp.isParameter(0) and outp.isResult())
81+
or
82+
// signature: func QuoteRuneToGraphic(r rune) string
83+
hasQualifiedName("strconv", "QuoteRuneToGraphic") and
84+
(inp.isParameter(0) and outp.isResult())
85+
or
86+
// signature: func QuoteToASCII(s string) string
87+
hasQualifiedName("strconv", "QuoteToASCII") and
88+
(inp.isParameter(0) and outp.isResult())
89+
or
90+
// signature: func QuoteToGraphic(s string) string
91+
hasQualifiedName("strconv", "QuoteToGraphic") and
92+
(inp.isParameter(0) and outp.isResult())
93+
or
94+
// signature: func Unquote(s string) (string, error)
95+
hasQualifiedName("strconv", "Unquote") and
96+
(inp.isParameter(0) and outp.isResult(0))
97+
or
98+
// signature: func UnquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err error)
99+
hasQualifiedName("strconv", "UnquoteChar") and
100+
(inp.isParameter(0) and outp.isResult([0, 2]))
101+
}
102+
103+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
104+
input = inp and output = outp
105+
}
106+
}
107+
}

0 commit comments

Comments
 (0)