Fix #2517 : Check for incomplete parentheses to prevent SQL inj… (#2519)

Fix #2517 : Check for incomplete parentheses to prevent SQL injection.
This commit is contained in:
Emir Beganović 2019-06-30 11:50:19 +04:00 committed by GitHub
commit 836fb2c19d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 0 deletions

View File

@ -133,6 +133,23 @@ 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) {
type AddressByZipCode struct {
ZipCode string `gorm:"primary_key"`
Address string
}
DB.AutoMigrate(&AddressByZipCode{})
DB.Create(&AddressByZipCode{ZipCode: "00502", Address: "Holtsville"})
var address AddressByZipCode
var addresses []AddressByZipCode
_ = DB.First(&address, "address_by_zip_codes=00502)) UNION ALL SELECT NULL,version(),current_database(),NULL,NULL,NULL,NULL,NULL--").Find(&addresses).GetErrors()
if len(addresses) > 0 {
t.Errorf("Fetch a record from with a string that has incomplete parentheses should be fail, zip code is %v", address.ZipCode)
}
}
func TestFindAsSliceOfPointers(t *testing.T) { func TestFindAsSliceOfPointers(t *testing.T) {
DB.Save(&User{Name: "user"}) DB.Save(&User{Name: "user"})

View File

@ -277,6 +277,23 @@ func (scope *Scope) AddToVars(value interface{}) string {
return scope.Dialect().BindVar(len(scope.SQLVars)) return scope.Dialect().BindVar(len(scope.SQLVars))
} }
// IsCompleteParentheses check if the string has complete parentheses to prevent SQL injection
func (scope *Scope) IsCompleteParentheses(value string) bool {
count := 0
for i, _ := range value {
if value[i] == 40 { // (
count++
} else if value[i] == 41 { // )
count--
}
if count < 0 {
break
}
i++
}
return count == 0
}
// SelectAttrs return selected attributes // SelectAttrs return selected attributes
func (scope *Scope) SelectAttrs() []string { func (scope *Scope) SelectAttrs() []string {
if scope.selectAttrs == nil { if scope.selectAttrs == nil {
@ -556,6 +573,10 @@ func (scope *Scope) buildCondition(clause map[string]interface{}, include bool)
} }
if value != "" { if value != "" {
if !scope.IsCompleteParentheses(value) {
scope.Err(fmt.Errorf("incomplete parentheses found: %v", value))
return
}
if !include { if !include {
if comparisonRegexp.MatchString(value) { if comparisonRegexp.MatchString(value) {
str = fmt.Sprintf("NOT (%v)", value) str = fmt.Sprintf("NOT (%v)", value)