English | 简体中文
- 标记污点源-UntrustedFlowSource
- 标记污点传播函数-TaintTracking::FunctionModel
- 标记SQL语句-SQL::QueryString
- 标记日志打印函数-LoggerCall
- 标记HTTP重定向URL-HTTP::Redirect
标记污点源,可提升CodeQL检测能力
//@codeql untrust (Param(0)| Result(0) | IsReceiver)
- Param(0) 表示第一个参数是不可信的污点源(用户可控)
- Result(0) 表示第一个返回值是不可信的污点源(用户可控)
- IsReceiver 表示方法接收者是不可信的污点源(用户可控)
- Param(0),Result(0),IsReceiver 可同时多个一起注释,表示第一个参数,第一个返回值,方法接收者都是不可信的污点源(用户可控)
- 在type定义上标记,代表整个结构体的所有字段都是不可信的用户可控输入。
//@codeql untrust
type Param struct {
Key string
Value string
}
标记依赖库(跨包)污点
//@codeql untrust Package(github.com/xxx/yyy) Type(Param)
// Param定义在别的项目中
type Param struct {
Key string
Value string
}
- 在结构体(struct)的字段(field)上标记,代表该字段是不可信的用户可控输入。
type Context struct {
app *Application
Params Params //@codeql untrust
Route *Route
Request *http.Request
Response http.ResponseWriter
query url.Values
}
标记依赖库(跨包)污点
//@codeql untrust Package(github.com/xxx/yyy) Field(Context,Params)
// Context定义在别的项目中
type Context struct {
app *Application
Params Params
Route *Route
Request *http.Request
Response http.ResponseWriter
query url.Values
}
- 在方法上添加注释/也支持标记依赖库(跨包)的方法/函数/接口方法
//@codeql untrust Param(0)
//@codeql untrust Package(github.com/xxx/yyy) Method(Context,Decode) Param(0)
//@codeql untrust Package(github.com/xxx/yyy) Interface(InterfaceName,Decode) Param(0)
//@codeql untrust Package(github.com/xxx/yyy) Func(Decode) Param(0)
func (c *Context) Decode(v interface{}) (err error) {
if c.app.Decoder == nil {
return ErrDecoderNotRegister
}
return c.app.Decoder.Decode(c.Request, v)
}
//@codeql untrust Result(0)
func (c *Context) QueryParam(key string) string {
return c.QueryParams().Get(key)
}
- 在函数上添加注释
// Vars returns the route variables for the current request, if any.
//@codeql untrust Result(0)
func Vars(r *http.Request) map[string]string {
if rv := r.Context().Value(varsKey); rv != nil {
return rv.(map[string]string)
}
return nil
}
- 在接口方法上添加注释
// Decoder is an interface that decodes request's input.
type Decoder interface {
// Decode decodes request's input and stores it in the value pointed to by v.
Decode(req *http.Request, v interface{}) error //@codeql untrust Param(1)
}
标记污点传播函数,可提升CodeQL检测能力
//@codeql tainttrack InParam(0) OutResult(0)
- InParam(0) 表示第一个参数是污点源
- InIsReceiver 表示方法接收者是污点源
- OutParam(1) 表示第二个参数会被污点源传染,也将成为污点源
- OutResult(1) 表示第二个返回值会被污点源传染,也将成为污点源
- OutIsReceiver 表示方法接收者会被污点源传染,也将成为污点源
- 在方法/函数/接口方法上标记污点传播函数
//@codeql tainttrack InParam(1) OutResult(0)
func NewError(code int, message ...string) *Error {
err := &Error{
Code: code,
Message: utils.StatusMessage(code),
}
if len(message) > 0 {
err.Message = message[0]
}
return err
}
//@codeql tainttrack InParam(0) OutResult(0)
func TrimBytes(b []byte, cutset byte) []byte {
i, j := 0, len(b)-1
for ; i <= j; i++ {
if b[i] != cutset {
break
}
}
for ; i < j; j-- {
if b[j] != cutset {
break
}
}
return b[i : j+1]
}
标记SQL语句,可用于发现SQL注入
//@codeql sql Param(0)
- 在方法/函数/接口方法上标记SQL语句参数位置
- 例子中Select方法的第二个参数就是SQL语句,所以是Param(1)
//@codeql sql Param(1)
func (db *DB) Select(dest interface{}, query string, args ...interface{}) error {
return Select(db, dest, query, args...)
}
标记日志打印函数,可用于发现敏感信息泄露
//@codeql logger
- 在日志库打印方法上添加注释
//@codeql logger
func (logger *Logger) Log(level Level, args ...interface{}) {
if logger.IsLevelEnabled(level) {
entry := logger.newEntry()
entry.Log(level, args...)
logger.releaseEntry(entry)
}
}
- 在日志库打印函数上添加注释
//@codeql logger
func Debug(args ...interface{}) {
std.Debug(args...)
}
//@codeql logger
func Print(args ...interface{}) {
std.Print(args...)
}
//@codeql logger
func Info(args ...interface{}) {
std.Info(args...)
}
- 为日志库接口方法添加注释
type FieldLogger interface {
WithField(key string, value interface{}) *Entry
WithFields(fields Fields) *Entry
WithError(err error) *Entry
Debugf(format string, args ...interface{})//@codeql logger
Infof(format string, args ...interface{})//@codeql logger
Printf(format string, args ...interface{})//@codeql logger
Warnf(format string, args ...interface{})//@codeql logger
Warningf(format string, args ...interface{})//@codeql logger
Errorf(format string, args ...interface{})//@codeql logger
Fatalf(format string, args ...interface{})//@codeql logger
Panicf(format string, args ...interface{})//@codeql logger
Debug(args ...interface{})//@codeql logger
Info(args ...interface{})//@codeql logger
Print(args ...interface{})//@codeql logger
Warn(args ...interface{})//@codeql logger
Warning(args ...interface{})//@codeql logger
Error(args ...interface{})//@codeql logger
Fatal(args ...interface{})//@codeql logger
Panic(args ...interface{})//@codeql logger
Debugln(args ...interface{})//@codeql logger
Infoln(args ...interface{})//@codeql logger
Println(args ...interface{})//@codeql logger
Warnln(args ...interface{})//@codeql logger
Warningln(args ...interface{})//@codeql logger
Errorln(args ...interface{})//@codeql logger
Fatalln(args ...interface{})//@codeql logger
Panicln(args ...interface{})//@codeql logger
}
标记HTTP重定向URL,用于发现重定向注入攻击
//@codeql redirect Param(0)
- 在方法/函数/接口方法上标记HTTP redirect方法URL参数位置
- 例子中Redirect方法的第一个参数就是URL,所以是Param(0)
//@codeql redirect Param(0)
func (c *Ctx) Redirect(location string, status ...int) error {
c.setCanonical(HeaderLocation, location)
if len(status) > 0 {
c.Status(status[0])
} else {
c.Status(StatusFound)
}
return nil
}