security: P0 fixes - SQL injection prevention + data race fix

- Add identifier validation for database names in PostgreSQL and MySQL
  - validateIdentifier() rejects names with invalid characters
  - quoteIdentifier() safely quotes identifiers with proper escaping
  - Max length: 63 chars (PostgreSQL), 64 chars (MySQL)
  - Only allows alphanumeric + underscores, must start with letter/underscore

- Fix data race in notification manager
  - Multiple goroutines were appending to shared error slice
  - Added errMu sync.Mutex to protect concurrent error collection

- Security improvements prevent:
  - SQL injection via malicious database names
  - CREATE DATABASE `foo`; DROP DATABASE production; --`
  - Race conditions causing lost or corrupted error data
This commit is contained in:
2026-01-07 09:45:13 +01:00
parent 63b16eee8b
commit 9d8a6e763e
4 changed files with 87 additions and 4 deletions

View File

@@ -69,6 +69,7 @@ func (m *Manager) NotifySync(ctx context.Context, event *Event) error {
m.mu.RUnlock()
var errors []error
var errMu sync.Mutex
var wg sync.WaitGroup
for _, n := range notifiers {
@@ -80,7 +81,9 @@ func (m *Manager) NotifySync(ctx context.Context, event *Event) error {
go func(notifier Notifier) {
defer wg.Done()
if err := notifier.Send(ctx, event); err != nil {
errMu.Lock()
errors = append(errors, fmt.Errorf("%s: %w", notifier.Name(), err))
errMu.Unlock()
}
}(n)
}