feat(sql): SQL Injection

This commit is contained in:
Björn Benouarets
2025-11-06 16:44:28 +01:00
parent 10110071eb
commit 59d6c911f9
14 changed files with 430 additions and 483 deletions

120
sql/validate.go Normal file
View 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, `"`, `""`) + `"`
}