Skip to content

Commit 75cc7dc

Browse files
authored
Fix false negative for SQL injection when using DB.QueryRow.Scan() (#759)
1 parent 58058af commit 75cc7dc

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

rules/sql.go

+13
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,19 @@ func (s *sqlStrFormat) Match(n ast.Node, ctx *gosec.Context) (*gosec.Issue, erro
261261
switch stmt := n.(type) {
262262
case *ast.AssignStmt:
263263
for _, expr := range stmt.Rhs {
264+
if call, ok := expr.(*ast.CallExpr); ok {
265+
selector, ok := call.Fun.(*ast.SelectorExpr)
266+
if !ok {
267+
continue
268+
}
269+
sqlQueryCall, ok := selector.X.(*ast.CallExpr)
270+
if ok && s.ContainsCallExpr(sqlQueryCall, ctx) != nil {
271+
issue, err := s.checkQuery(sqlQueryCall, ctx)
272+
if err == nil && issue != nil {
273+
return issue, err
274+
}
275+
}
276+
}
264277
if sqlQueryCall, ok := expr.(*ast.CallExpr); ok && s.ContainsCallExpr(expr, ctx) != nil {
265278
return s.checkQuery(sqlQueryCall, ctx)
266279
}

testutils/source.go

+66
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,72 @@ func main(){
11891189
panic(err)
11901190
}
11911191
defer rows.Close()
1192+
}`}, 1, gosec.NewConfig()}, {[]string{`
1193+
// Format string with \n\r
1194+
package main
1195+
1196+
import (
1197+
"database/sql"
1198+
"fmt"
1199+
"os"
1200+
)
1201+
1202+
func main(){
1203+
db, err := sql.Open("sqlite3", ":memory:")
1204+
if err != nil {
1205+
panic(err)
1206+
}
1207+
q := fmt.Sprintf("SELECT * FROM foo where\nname = '%s'", os.Args[1])
1208+
rows, err := db.Query(q)
1209+
if err != nil {
1210+
panic(err)
1211+
}
1212+
defer rows.Close()
1213+
}`}, 1, gosec.NewConfig()}, {[]string{`
1214+
// SQLI by db.Query(some).Scan(&other)
1215+
package main
1216+
1217+
import (
1218+
"database/sql"
1219+
"fmt"
1220+
"os"
1221+
)
1222+
1223+
func main() {
1224+
var name string
1225+
db, err := sql.Open("sqlite3", ":memory:")
1226+
if err != nil {
1227+
panic(err)
1228+
}
1229+
q := fmt.Sprintf("SELECT name FROM users where id = '%s'", os.Args[1])
1230+
row := db.QueryRow(q)
1231+
err = row.Scan(&name)
1232+
if err != nil {
1233+
panic(err)
1234+
}
1235+
defer db.Close()
1236+
}`}, 1, gosec.NewConfig()}, {[]string{`
1237+
// SQLI by db.Query(some).Scan(&other)
1238+
package main
1239+
1240+
import (
1241+
"database/sql"
1242+
"fmt"
1243+
"os"
1244+
)
1245+
1246+
func main() {
1247+
var name string
1248+
db, err := sql.Open("sqlite3", ":memory:")
1249+
if err != nil {
1250+
panic(err)
1251+
}
1252+
q := fmt.Sprintf("SELECT name FROM users where id = '%s'", os.Args[1])
1253+
err = db.QueryRow(q).Scan(&name)
1254+
if err != nil {
1255+
panic(err)
1256+
}
1257+
defer db.Close()
11921258
}`}, 1, gosec.NewConfig()},
11931259
}
11941260

0 commit comments

Comments
 (0)