mirror of
https://github.com/github/codeql.git
synced 2026-01-29 22:32:58 +01:00
Move to stdlib and extend the models for fmt package
This commit is contained in:
@@ -73,76 +73,6 @@ private class CopyFunction extends TaintTracking::FunctionModel {
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides models of commonly used functions in the `fmt` package. */
|
||||
module Fmt {
|
||||
/** The `Sprint` function or one of its variants. */
|
||||
class Sprinter extends TaintTracking::FunctionModel {
|
||||
Sprinter() { this.hasQualifiedName("fmt", ["Sprint", "Sprintf", "Sprintln"]) }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) {
|
||||
inp.isParameter(_) and outp.isResult()
|
||||
}
|
||||
}
|
||||
|
||||
/** The `Print` function or one of its variants. */
|
||||
class Printer extends Function {
|
||||
Printer() { this.hasQualifiedName("fmt", ["Print", "Printf", "Println"]) }
|
||||
}
|
||||
|
||||
/** A call to `Print`, `Fprint`, or similar. */
|
||||
private class PrintCall extends LoggerCall::Range, DataFlow::CallNode {
|
||||
int firstPrintedArg;
|
||||
|
||||
PrintCall() {
|
||||
this.getTarget() instanceof Printer and firstPrintedArg = 0
|
||||
or
|
||||
this.getTarget() instanceof Fprinter and firstPrintedArg = 1
|
||||
}
|
||||
|
||||
override DataFlow::Node getAMessageComponent() {
|
||||
result = this.getArgument(any(int i | i >= firstPrintedArg))
|
||||
}
|
||||
}
|
||||
|
||||
/** The `Fprint` function or one of its variants. */
|
||||
private class Fprinter extends TaintTracking::FunctionModel {
|
||||
Fprinter() { this.hasQualifiedName("fmt", ["Fprint", "Fprintf", "Fprintln"]) }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input.isParameter(any(int i | i > 0)) and output.isParameter(0)
|
||||
}
|
||||
}
|
||||
|
||||
/** The `Sscan` function or one of its variants. */
|
||||
private class Sscanner extends TaintTracking::FunctionModel {
|
||||
Sscanner() { this.hasQualifiedName("fmt", ["Sscan", "Sscanf", "Sscanln"]) }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input.isParameter(0) and
|
||||
exists(int i | if getName() = "Sscanf" then i > 1 else i > 0 | output.isParameter(i))
|
||||
}
|
||||
}
|
||||
|
||||
/** The `Scan` function or one of its variants, all of which read from os.Stdin */
|
||||
class Scanner extends Function {
|
||||
Scanner() { this.hasQualifiedName("fmt", ["Scan", "Scanf", "Scanln"]) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Fscan` function or one of its variants,
|
||||
* all of which read from a specified io.Reader
|
||||
*/
|
||||
class FScanner extends Function {
|
||||
FScanner() { this.hasQualifiedName("fmt", ["Fscan", "Fscanf", "Fscanln"]) }
|
||||
|
||||
/**
|
||||
* Returns the node corresponding to the io.Reader
|
||||
* argument provided in the call.
|
||||
*/
|
||||
FunctionInput getReader() { result.isParameter(0) }
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides models of commonly used functions in the `io` package. */
|
||||
module Io {
|
||||
private class Copy extends TaintTracking::FunctionModel {
|
||||
|
||||
165
ql/src/semmle/go/frameworks/stdlib/Fmt.qll
Normal file
165
ql/src/semmle/go/frameworks/stdlib/Fmt.qll
Normal file
@@ -0,0 +1,165 @@
|
||||
/**
|
||||
* Provides classes modeling security-relevant aspects of the `fmt` package.
|
||||
*/
|
||||
|
||||
import go
|
||||
|
||||
/** Provides models of commonly used functions in the `fmt` package. */
|
||||
module Fmt {
|
||||
/** The `Sprint` function or one of its variants. */
|
||||
class Sprinter extends TaintTracking::FunctionModel {
|
||||
Sprinter() {
|
||||
// signature: func Sprint(a ...interface{}) string
|
||||
hasQualifiedName("fmt", "Sprint")
|
||||
or
|
||||
// signature: func Sprintf(format string, a ...interface{}) string
|
||||
hasQualifiedName("fmt", "Sprintf")
|
||||
or
|
||||
// signature: func Sprintln(a ...interface{}) string
|
||||
hasQualifiedName("fmt", "Sprintln")
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) {
|
||||
inp.isParameter(_) and outp.isResult()
|
||||
}
|
||||
}
|
||||
|
||||
/** The `Print` function or one of its variants. */
|
||||
class Printer extends Function {
|
||||
Printer() { hasQualifiedName("fmt", ["Print", "Printf", "Println"]) }
|
||||
}
|
||||
|
||||
/** A call to `Print`, `Fprint`, or similar. */
|
||||
private class PrintCall extends LoggerCall::Range, DataFlow::CallNode {
|
||||
int firstPrintedArg;
|
||||
|
||||
PrintCall() {
|
||||
this.getTarget() instanceof Printer and firstPrintedArg = 0
|
||||
or
|
||||
this.getTarget() instanceof Fprinter and firstPrintedArg = 1
|
||||
}
|
||||
|
||||
override DataFlow::Node getAMessageComponent() {
|
||||
result = this.getArgument(any(int i | i >= firstPrintedArg))
|
||||
}
|
||||
}
|
||||
|
||||
/** The `Fprint` function or one of its variants. */
|
||||
private class Fprinter extends TaintTracking::FunctionModel {
|
||||
Fprinter() {
|
||||
// signature: func Fprint(w io.Writer, a ...interface{}) (n int, err error)
|
||||
hasQualifiedName("fmt", "Fprint")
|
||||
or
|
||||
// signature: func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)
|
||||
hasQualifiedName("fmt", "Fprintf")
|
||||
or
|
||||
// signature: func Fprintln(w io.Writer, a ...interface{}) (n int, err error)
|
||||
hasQualifiedName("fmt", "Fprintln")
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input.isParameter(any(int i | i > 0)) and output.isParameter(0)
|
||||
}
|
||||
}
|
||||
|
||||
/** The `Sscan` function or one of its variants. */
|
||||
private class Sscanner extends TaintTracking::FunctionModel {
|
||||
FunctionInput inp;
|
||||
FunctionOutput outp;
|
||||
|
||||
Sscanner() {
|
||||
// signature: func Sscan(str string, a ...interface{}) (n int, err error)
|
||||
hasQualifiedName("fmt", "Sscan") and
|
||||
(inp.isParameter(0) and outp.isParameter(any(int i | i >= 1)))
|
||||
or
|
||||
// signature: func Sscanf(str string, format string, a ...interface{}) (n int, err error)
|
||||
hasQualifiedName("fmt", "Sscanf") and
|
||||
(inp.isParameter([0, 1]) and outp.isParameter(any(int i | i >= 2)))
|
||||
or
|
||||
// signature: func Sscanln(str string, a ...interface{}) (n int, err error)
|
||||
hasQualifiedName("fmt", "Sscanln") and
|
||||
(inp.isParameter(0) and outp.isParameter(any(int i | i >= 1)))
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input = inp and output = outp
|
||||
}
|
||||
}
|
||||
|
||||
/** The `Scan` function or one of its variants, all of which read from os.Stdin */
|
||||
class Scanner extends Function {
|
||||
Scanner() { this.hasQualifiedName("fmt", ["Scan", "Scanf", "Scanln"]) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Fscan` function or one of its variants,
|
||||
* all of which read from a specified io.Reader
|
||||
*/
|
||||
class FScanner extends Function {
|
||||
FScanner() { this.hasQualifiedName("fmt", ["Fscan", "Fscanf", "Fscanln"]) }
|
||||
|
||||
/**
|
||||
* Returns the node corresponding to the io.Reader
|
||||
* argument provided in the call.
|
||||
*/
|
||||
FunctionInput getReader() { result.isParameter(0) }
|
||||
}
|
||||
|
||||
private class FunctionModels extends TaintTracking::FunctionModel {
|
||||
FunctionInput inp;
|
||||
FunctionOutput outp;
|
||||
|
||||
FunctionModels() {
|
||||
// signature: func Errorf(format string, a ...interface{}) error
|
||||
hasQualifiedName("fmt", "Errorf") and
|
||||
(inp.isParameter(_) and outp.isResult())
|
||||
or
|
||||
// signature: func Fscan(r io.Reader, a ...interface{}) (n int, err error)
|
||||
hasQualifiedName("fmt", "Fscan") and
|
||||
(inp.isParameter(0) and outp.isParameter(any(int i | i >= 1)))
|
||||
or
|
||||
// signature: func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error)
|
||||
hasQualifiedName("fmt", "Fscanf") and
|
||||
(inp.isParameter([0, 1]) and outp.isParameter(any(int i | i >= 2)))
|
||||
or
|
||||
// signature: func Fscanln(r io.Reader, a ...interface{}) (n int, err error)
|
||||
hasQualifiedName("fmt", "Fscanln") and
|
||||
(inp.isParameter(0) and outp.isParameter(any(int i | i >= 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() {
|
||||
// signature: func (GoStringer).GoString() string
|
||||
this.implements("fmt", "GoStringer", "GoString") and
|
||||
(inp.isReceiver() and outp.isResult())
|
||||
or
|
||||
// signature: func (ScanState).Read(buf []byte) (n int, err error)
|
||||
this.implements("fmt", "ScanState", "Read") and
|
||||
(inp.isReceiver() and outp.isParameter(0))
|
||||
or
|
||||
// signature: func (Stringer).String() string
|
||||
this.implements("fmt", "Stringer", "String") and
|
||||
(inp.isReceiver() and outp.isResult())
|
||||
or
|
||||
// signature: func (ScanState).Token(skipSpace bool, f func(rune) bool) (token []byte, err error)
|
||||
this.implements("fmt", "ScanState", "Token") and
|
||||
(inp.isReceiver() and outp.isResult(0))
|
||||
or
|
||||
// signature: func (State).Write(b []byte) (n int, err error)
|
||||
this.implements("fmt", "State", "Write") and
|
||||
(inp.isParameter(0) and outp.isReceiver())
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input = inp and output = outp
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
// Code generated by https://github.com/gagliardetto/codebox. DO NOT EDIT.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
func TaintStepTest_FmtErrorf_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromString656 := sourceCQL.(string)
|
||||
intoError414 := fmt.Errorf(fromString656, nil)
|
||||
return intoError414
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtErrorf_B0I1O0(sourceCQL interface{}) interface{} {
|
||||
fromInterface518 := sourceCQL.(interface{})
|
||||
intoError650 := fmt.Errorf("", fromInterface518)
|
||||
return intoError650
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtFprint_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromInterface784 := sourceCQL.(interface{})
|
||||
var intoWriter957 io.Writer
|
||||
fmt.Fprint(intoWriter957, fromInterface784)
|
||||
return intoWriter957
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtFprintf_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromString520 := sourceCQL.(string)
|
||||
var intoWriter443 io.Writer
|
||||
fmt.Fprintf(intoWriter443, fromString520, nil)
|
||||
return intoWriter443
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtFprintf_B0I1O0(sourceCQL interface{}) interface{} {
|
||||
fromInterface127 := sourceCQL.(interface{})
|
||||
var intoWriter483 io.Writer
|
||||
fmt.Fprintf(intoWriter483, "", fromInterface127)
|
||||
return intoWriter483
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtFprintln_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromInterface989 := sourceCQL.(interface{})
|
||||
var intoWriter982 io.Writer
|
||||
fmt.Fprintln(intoWriter982, fromInterface989)
|
||||
return intoWriter982
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtFscan_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromReader417 := sourceCQL.(io.Reader)
|
||||
var intoInterface584 interface{}
|
||||
fmt.Fscan(fromReader417, intoInterface584)
|
||||
return intoInterface584
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtFscanf_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromReader991 := sourceCQL.(io.Reader)
|
||||
var intoInterface881 interface{}
|
||||
fmt.Fscanf(fromReader991, "", intoInterface881)
|
||||
return intoInterface881
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtFscanf_B0I1O0(sourceCQL interface{}) interface{} {
|
||||
fromString186 := sourceCQL.(string)
|
||||
var intoInterface284 interface{}
|
||||
fmt.Fscanf(nil, fromString186, intoInterface284)
|
||||
return intoInterface284
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtFscanln_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromReader908 := sourceCQL.(io.Reader)
|
||||
var intoInterface137 interface{}
|
||||
fmt.Fscanln(fromReader908, intoInterface137)
|
||||
return intoInterface137
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtSprint_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromInterface494 := sourceCQL.(interface{})
|
||||
intoString873 := fmt.Sprint(fromInterface494)
|
||||
return intoString873
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtSprintf_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromString599 := sourceCQL.(string)
|
||||
intoString409 := fmt.Sprintf(fromString599, nil)
|
||||
return intoString409
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtSprintf_B0I1O0(sourceCQL interface{}) interface{} {
|
||||
fromInterface246 := sourceCQL.(interface{})
|
||||
intoString898 := fmt.Sprintf("", fromInterface246)
|
||||
return intoString898
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtSprintln_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromInterface598 := sourceCQL.(interface{})
|
||||
intoString631 := fmt.Sprintln(fromInterface598)
|
||||
return intoString631
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtSscan_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromString165 := sourceCQL.(string)
|
||||
var intoInterface150 interface{}
|
||||
fmt.Sscan(fromString165, intoInterface150)
|
||||
return intoInterface150
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtSscanf_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromString340 := sourceCQL.(string)
|
||||
var intoInterface471 interface{}
|
||||
fmt.Sscanf(fromString340, "", intoInterface471)
|
||||
return intoInterface471
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtSscanf_B0I1O0(sourceCQL interface{}) interface{} {
|
||||
fromString290 := sourceCQL.(string)
|
||||
var intoInterface758 interface{}
|
||||
fmt.Sscanf("", fromString290, intoInterface758)
|
||||
return intoInterface758
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtSscanln_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromString396 := sourceCQL.(string)
|
||||
var intoInterface707 interface{}
|
||||
fmt.Sscanln(fromString396, intoInterface707)
|
||||
return intoInterface707
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtGoStringerGoString_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromGoStringer912 := sourceCQL.(fmt.GoStringer)
|
||||
intoString718 := fromGoStringer912.GoString()
|
||||
return intoString718
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtScanStateRead_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromScanState972 := sourceCQL.(fmt.ScanState)
|
||||
var intoByte633 []byte
|
||||
fromScanState972.Read(intoByte633)
|
||||
return intoByte633
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtStringerString_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromStringer316 := sourceCQL.(fmt.Stringer)
|
||||
intoString145 := fromStringer316.String()
|
||||
return intoString145
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtScanStateToken_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromScanState817 := sourceCQL.(fmt.ScanState)
|
||||
intoByte474, _ := fromScanState817.Token(false, nil)
|
||||
return intoByte474
|
||||
}
|
||||
|
||||
func TaintStepTest_FmtStateWrite_B0I0O0(sourceCQL interface{}) interface{} {
|
||||
fromByte832 := sourceCQL.([]byte)
|
||||
var intoState378 fmt.State
|
||||
intoState378.Write(fromByte832)
|
||||
return intoState378
|
||||
}
|
||||
|
||||
func RunAllTaints_Fmt() {
|
||||
{
|
||||
source := newSource(0)
|
||||
out := TaintStepTest_FmtErrorf_B0I0O0(source)
|
||||
sink(0, out)
|
||||
}
|
||||
{
|
||||
source := newSource(1)
|
||||
out := TaintStepTest_FmtErrorf_B0I1O0(source)
|
||||
sink(1, out)
|
||||
}
|
||||
{
|
||||
source := newSource(2)
|
||||
out := TaintStepTest_FmtFprint_B0I0O0(source)
|
||||
sink(2, out)
|
||||
}
|
||||
{
|
||||
source := newSource(3)
|
||||
out := TaintStepTest_FmtFprintf_B0I0O0(source)
|
||||
sink(3, out)
|
||||
}
|
||||
{
|
||||
source := newSource(4)
|
||||
out := TaintStepTest_FmtFprintf_B0I1O0(source)
|
||||
sink(4, out)
|
||||
}
|
||||
{
|
||||
source := newSource(5)
|
||||
out := TaintStepTest_FmtFprintln_B0I0O0(source)
|
||||
sink(5, out)
|
||||
}
|
||||
{
|
||||
source := newSource(6)
|
||||
out := TaintStepTest_FmtFscan_B0I0O0(source)
|
||||
sink(6, out)
|
||||
}
|
||||
{
|
||||
source := newSource(7)
|
||||
out := TaintStepTest_FmtFscanf_B0I0O0(source)
|
||||
sink(7, out)
|
||||
}
|
||||
{
|
||||
source := newSource(8)
|
||||
out := TaintStepTest_FmtFscanf_B0I1O0(source)
|
||||
sink(8, out)
|
||||
}
|
||||
{
|
||||
source := newSource(9)
|
||||
out := TaintStepTest_FmtFscanln_B0I0O0(source)
|
||||
sink(9, out)
|
||||
}
|
||||
{
|
||||
source := newSource(10)
|
||||
out := TaintStepTest_FmtSprint_B0I0O0(source)
|
||||
sink(10, out)
|
||||
}
|
||||
{
|
||||
source := newSource(11)
|
||||
out := TaintStepTest_FmtSprintf_B0I0O0(source)
|
||||
sink(11, out)
|
||||
}
|
||||
{
|
||||
source := newSource(12)
|
||||
out := TaintStepTest_FmtSprintf_B0I1O0(source)
|
||||
sink(12, out)
|
||||
}
|
||||
{
|
||||
source := newSource(13)
|
||||
out := TaintStepTest_FmtSprintln_B0I0O0(source)
|
||||
sink(13, out)
|
||||
}
|
||||
{
|
||||
source := newSource(14)
|
||||
out := TaintStepTest_FmtSscan_B0I0O0(source)
|
||||
sink(14, out)
|
||||
}
|
||||
{
|
||||
source := newSource(15)
|
||||
out := TaintStepTest_FmtSscanf_B0I0O0(source)
|
||||
sink(15, out)
|
||||
}
|
||||
{
|
||||
source := newSource(16)
|
||||
out := TaintStepTest_FmtSscanf_B0I1O0(source)
|
||||
sink(16, out)
|
||||
}
|
||||
{
|
||||
source := newSource(17)
|
||||
out := TaintStepTest_FmtSscanln_B0I0O0(source)
|
||||
sink(17, out)
|
||||
}
|
||||
{
|
||||
source := newSource(18)
|
||||
out := TaintStepTest_FmtGoStringerGoString_B0I0O0(source)
|
||||
sink(18, out)
|
||||
}
|
||||
{
|
||||
source := newSource(19)
|
||||
out := TaintStepTest_FmtScanStateRead_B0I0O0(source)
|
||||
sink(19, out)
|
||||
}
|
||||
{
|
||||
source := newSource(20)
|
||||
out := TaintStepTest_FmtStringerString_B0I0O0(source)
|
||||
sink(20, out)
|
||||
}
|
||||
{
|
||||
source := newSource(21)
|
||||
out := TaintStepTest_FmtScanStateToken_B0I0O0(source)
|
||||
sink(21, out)
|
||||
}
|
||||
{
|
||||
source := newSource(22)
|
||||
out := TaintStepTest_FmtStateWrite_B0I0O0(source)
|
||||
sink(22, out)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user