fix(security): phase 2 high-severity hardening
CI / test (pull_request) Successful in 4m31s
CI / lint (pull_request) Successful in 56s

- Push heartbeat accepts Authorization: Bearer header (query string deprecated)
- Gotify alerts use X-Gotify-Key header instead of token in URL
- Per-IP rate limiting on all API endpoints (token-bucket)
- /metrics gated behind cluster secret (UPTOP_METRICS_PUBLIC=true to opt out)
- Config export redacts passwords/tokens by default (redact_secrets=false to override)
- Fix rewritePlaceholders for 100+ SQL parameters
- Fix AddSiteReturningID/AddAlertReturningID race with LastInsertId/RETURNING
- HTTP server timeouts: read 30s, write 60s, idle 120s
This commit is contained in:
2026-05-25 21:15:33 -04:00
parent b43dfae98f
commit d30d1460bd
6 changed files with 226 additions and 51 deletions
+5 -7
View File
@@ -1,6 +1,9 @@
package store
import "database/sql"
import (
"database/sql"
"strconv"
)
type Dialect interface {
DriverName() string
@@ -13,8 +16,6 @@ type Dialect interface {
UpsertNodeSQL() string
}
// rewritePlaceholders converts ? markers to $1, $2, etc. for Postgres.
// For SQLite (or any dialect not needing rewrite), returns the input unchanged.
func rewritePlaceholders(query string, dollarStyle bool) string {
if !dollarStyle {
return query
@@ -25,10 +26,7 @@ func rewritePlaceholders(query string, dollarStyle bool) string {
if query[i] == '?' {
n++
buf = append(buf, '$')
if n >= 10 {
buf = append(buf, byte('0'+n/10))
}
buf = append(buf, byte('0'+n%10))
buf = append(buf, []byte(strconv.Itoa(n))...)
} else {
buf = append(buf, query[i])
}