mirror of
https://github.com/J3vb/OwnCord.git
synced 2026-09-03 03:50:00 +03:00
Security audit across all 11 sections (AUTH-001 through DATA-001) found 0 critical, 1 high, 7 medium, 15 low issues. This commit addresses: - Add json:"-" to User.PasswordHash, User.TOTPSecret, Session.TokenHash to prevent accidental serialization of sensitive fields (M7) - Add X-Content-Type-Options: nosniff to file serve responses (M5) - Apply owner-only guard to backup list endpoint for consistency (M6) - Persist rate-limit lockouts to SQLite so they survive restarts (M2) - Normalize DM non-participant responses to 404 to prevent oracle (L3) - Add explicit per-entry expiry check in partial auth Lookup/Consume (L1) - Truncate unknown WS message type to 64 chars before echo (L6) - Rate-limit ping handler to 2/sec per user (L7) - Replace raw error strings in update handlers with generic messages (L15) - Update 4 tests to match new 404 behavior for DM non-participant
55 lines
1.5 KiB
Go
55 lines
1.5 KiB
Go
package db
|
|
|
|
import "time"
|
|
|
|
// UpsertLockout inserts or replaces a rate-limit lockout entry.
|
|
func (d *DB) UpsertLockout(key string, expiresAt time.Time) error {
|
|
_, err := d.sqlDB.Exec(
|
|
`INSERT OR REPLACE INTO rate_lockouts (key, expires_at) VALUES (?, ?)`,
|
|
key, expiresAt.UTC().Format(time.RFC3339),
|
|
)
|
|
return err
|
|
}
|
|
|
|
// LoadActiveLockouts returns all lockouts that have not yet expired as
|
|
// parallel slices of keys and expiry times.
|
|
func (d *DB) LoadActiveLockouts() (keys []string, expiresAt []time.Time, err error) {
|
|
rows, err := d.sqlDB.Query(
|
|
`SELECT key, expires_at FROM rate_lockouts WHERE expires_at > ?`,
|
|
time.Now().UTC().Format(time.RFC3339),
|
|
)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
defer rows.Close() //nolint:errcheck
|
|
|
|
for rows.Next() {
|
|
var key, expiresStr string
|
|
if err := rows.Scan(&key, &expiresStr); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
t, parseErr := time.Parse(time.RFC3339, expiresStr)
|
|
if parseErr != nil {
|
|
continue // skip unparseable rows
|
|
}
|
|
keys = append(keys, key)
|
|
expiresAt = append(expiresAt, t)
|
|
}
|
|
return keys, expiresAt, rows.Err()
|
|
}
|
|
|
|
// CleanupExpiredLockouts removes lockout rows whose expiry has passed.
|
|
func (d *DB) CleanupExpiredLockouts() error {
|
|
_, err := d.sqlDB.Exec(
|
|
`DELETE FROM rate_lockouts WHERE expires_at <= ?`,
|
|
time.Now().UTC().Format(time.RFC3339),
|
|
)
|
|
return err
|
|
}
|
|
|
|
// DeleteLockout removes a single lockout entry.
|
|
func (d *DB) DeleteLockout(key string) error {
|
|
_, err := d.sqlDB.Exec(`DELETE FROM rate_lockouts WHERE key = ?`, key)
|
|
return err
|
|
}
|