CVE-2023-4815: Missing Authentication for Critical Function (CWE-306)
value: Missing Authentication for Critical Function in GitHub repository answerdev/answer prior to v1.1.3.
CWE description: The product does not perform any authentication for functionality that requires a provable user identity or consumes a significant amount of resources.
CVSS v3 base score: 8.8
Published: 2023-09-07T07:15Z
Repository: https://github.com/answerdev/answer
Language: Go
Files changed: internal/base/middleware/auth.go, internal/repo/activity/answer_repo.go
Commit date: 2023-08-29 11:39:51 +0800
Commit message: fix(answer): fix incorrect notification's triggerUserID when cancel accepted answer

Diff: diff --git a/internal/base/middleware/auth.go b/internal/base/middleware/auth.go
index 5532a479c..a51b44de6 100644
--- a/internal/base/middleware/auth.go
+++ b/internal/base/middleware/auth.go
@@ -124,11 +124,11 @@ func (am *AuthUserMiddleware) AdminAuth() gin.HandlerFunc {
 			handler.HandleResponse(ctx, errors.Unauthorized(reason.UnauthorizedError), nil)
 			ctx.Abort()
 			return
 		}
 		userInfo, err := am.authService.GetAdminUserCacheInfo(ctx, token)
-		if err != nil {
+		if err != nil || userInfo == nil {
 			handler.HandleResponse(ctx, errors.Forbidden(reason.UnauthorizedError), nil)
 			ctx.Abort()
 			return
 		}
 		if userInfo != nil {
diff --git a/internal/repo/activity/answer_repo.go b/internal/repo/activity/answer_repo.go
index fa4aacd0b..02ae66f04 100644
--- a/internal/repo/activity/answer_repo.go
+++ b/internal/repo/activity/answer_repo.go
@@ -53,11 +53,10 @@ func (ar *AnswerActivityRepo) SaveAcceptAnswerActivity(ctx context.Context, op *
 	}
 	if noNeedToDo {
 		return nil
 	}
 
-	ar.data.DB.ShowSQL(true)
 	// save activity
 	_, err = ar.data.DB.Transaction(func(session *xorm.Session) (result any, err error) {
 		session = session.Context(ctx)
 
 		userInfoMapping, err := ar.acquireUserInfo(session, op.GetUserIDs())
@@ -309,16 +308,15 @@ func (ar *AnswerActivityRepo) sendAcceptAnswerNotification(
 	for _, act := range op.Activities {
 		msg := &schema.NotificationMsg{
 			Type:           schema.NotificationTypeAchievement,
 			ObjectID:       op.AnswerObjectID,
 			ReceiverUserID: act.ActivityUserID,
+			TriggerUserID:  act.TriggerUserID,
 		}
 		if act.ActivityUserID == op.QuestionUserID {
-			msg.TriggerUserID = op.AnswerUserID
 			msg.ObjectType = constant.AnswerObjectType
 		} else {
-			msg.TriggerUserID = op.QuestionUserID
 			msg.ObjectType = constant.AnswerObjectType
 		}
 		if msg.TriggerUserID != msg.ReceiverUserID {
 			ar.notificationQueueService.Send(ctx, msg)
 		}
@@ -327,13 +325,13 @@ func (ar *AnswerActivityRepo) sendAcceptAnswerNotification(
 	for _, act := range op.Activities {
 		msg := &schema.NotificationMsg{
 			ReceiverUserID: act.ActivityUserID,
 			Type:           schema.NotificationTypeInbox,
 			ObjectID:       op.AnswerObjectID,
+			TriggerUserID:  op.TriggerUserID,
 		}
 		if act.ActivityUserID != op.QuestionUserID {
-			msg.TriggerUserID = op.QuestionUserID
 			msg.ObjectType = constant.AnswerObjectType
 			msg.NotificationAction = constant.NotificationAcceptAnswer
 			ar.notificationQueueService.Send(ctx, msg)
 		}
 	}
@@ -341,19 +339,18 @@ func (ar *AnswerActivityRepo) sendAcceptAnswerNotification(
 
 func (ar *AnswerActivityRepo) sendCancelAcceptAnswerNotification(
 	ctx context.Context, op *schema.AcceptAnswerOperationInfo) {
 	for _, act := range op.Activities {
 		msg := &schema.NotificationMsg{
+			TriggerUserID:  act.TriggerUserID,
 			ReceiverUserID: act.ActivityUserID,
 			Type:           schema.NotificationTypeAchievement,
 			ObjectID:       op.AnswerObjectID,
 		}
 		if act.ActivityUserID == op.QuestionObjectID {
-			msg.TriggerUserID = op.AnswerObjectID
 			msg.ObjectType = constant.QuestionObjectType
 		} else {
-			msg.TriggerUserID = op.QuestionObjectID
 			msg.ObjectType = constant.AnswerObjectType
 		}
 		if msg.TriggerUserID != msg.ReceiverUserID {
 			ar.notificationQueueService.Send(ctx, msg)
 		}

Vulnerable code: 		if err != nil {
	ar.data.DB.ShowSQL(true)
			msg.TriggerUserID = op.AnswerUserID
			msg.TriggerUserID = op.QuestionUserID
			msg.TriggerUserID = op.QuestionUserID
			msg.TriggerUserID = op.AnswerObjectID
			msg.TriggerUserID = op.QuestionObjectID
Fixed code: 		if err != nil || userInfo == nil {
			TriggerUserID:  act.TriggerUserID,
			TriggerUserID:  op.TriggerUserID,
			TriggerUserID:  act.TriggerUserID,