Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f25b96f

Browse files
committed
fix(api): restrict auth audit events and correct login_success timing
- Limit global /api/events to admins via GetAllEvents; exclude null-project events from GetUserEvents so auth audit rows are not visible to all users - Log login_success only after the session cookie is set and MFA is complete - Audit login_fail when password login is disabled
1 parent 4eeb7a8 commit f25b96f

4 files changed

Lines changed: 14 additions & 5 deletions

File tree

api/auth.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package api
22

33
import (
44
"errors"
5+
"fmt"
56
"net/http"
67
"net/url"
78
"strings"
@@ -208,6 +209,8 @@ func verifySession(w http.ResponseWriter, r *http.Request) {
208209
return
209210
}
210211

212+
logAuthEvent(r, helpers.EventLogLoginSuccess, user.ID, fmt.Sprintf("User %s logged in", user.Username))
213+
211214
case db.SessionVerificationNone:
212215
w.WriteHeader(http.StatusNoContent)
213216
return

api/events.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ func getEvents(w http.ResponseWriter, r *http.Request, limit int) {
2828
}
2929

3030
events, err = helpers.Store(r).GetEvents(project.ID, db.RetrieveQueryParams{Count: limit})
31+
} else if user.Admin {
32+
events, err = helpers.Store(r).GetAllEvents(db.RetrieveQueryParams{Count: limit})
3133
} else {
3234
events, err = helpers.Store(r).GetUserEvents(user.ID, db.RetrieveQueryParams{Count: limit})
3335
}

api/login.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,6 @@ func createSession(w http.ResponseWriter, r *http.Request, user db.User, oidc bo
196196
return
197197
}
198198

199-
logAuthEvent(r, helpers.EventLogLoginSuccess, user.ID, fmt.Sprintf("User %s logged in", user.Username))
200-
201199
encoded, err := util.Cookie.Encode("semaphore", map[string]any{
202200
"user": user.ID,
203201
"session": newSession.ID,
@@ -225,6 +223,10 @@ func createSession(w http.ResponseWriter, r *http.Request, user db.User, oidc bo
225223
// it can still be used without TLS inside private networks.
226224
Secure: isSecureWebHost(),
227225
})
226+
227+
if verified {
228+
logAuthEvent(r, helpers.EventLogLoginSuccess, user.ID, fmt.Sprintf("User %s logged in", user.Username))
229+
}
228230
}
229231

230232
// isSecureWebHost reports whether Semaphore's public web host uses HTTPS, in
@@ -371,6 +373,7 @@ func login(w http.ResponseWriter, r *http.Request) {
371373
switch login.Method {
372374
case "password":
373375
if util.Config.PasswordLoginDisable {
376+
logAuthEvent(r, helpers.EventLogLoginFail, 0, fmt.Sprintf("Failed login attempt for %s", login.Auth))
374377
w.WriteHeader(http.StatusUnauthorized)
375378
return
376379
}
@@ -425,6 +428,7 @@ func login(w http.ResponseWriter, r *http.Request) {
425428

426429
if ldapUser == nil {
427430
if util.Config.PasswordLoginDisable {
431+
logAuthEvent(r, helpers.EventLogLoginFail, 0, fmt.Sprintf("Failed login attempt for %s", login.Auth))
428432
w.WriteHeader(http.StatusUnauthorized)
429433
return
430434
}
@@ -975,8 +979,8 @@ func oidcRedirect(w http.ResponseWriter, r *http.Request) {
975979
}
976980

977981
user, err := resolveExternalUser(helpers.Store(r), externalUserProfile{
978-
Type: db.IdentityTypeOidc,
979-
Provider: pid,
982+
Type: db.IdentityTypeOidc,
983+
Provider: pid,
980984
ExternalUID: claims.sub,
981985
Username: claims.username,
982986
Name: claims.name,

db/sql/event.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func (d *SqlDb) GetUserEvents(userID int, params db.RetrieveQueryParams) ([]db.E
6161
LeftJoin("project as p on event.project_id=p.id").
6262
OrderBy("id desc").
6363
LeftJoin("project__user as pu on pu.project_id=p.id").
64-
Where("p.id IS NULL or pu.user_id=?", userID)
64+
Where("event.project_id IS NOT NULL AND pu.user_id=?", userID)
6565

6666
return d.getEvents(q, params)
6767
}

0 commit comments

Comments
 (0)