fix(security): address validation review comments - mutex safety and issuer normalization

Agent-Logs-Url: https://github.com/bitechdev/ResolveSpec/sessions/e886b781-c910-425f-aa6f-06d13c46dcc7

Co-authored-by: warkanum <208308+warkanum@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-04-09 14:07:45 +00:00
committed by GitHub
parent 850ad2b2ab
commit ca0545e144
2 changed files with 20 additions and 6 deletions

View File

@@ -1545,6 +1545,8 @@ BEGIN
'username', u.username,
'email', u.email,
'user_level', u.user_level,
-- NULLIF converts empty string to NULL; string_to_array(NULL) returns NULL;
-- to_jsonb(NULL) returns NULL; COALESCE then returns '[]' for NULL/empty roles.
'roles', COALESCE(to_jsonb(string_to_array(NULLIF(u.roles, ''), ',')), '[]'::jsonb),
'exp', EXTRACT(EPOCH FROM s.expires_at)::bigint,
'iat', EXTRACT(EPOCH FROM s.created_at)::bigint

View File

@@ -128,8 +128,8 @@ func NewOAuthServer(cfg OAuthServerConfig, auth *DatabaseAuthenticator) *OAuthSe
if cfg.AuthCodeTTL == 0 {
cfg.AuthCodeTTL = 2 * time.Minute
}
// Normalize issuer: trim trailing slash to ensure consistent endpoint URL construction.
cfg.Issuer = strings.TrimRight(cfg.Issuer, "/")
// Normalize issuer: remove trailing slash to ensure consistent endpoint URL construction.
cfg.Issuer = strings.TrimSuffix(cfg.Issuer, "/")
s := &OAuthServer{
cfg: cfg,
auth: auth,
@@ -704,9 +704,17 @@ func (s *OAuthServer) revokeHandler(w http.ResponseWriter, r *http.Request) {
if s.auth != nil {
s.auth.OAuthRevokeToken(r.Context(), token) //nolint:errcheck
} else if len(s.providers) > 0 {
} else {
// In external-provider-only mode, attempt revocation via the first provider's auth.
s.providers[0].auth.OAuthRevokeToken(r.Context(), token) //nolint:errcheck
s.mu.RLock()
var providerAuth *DatabaseAuthenticator
if len(s.providers) > 0 {
providerAuth = s.providers[0].auth
}
s.mu.RUnlock()
if providerAuth != nil {
providerAuth.OAuthRevokeToken(r.Context(), token) //nolint:errcheck
}
}
w.WriteHeader(http.StatusOK)
}
@@ -735,8 +743,12 @@ func (s *OAuthServer) introspectHandler(w http.ResponseWriter, r *http.Request)
// Resolve the authenticator to use: prefer the primary auth, then the first provider's auth.
authToUse := s.auth
if authToUse == nil && len(s.providers) > 0 {
authToUse = s.providers[0].auth
if authToUse == nil {
s.mu.RLock()
if len(s.providers) > 0 {
authToUse = s.providers[0].auth
}
s.mu.RUnlock()
}
if authToUse == nil {
w.Write([]byte(`{"active":false}`)) //nolint:errcheck