Includes original fix expanded for not taking into consideration quoted parenthesis

Revert "Revert "Fix #2517 : Check for incomplete parentheses to prevent SQL injection." (#2674)"
This commit is contained in:
Federico Laitano 2020-02-05 14:14:28 -08:00
parent bcc189866e
commit 87d8239a66
2 changed files with 25 additions and 6 deletions

View File

@ -133,6 +133,7 @@ func TestStringPrimaryKeyForNumericValueStartingWithZero(t *testing.T) {
t.Errorf("Fetch a record from with a string primary key for a numeric value starting with zero should work, but failed, zip code is %v", address.ZipCode) t.Errorf("Fetch a record from with a string primary key for a numeric value starting with zero should work, but failed, zip code is %v", address.ZipCode)
} }
} }
func TestStringAgainstIncompleteParentheses(t *testing.T) { func TestStringAgainstIncompleteParentheses(t *testing.T) {
type AddressByZipCode struct { type AddressByZipCode struct {
ZipCode string `gorm:"primary_key"` ZipCode string `gorm:"primary_key"`
@ -151,6 +152,17 @@ func TestStringAgainstIncompleteParentheses(t *testing.T) {
} }
func TestStringAgainstIncompleteParenthesesQuoted(t *testing.T) {
DB.Save(&User{Name: "name-)-surname"})
var user User
res := DB.Raw("select * from users WHERE name = 'name-)-surname'").First(&user)
if res.Error != nil {
t.Errorf("Can't execute valid query because error : %s", res.Error.Error())
}
}
func TestFindAsSliceOfPointers(t *testing.T) { func TestFindAsSliceOfPointers(t *testing.T) {
DB.Save(&User{Name: "user"}) DB.Save(&User{Name: "user"})

View File

@ -280,16 +280,23 @@ func (scope *Scope) AddToVars(value interface{}) string {
// IsCompleteParentheses check if the string has complete parentheses to prevent SQL injection // IsCompleteParentheses check if the string has complete parentheses to prevent SQL injection
func (scope *Scope) IsCompleteParentheses(value string) bool { func (scope *Scope) IsCompleteParentheses(value string) bool {
count := 0 count := 0
for i, _ := range value { unquoted := true
if value[i] == 40 { // ( for _, ch := range value {
switch ch {
case '(':
if unquoted {
count++ count++
} else if value[i] == 41 { // ) }
case ')':
if unquoted {
count-- count--
} }
case '\'':
unquoted = unquoted != true
}
if count < 0 { if count < 0 {
break break
} }
i++
} }
return count == 0 return count == 0
} }