Audit required: Unsafe quoting for `github.com/Masterminds/squirrel` packageGO-S1017
Code that forms a string containing a quoted substring must guarantee that any user-provided data embedded between the quotes does not itself have a quote. Else, the embedded data could (accidentally or intentionally) change the overall structure by terminating the quoted substring early, with potentially severe consequences like command injection or SQL injection attacks. It is recommended to use the squirrel's placeholder syntax or sanitize the embedded data appropriately to ensure quotes are escaped or use an API that does not manually construct quoted substrings.
Bad practice
func insert(id string, version interface{}) {
vJSON, _ := json.Marshal(version)
sq.StatementBuilder.
Insert("metrics").
Columns("metric_id", "vgo").
Values(
id,
sq.Expr(fmt.Sprintf("vgo('%s')", vJSON)),
).
Exec()
}
In the example, assume that the version
is from an untrusted source. json.Marshal
is used to serializing the version
object into a JSON encoded string and embed it into a SQL query built using the Squirrel library. While Squirrel package provides a structured API for constructing SQL queries that mitigate against some common SQL injection attacks, this code is still vulnerable to exploitation. If the JSON encoded string of the version
objects contains a single quote, this will prematurely close the surrounding string even when it didn't end, therefore, changing the structure of the SQL expression being built. This could be exploited to mount a SQL injection attack.
Recommended
func insert(id string, version interface{}) {
vJSON, _ := json.Marshal(version)
sq.StatementBuilder.
Insert("metrics").
Columns("metric_id", "vgo").
Values(
id,
// NOTE: Use squirrel's placeholder syntax to avoid the need to
// explicitly construct a quoted string
sq.Expr("vgo(?)", vJSON),
).
Exec()
}