mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 17:08:53 +00:00
Sanitize column names for order key in MySQL (#2224)
This adds a SQL injection prevention for a case in which we cannot use parameters in the query. It is not clear that this was possible to exploit. If it was possible, it would have required a valid login to the Fleet server.
This commit is contained in:
parent
ed79c00341
commit
be8dbb426e
2 changed files with 37 additions and 1 deletions
|
|
@ -7,6 +7,7 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"github.com/WatchBeam/clock"
|
||||
|
|
@ -25,6 +26,10 @@ const (
|
|||
defaultSelectLimit = 100000
|
||||
)
|
||||
|
||||
var (
|
||||
columnCharsRegexp = regexp.MustCompile(`[^\w-]`)
|
||||
)
|
||||
|
||||
// Datastore is an implementation of kolide.Datastore interface backed by
|
||||
// MySQL
|
||||
type Datastore struct {
|
||||
|
|
@ -249,14 +254,19 @@ func (d *Datastore) log(msg string) {
|
|||
d.logger.Log("comp", d.Name(), "msg", msg)
|
||||
}
|
||||
|
||||
func sanitizeColumn(col string) string {
|
||||
return columnCharsRegexp.ReplaceAllString(col, "")
|
||||
}
|
||||
|
||||
func appendListOptionsToSQL(sql string, opts kolide.ListOptions) string {
|
||||
if opts.OrderKey != "" {
|
||||
direction := "ASC"
|
||||
if opts.OrderDirection == kolide.OrderDescending {
|
||||
direction = "DESC"
|
||||
}
|
||||
orderKey := sanitizeColumn(opts.OrderKey)
|
||||
|
||||
sql = fmt.Sprintf("%s ORDER BY %s %s", sql, opts.OrderKey, direction)
|
||||
sql = fmt.Sprintf("%s ORDER BY %s %s", sql, orderKey, direction)
|
||||
}
|
||||
// REVIEW: If caller doesn't supply a limit apply a default limit of 1000
|
||||
// to insure that an unbounded query with many results doesn't consume too
|
||||
|
|
|
|||
26
server/datastore/mysql/mysql_test.go
Normal file
26
server/datastore/mysql/mysql_test.go
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
package mysql
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSanitizeColumn(t *testing.T) {
|
||||
testCases := []struct {
|
||||
input string
|
||||
output string
|
||||
}{
|
||||
{"foobar-column", "foobar-column"},
|
||||
{"foobar_column", "foobar_column"},
|
||||
{"foobar;column", "foobarcolumn"},
|
||||
{"foobar#", "foobar"},
|
||||
{"foobar*baz", "foobarbaz"},
|
||||
}
|
||||
|
||||
for _, tt := range testCases {
|
||||
t.Run(tt.input, func(t *testing.T) {
|
||||
assert.Equal(t, tt.output, sanitizeColumn(tt.input))
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue