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

View File

@@ -2,9 +2,6 @@ package schema
import (
"encoding/json"
"fmt"
"git.secnex.io/secnex/pgson/utils"
)
type Table struct {
@@ -32,19 +29,6 @@ type Reference struct {
OnUpdate string `json:"on_update"`
}
var fieldTypeToSQLType = map[string]string{
"string": "VARCHAR",
"int": "INTEGER",
"float": "FLOAT",
"bool": "BOOLEAN",
"date": "DATE",
"time": "TIME",
"datetime": "TIMESTAMP",
"uuid": "UUID",
"json": "JSONB",
"hash": "VARCHAR",
}
func NewTable(data []byte) (*Table, error) {
var table Table
err := json.Unmarshal(data, &table)
@@ -57,82 +41,3 @@ func NewTable(data []byte) (*Table, error) {
func (t *Table) JSON() ([]byte, error) {
return json.Marshal(t)
}
func (f *Field) SQL() string {
if !utils.IsValidIdentifier(f.Name) {
return ""
}
sqlType := fieldTypeToSQLType[f.Type]
if sqlType == "" {
return ""
}
quotedName := utils.SQLQuoteIdent(f.Name)
sql := fmt.Sprintf("%s %s", quotedName, sqlType)
if f.Nullable != nil && !*f.Nullable {
sql += " NOT NULL"
}
if f.Primary != nil && *f.Primary {
sql += " PRIMARY KEY"
if f.Default == nil && f.Type == "uuid" {
sql += " DEFAULT uuid_generate_v4()"
}
}
if f.Unique != nil && *f.Unique {
sql += " UNIQUE"
}
if f.Default != nil && f.Primary == nil {
def := *f.Default
if utils.IsValidDefault(def) {
switch {
case utils.IsValidDefault(def):
if utils.IsValidDefault(def) && (def == "CURRENT_TIMESTAMP" || def == "now()" || def == "uuid_generate_v4()") {
sql += fmt.Sprintf(" DEFAULT %s", def)
} else {
sql += fmt.Sprintf(" DEFAULT %s", utils.SQLQuoteValue(def))
}
}
} else {
return ""
}
}
if f.References != nil {
ref := f.References
if !utils.IsValidIdentifier(ref.Table) || !utils.IsValidIdentifier(ref.Column) {
return ""
}
sql += fmt.Sprintf(" REFERENCES %s(%s)", utils.SQLQuoteIdent(ref.Table), utils.SQLQuoteIdent(ref.Column))
if ref.OnDelete != "" {
action, err := utils.SanitizeOnAction(ref.OnDelete)
if err == nil && action != "" {
sql += fmt.Sprintf(" ON DELETE %s", action)
}
}
if ref.OnUpdate != "" {
action, err := utils.SanitizeOnAction(ref.OnUpdate)
if err == nil && action != "" {
sql += fmt.Sprintf(" ON UPDATE %s", action)
}
}
}
return sql
}
func (f *Field) SQLReferences() string {
if f.References == nil {
return ""
}
ref := f.References
if !utils.IsValidIdentifier(ref.Table) || !utils.IsValidIdentifier(ref.Column) {
return ""
}
return fmt.Sprintf(" REFERENCES %s(%s)", utils.SQLQuoteIdent(ref.Table), utils.SQLQuoteIdent(ref.Column))
}