Skip to content

Commit 1d909e2

Browse files
authored
Add db.Exec and db.Prepare to the sql rule (#763)
* Add db.Exec and db.Prepare to the sql rule * add test cases for G201,G202
1 parent 742aa84 commit 1d909e2

File tree

2 files changed

+165
-5
lines changed

2 files changed

+165
-5
lines changed

rules/sql.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ func NewSQLStrConcat(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
137137
},
138138
}
139139

140-
rule.AddAll("*database/sql.DB", "Query", "QueryContext", "QueryRow", "QueryRowContext")
141-
rule.AddAll("*database/sql.Tx", "Query", "QueryContext", "QueryRow", "QueryRowContext")
140+
rule.AddAll("*database/sql.DB", "Query", "QueryContext", "QueryRow", "QueryRowContext", "Exec", "ExecContext", "Prepare", "PrepareContext")
141+
rule.AddAll("*database/sql.Tx", "Query", "QueryContext", "QueryRow", "QueryRowContext", "Exec", "ExecContext", "Prepare", "PrepareContext")
142142
return rule, []ast.Node{(*ast.AssignStmt)(nil), (*ast.ExprStmt)(nil)}
143143
}
144144

@@ -306,8 +306,8 @@ func NewSQLStrFormat(id string, conf gosec.Config) (gosec.Rule, []ast.Node) {
306306
},
307307
},
308308
}
309-
rule.AddAll("*database/sql.DB", "Query", "QueryContext", "QueryRow", "QueryRowContext")
310-
rule.AddAll("*database/sql.Tx", "Query", "QueryContext", "QueryRow", "QueryRowContext")
309+
rule.AddAll("*database/sql.DB", "Query", "QueryContext", "QueryRow", "QueryRowContext", "Exec", "ExecContext", "Prepare", "PrepareContext")
310+
rule.AddAll("*database/sql.Tx", "Query", "QueryContext", "QueryRow", "QueryRowContext", "Exec", "ExecContext", "Prepare", "PrepareContext")
311311
rule.fmtCalls.AddAll("fmt", "Sprint", "Sprintf", "Sprintln", "Fprintf")
312312
rule.noIssue.AddAll("os", "Stdout", "Stderr")
313313
rule.noIssueQuoted.Add("github.com/lib/pq", "QuoteIdentifier")

testutils/source.go

