Security Audit Fixes: Session fixation prevention, SameSite cookies, audit log redaction, backup integrity, Docker hardening, error sanitization, rate limiting, trusted proxies, and config hardening
This commit is contained in:
parent
7fc90524b5
commit
b587fb87a9
18 changed files with 987 additions and 87 deletions
|
|
@ -39,6 +39,11 @@ func (r *SessionRepository) Delete(id string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (r *SessionRepository) DeleteByUserID(userID string) error {
|
||||
_, err := r.db.Exec(`DELETE FROM sessions WHERE user_id = ?`, userID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *SessionRepository) DeleteExpired() error {
|
||||
_, err := r.db.Exec(`DELETE FROM sessions WHERE expires_at < ?`, time.Now())
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
"time"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
|
|
@ -29,6 +30,10 @@ func New(path string) (*DB, error) {
|
|||
}
|
||||
|
||||
db.SetMaxOpenConns(1)
|
||||
// Restrict database file permissions (0600) to prevent unauthorized access
|
||||
if err := os.Chmod(path, 0o600); err != nil {
|
||||
log.Printf("warning: could not set db file permissions: %v", err)
|
||||
}
|
||||
return &DB{db}, nil
|
||||
}
|
||||
|
||||
|
|
@ -69,6 +74,27 @@ func (d *DB) Migrate() error {
|
|||
)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_backups_filename ON backups(filename)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_backups_created_at ON backups(created_at)`,
|
||||
`CREATE TABLE IF NOT EXISTS audit_log (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
username TEXT NOT NULL,
|
||||
role TEXT NOT NULL,
|
||||
action TEXT NOT NULL,
|
||||
resource_type TEXT NOT NULL,
|
||||
resource_name TEXT,
|
||||
provider TEXT,
|
||||
source_file TEXT,
|
||||
content_hash TEXT,
|
||||
timestamp TEXT NOT NULL,
|
||||
result TEXT NOT NULL,
|
||||
error_category TEXT,
|
||||
rollback_occurred INTEGER NOT NULL DEFAULT 0,
|
||||
error_message TEXT
|
||||
)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_audit_log_user_id ON audit_log(user_id)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_audit_log_timestamp ON audit_log(timestamp)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_audit_log_action ON audit_log(action)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_audit_log_result ON audit_log(result)`,
|
||||
}
|
||||
|
||||
for _, q := range queries {
|
||||
|
|
@ -89,14 +115,17 @@ func (d *DB) ensureAdminUser() error {
|
|||
|
||||
if count == 0 {
|
||||
// Default admin: admin / changeme (bcrypt hash) — development-only
|
||||
// Generate random UUID for admin user ID (not predictable)
|
||||
id := uuid.V4().String()
|
||||
hash := "$2a$10$KsL.67hxLy.jwc50Uk7b3.dEmO1LNE3atnfUjNskAKlh9raiug4ju"
|
||||
_, err = d.Exec(
|
||||
`INSERT INTO users (id, username, email, password_hash, role) VALUES (?, ?, ?, ?, ?)`,
|
||||
"admin-uuid-0000-0000-000000000001", "admin", "admin@localhost", hash, "admin",
|
||||
id, "admin", "admin@localhost", hash, "admin",
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create admin user: %w", err)
|
||||
}
|
||||
log.Println("Default admin user created with generated UUID (development-only)")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -114,12 +143,14 @@ func (d *DB) EnsureAdminPasswordViaEnv(envPassword string, devMode bool) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("hash admin password: %w", err)
|
||||
}
|
||||
// Generate random UUID for admin user ID (not predictable)
|
||||
id := uuid.V4().String()
|
||||
// Upsert admin user
|
||||
_, err = d.Exec(`
|
||||
INSERT INTO users (id, username, email, password_hash, role)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
ON CONFLICT(username) DO UPDATE SET password_hash=excluded.password_hash, updated_at=CURRENT_TIMESTAMP
|
||||
`, "admin-uuid-0000-0000-000000000001", "admin", "admin@localhost", string(hash), "admin")
|
||||
`, id, "admin", "admin@localhost", string(hash), "admin")
|
||||
if err != nil {
|
||||
return fmt.Errorf("upsert admin via env: %w", err)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue