From 5e81bed7097f182cb99379fcdc074913e51d2db8 Mon Sep 17 00:00:00 2001 From: Yumechi Date: Sat, 4 Jul 2026 14:46:35 +0800 Subject: [PATCH] fix(security): check app ownership in security endpoint --- api/application.go | 5 +++++ api/application_test.go | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/api/application.go b/api/application.go index 1cfc8c25..4d3dca41 100644 --- a/api/application.go +++ b/api/application.go @@ -335,6 +335,11 @@ func (a *ApplicationAPI) UpdateApplicationSecurity(ctx *gin.Context) { if success := successOrAbort(ctx, 500, err); !success { return } + if app == nil || app.UserID != auth.GetUserID(ctx) { + ctx.AbortWithError(404, fmt.Errorf("app with id %d doesn't exists", id)) + return + } + action := model.SecurityUpdateAction{} response := model.SecurityUpdateActionResponse{} if err := ctx.Bind(&action); err == nil { diff --git a/api/application_test.go b/api/application_test.go index 238c8314..13591546 100644 --- a/api/application_test.go +++ b/api/application_test.go @@ -187,6 +187,23 @@ func (s *ApplicationSuite) Test_UpdateApplicationSecurity_isNoOpIfNilAction() { assert.Equal(s.T(), oldToken, newToken) } +func (s *ApplicationSuite) Test_UpdateApplicationSecurity_expectNotFoundOnCurrentUserIsNotOwner() { + s.db.User(2) + s.db.User(5).App(1) + test.WithUser(s.ctx, 2) + + oldToken, err := s.db.GetApplicationByID(1) + assert.NoError(s.T(), err) + s.ctx.Request = httptest.NewRequest("PUT", "/application/1/security", bytes.NewBufferString(`{}`)) + s.ctx.Request.Header.Set("Content-Type", "application/json") + s.ctx.Params = gin.Params{{Key: "id", Value: "1"}} + s.a.UpdateApplicationSecurity(s.ctx) + assert.Equal(s.T(), 404, s.recorder.Code) + newToken, err := s.db.GetApplicationByID(1) + assert.NoError(s.T(), err) + assert.Equal(s.T(), oldToken, newToken) +} + func (s *ApplicationSuite) Test_DeleteApplication_expectNotFoundOnCurrentUserIsNotOwner() { s.db.User(2) s.db.User(5).App(5)