security: remediate all P0-P2 audit findings (12 tasks)
P0 fixes: - WebSocket origin checking (reject untrusted origins) - WS session token moved from URL query param to first message frame - WebAuthn login cookie now uses Secure flag via shared SetSessionCookie - PostgreSQL sslmode configurable via POSTGRES_SSLMODE env (default: require) - Fixed DatabaseDSN to use real password instead of masked placeholder P1 fixes: - Per-IP rate limiting middleware (auth: 5 req/s, invites: 2 req/s) - Security headers on all responses (CSP, X-Frame-Options, nosniff, etc.) - WS broadcasts scoped to server members (prevents cross-server data leak) - Webhook tokens stored as SHA-256 hashes (not plaintext) P2 fixes: - CSRF protection via Origin header validation on state-changing requests - MANAGE_CHANNELS permission enforced on channel update/delete - Upload validation: 25MB limit, extension allowlist, server-side MIME check - File serve: path traversal protection + Content-Disposition: attachment Files: 23 changed, +499/-100. Builds clean (go build, go vet, npm build). Zero CVEs (govulncheck, npm audit).
This commit is contained in:
@@ -114,7 +114,7 @@ func (h *Handler) requireMessageAccess(w http.ResponseWriter, r *http.Request, m
|
||||
// @Router /messages/{messageID}/reactions [post]
|
||||
func (h *Handler) Add(w http.ResponseWriter, r *http.Request) {
|
||||
messageID := chi.URLParam(r, "messageID")
|
||||
userID, channelID, _, ok := h.requireMessageAccess(w, r, messageID)
|
||||
userID, channelID, serverID, ok := h.requireMessageAccess(w, r, messageID)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
@@ -145,7 +145,7 @@ func (h *Handler) Add(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
reaction.CreatedAt = createdAt.String
|
||||
|
||||
h.hub.BroadcastEvent(gateway.Event{
|
||||
h.hub.BroadcastToServer(serverID, gateway.Event{
|
||||
Type: gateway.EventReactionAdd,
|
||||
Data: map[string]interface{}{
|
||||
"reaction": reaction,
|
||||
@@ -173,7 +173,7 @@ func (h *Handler) Add(w http.ResponseWriter, r *http.Request) {
|
||||
func (h *Handler) Remove(w http.ResponseWriter, r *http.Request) {
|
||||
messageID := chi.URLParam(r, "messageID")
|
||||
emoji := chi.URLParam(r, "emoji")
|
||||
userID, channelID, _, ok := h.requireMessageAccess(w, r, messageID)
|
||||
userID, channelID, serverID, ok := h.requireMessageAccess(w, r, messageID)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
@@ -196,7 +196,7 @@ func (h *Handler) Remove(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
h.hub.BroadcastEvent(gateway.Event{
|
||||
h.hub.BroadcastToServer(serverID, gateway.Event{
|
||||
Type: gateway.EventReactionRemove,
|
||||
Data: map[string]interface{}{
|
||||
"user_id": userID,
|
||||
|
||||
Reference in New Issue
Block a user