feat(sql): SQL Injection
This commit is contained in:
120
sql/validate.go
Normal file
120
sql/validate.go
Normal file
@@ -0,0 +1,120 @@
|
||||
package sql
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"git.secnex.io/secnex/pgson/schema"
|
||||
)
|
||||
|
||||
var (
|
||||
IdentifierRegex = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_]*$`)
|
||||
TypeMap = map[string]string{
|
||||
"string": "VARCHAR",
|
||||
"int": "INTEGER",
|
||||
"float": "FLOAT",
|
||||
"bool": "BOOLEAN",
|
||||
"date": "DATE",
|
||||
"time": "TIME",
|
||||
"datetime": "TIMESTAMP",
|
||||
"uuid": "UUID",
|
||||
"json": "JSONB",
|
||||
"hash": "VARCHAR",
|
||||
}
|
||||
FkActions = map[string]struct{}{
|
||||
"CASCADE": {},
|
||||
"RESTRICT": {},
|
||||
"SET NULL": {},
|
||||
"NO ACTION": {},
|
||||
"SET DEFAULT": {},
|
||||
}
|
||||
DefaultFunctions = map[string]struct{}{
|
||||
"CURRENT_TIMESTAMP": {},
|
||||
"now()": {},
|
||||
"uuid_generate_v4()": {},
|
||||
}
|
||||
AlgorithmMap = map[string]struct{}{
|
||||
"argon2": {},
|
||||
"bcrypt": {},
|
||||
"md5": {},
|
||||
"sha256": {},
|
||||
"sha512": {},
|
||||
}
|
||||
)
|
||||
|
||||
func ValidateIdent(name string) error {
|
||||
if !IdentifierRegex.MatchString(name) {
|
||||
return fmt.Errorf("invalid identifier: %s", name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidateType(name string) (string, error) {
|
||||
pg, ok := TypeMap[name]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("invalid type: %s", name)
|
||||
}
|
||||
return pg, nil
|
||||
}
|
||||
|
||||
func ValidateAction(act string) (string, error) {
|
||||
a := strings.ToUpper(act)
|
||||
if _, ok := FkActions[a]; !ok {
|
||||
return "", fmt.Errorf("invalid action: %s", act)
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func ValidateDefault(def string) (string, error) {
|
||||
if regexp.MustCompile(`^\d+(\.\d+)?$`).MatchString(def) || regexp.MustCompile(`^'.*'$`).MatchString(def) {
|
||||
return def, nil
|
||||
}
|
||||
if _, ok := DefaultFunctions[strings.ToLower(def)]; ok {
|
||||
return def, nil
|
||||
}
|
||||
return "", fmt.Errorf("invalid default: %s", def)
|
||||
}
|
||||
|
||||
func ValidateReferences(refs *schema.Reference) error {
|
||||
if err := ValidateIdent(refs.Table); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ValidateIdent(refs.Column); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidateAlgorithm(algo string) error {
|
||||
a := strings.ToUpper(algo)
|
||||
if _, ok := AlgorithmMap[a]; !ok {
|
||||
return fmt.Errorf("invalid algorithm: %s", algo)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidatePrimary(primary bool) error {
|
||||
if primary {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("primary is required")
|
||||
}
|
||||
|
||||
func ValidateUnique(unique bool) error {
|
||||
if unique {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("unique is required")
|
||||
}
|
||||
|
||||
func ValidateComment(comment *string) error {
|
||||
if comment == nil {
|
||||
return nil
|
||||
}
|
||||
return ValidateIdent(*comment)
|
||||
}
|
||||
|
||||
func QuoteIdent(name string) string {
|
||||
return `"` + strings.ReplaceAll(name, `"`, `""`) + `"`
|
||||
}
|
||||
Reference in New Issue
Block a user