+161-1
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,103 @@ func main() {
12551255
panic(err)
12561256
}
12571257
defer db.Close()
1258-
}`}, 1, gosec.NewConfig()},
1258+
}`}, 1, gosec.NewConfig()}, {[]string{`
1259+
// SQLI by db.Prepare(some)
1260+
package main
1261+
1262+
import (
1263+
"database/sql"
1264+
"fmt"
1265+
"log"
1266+
"os"
1267+
)
1268+
1269+
const Table = "foo"
1270+
1271+
func main() {
1272+
var album string
1273+
db, err := sql.Open("sqlite3", ":memory:")
1274+
if err != nil {
1275+
panic(err)
1276+
}
1277+
q := fmt.Sprintf("SELECT name FROM users where '%s' = ?", os.Args[1])
1278+
stmt, err := db.Prepare(q)
1279+
if err != nil {
1280+
log.Fatal(err)
1281+
}
1282+
stmt.QueryRow(fmt.Sprintf("%s", os.Args[2])).Scan(&album)
1283+
if err != nil {
1284+
if err == sql.ErrNoRows {
1285+
log.Fatal(err)
1286+
}
1287+
}
1288+
defer stmt.Close()
1289+
}
1290+
`}, 1, gosec.NewConfig()}, {[]string{`
1291+
// SQLI by db.PrepareContext(some)
1292+
package main
1293+
1294+
import (
1295+
"context"
1296+
"database/sql"
1297+
"fmt"
1298+
"log"
1299+
"os"
1300+
)
1301+
1302+
const Table = "foo"
1303+
1304+
func main() {
1305+
var album string
1306+
db, err := sql.Open("sqlite3", ":memory:")
1307+
if err != nil {
1308+
panic(err)
1309+
}
1310+
q := fmt.Sprintf("SELECT name FROM users where '%s' = ?", os.Args[1])
1311+
stmt, err := db.PrepareContext(context.Background(), q)
1312+
if err != nil {
1313+
log.Fatal(err)
1314+
}
1315+
stmt.QueryRow(fmt.Sprintf("%s", os.Args[2])).Scan(&album)
1316+
if err != nil {
1317+
if err == sql.ErrNoRows {
1318+
log.Fatal(err)
1319+
}
1320+
}
1321+
defer stmt.Close()
1322+
}
1323+
`}, 1, gosec.NewConfig()}, {[]string{`
1324+
// false positive
1325+
package main
1326+
1327+
import (
1328+
"database/sql"
1329+
"fmt"
1330+
"log"
1331+
"os"
1332+
)
1333+
1334+
const Table = "foo"
1335+
1336+
func main() {
1337+
var album string
1338+
db, err := sql.Open("sqlite3", ":memory:")
1339+
if err != nil {
1340+
panic(err)
1341+
}
1342+
stmt, err := db.Prepare("SELECT * FROM album WHERE id = ?")
1343+
if err != nil {
1344+
log.Fatal(err)
1345+
}
1346+
stmt.QueryRow(fmt.Sprintf("%s", os.Args[1])).Scan(&album)
1347+
if err != nil {
1348+
if err == sql.ErrNoRows {
1349+
log.Fatal(err)
1350+
}
1351+
}
1352+
defer stmt.Close()
1353+
}
1354+
`}, 0, gosec.NewConfig()},
12591355
}
12601356

12611357
// SampleCodeG202 - SQL query string building via string concatenation
@@ -1431,6 +1527,70 @@ func main(){
14311527
}
14321528
defer rows.Close()
14331529
}
1530+
`}, 0, gosec.NewConfig()}, {[]string{`
1531+
// ExecContext match
1532+
package main
1533+
1534+
import (
1535+
"context"
1536+
"database/sql"
1537+
"fmt"
1538+
"os"
1539+
)
1540+
1541+
func main() {
1542+
db, err := sql.Open("sqlite3", ":memory:")
1543+
if err != nil {
1544+
panic(err)
1545+
}
1546+
result, err := db.ExecContext(context.Background(), "select * from foo where name = "+os.Args[1])
1547+
if err != nil {
1548+
panic(err)
1549+
}
1550+
fmt.Println(result)
1551+
}`}, 1, gosec.NewConfig()}, {[]string{`
1552+
// Exec match
1553+
package main
1554+
1555+
import (
1556+
"database/sql"
1557+
"fmt"
1558+
"os"
1559+
)
1560+
1561+
func main() {
1562+
db, err := sql.Open("sqlite3", ":memory:")
1563+
if err != nil {
1564+
panic(err)
1565+
}
1566+
result, err := db.Exec("select * from foo where name = " + os.Args[1])
1567+
if err != nil {
1568+
panic(err)
1569+
}
1570+
fmt.Println(result)
1571+
}`}, 1, gosec.NewConfig()}, {[]string{`
1572+
package main
1573+
1574+
import (
1575+
"database/sql"
1576+
"fmt"
1577+
)
1578+
const gender = "M"
1579+
const age = "32"
1580+
1581+
var staticQuery = "SELECT * FROM foo WHERE age < "
1582+
1583+
func main() {
1584+
db, err := sql.Open("sqlite3", ":memory:")
1585+
if err != nil {
1586+
panic(err)
1587+
}
1588+
result, err := db.Exec("SELECT * FROM foo WHERE gender = " + gender)
1589+
if err != nil {
1590+
panic(err)
1591+
}
1592+
fmt.Println(result)
1593+
}
14341594
`}, 0, gosec.NewConfig()},
14351595
}
14361596

0 commit comments

Comments
 (0)