VYPR
Critical severityNVD Advisory· Published Feb 8, 2022· Updated Aug 4, 2024

CVE-2021-45327

CVE-2021-45327

Description

Gitea before 1.11.2 is affected by Trusting HTTP Permission Methods on the Server Side when referencing the vulnerable admin or user API. which could let a remote malisious user execute arbitrary code.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Gitea before v1.11.2 trusts HTTP GET requests for admin/user API actions, allowing a remote attacker to execute arbitrary code.

Vulnerability

Gitea versions before 1.11.2 are affected by a vulnerability in the admin and user API endpoints that trust HTTP GET methods for operations that should require a POST request. This issue, identified as CVE-2021-45327 in references [1], allows a remote attacker to trigger server-side operations, including administrative actions, through simple GET requests [1][2][4]. The vulnerable endpoints include the admin dashboard operations, as shown by the commit that changed these GET-based actions to POST [2]. All Gitea instances running versions prior to 1.11.2 are affected [1].

Exploitation

An attacker with network access to the Gitea instance can exploit this by sending crafted HTTP GET requests to vulnerable admin or user API endpoints [1]. No authentication or special privileges are required if the attacker is able to reach the server over the network. The commit history shows that actions such as runOp were previously handled via GET, and the fix changed them to POST to require CSRF protection and proper HTTP method enforcement [2][4]. An attacker could chain these GET requests to trigger operations like user creation, repository deletion, or other administrative functions.

Impact

Successful exploitation allows a remote, unauthenticated attacker to execute arbitrary code on the Gitea server [1]. The vulnerable API endpoints may allow the attacker to perform privileged actions without proper authorization. This can lead to complete compromise of the Gitea instance, including data disclosure, file modification, and denial of service. The CVSS score for this CVE is not yet provided by NVD, but the impact is severe due to the potential for remote code execution in the admin context [1].

Mitigation

The vulnerability is fixed in Gitea version 1.11.2 [1][2]. The fix involved changing the HTTP methods for admin dashboard operations from GET to POST, as documented in pull request #10462 and commit ed664a9e1dae4d4660e60c981173bbc5102e69ea [2][4]. Users should upgrade to Gitea 1.11.2 or later immediately. No workaround is available for older versions. There is no indication that this CVE is listed in CISA's Known Exploited Vulnerabilities (KEV) catalog.

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/go-gitea/giteaGo
< 1.11.21.11.2

Affected products

3

Patches

3
6f5656ab0ebe

Logout POST action (#10582) (#10585)

https://github.com/go-gitea/giteaJohn OlheiserMar 3, 2020via ghsa
4 files changed · +6 3
  • integrations/signout_test.go+1 1 modified
    @@ -14,7 +14,7 @@ func TestSignOut(t *testing.T) {
     
     	session := loginUser(t, "user2")
     
    -	req := NewRequest(t, "GET", "/user/logout")
    +	req := NewRequest(t, "POST", "/user/logout")
     	session.MakeRequest(t, req, http.StatusFound)
     
     	// try to view a private repo, should fail
    
  • routers/routes/routes.go+1 1 modified
    @@ -399,7 +399,7 @@ func RegisterRoutes(m *macaron.Macaron) {
     		m.Post("/recover_account", user.ResetPasswdPost)
     		m.Get("/forgot_password", user.ForgotPasswd)
     		m.Post("/forgot_password", user.ForgotPasswdPost)
    -		m.Get("/logout", user.SignOut)
    +		m.Post("/logout", user.SignOut)
     	})
     	// ***** END: User *****
     
    
  • templates/base/head_navbar.tmpl+1 1 modified
    @@ -109,7 +109,7 @@
     					{{end}}
     
     					<div class="divider"></div>
    -					<a class="item" href="{{AppSubUrl}}/user/logout">
    +					<a class="item link-action" href data-url="{{AppSubUrl}}/user/logout" data-redirect="{{AppSubUrl}}/">
     						<i class="octicon octicon-sign-out"></i>
     						{{.i18n.Tr "sign_out"}}<!-- Sign Out -->
     					</a>
    
  • web_src/js/index.js+3 0 modified
    @@ -2740,11 +2740,14 @@ function showAddAllPopup() {
     
     function linkAction() {
       const $this = $(this);
    +  const redirect = $this.data('redirect');
       $.post($this.data('url'), {
         _csrf: csrf
       }).done((data) => {
         if (data.redirect) {
           window.location.href = data.redirect;
    +    } else if (redirect) {
    +      window.location.href = redirect;
         } else {
           window.location.reload();
         }
    
ed664a9e1dae

Change admin dashboard to POST (#10465) (#10466)

https://github.com/go-gitea/giteaJohn OlheiserFeb 25, 2020via ghsa
5 files changed · +81 55
  • modules/auth/admin.go+10 0 modified
    @@ -47,3 +47,13 @@ type AdminEditUserForm struct {
     func (f *AdminEditUserForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
     	return validate(errs, ctx.Data, f, ctx.Locale)
     }
    +
    +// AdminDashboardForm form for admin dashboard operations
    +type AdminDashboardForm struct {
    +	Op int `binding:"required"`
    +}
    +
    +// Validate validates form fields
    +func (f *AdminDashboardForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
    +	return validate(errs, ctx.Data, f, ctx.Locale)
    +}
    
  • routers/admin/admin.go+19 11 modified
    @@ -16,6 +16,7 @@ import (
     	"time"
     
     	"code.gitea.io/gitea/models"
    +	"code.gitea.io/gitea/modules/auth"
     	"code.gitea.io/gitea/modules/base"
     	"code.gitea.io/gitea/modules/context"
     	"code.gitea.io/gitea/modules/cron"
    @@ -30,7 +31,6 @@ import (
     
     	"gitea.com/macaron/macaron"
     	"gitea.com/macaron/session"
    -	"github.com/unknwon/com"
     )
     
     const (
    @@ -144,14 +144,28 @@ func Dashboard(ctx *context.Context) {
     	ctx.Data["Title"] = ctx.Tr("admin.dashboard")
     	ctx.Data["PageIsAdmin"] = true
     	ctx.Data["PageIsAdminDashboard"] = true
    +	ctx.Data["Stats"] = models.GetStatistic()
    +	// FIXME: update periodically
    +	updateSystemStatus()
    +	ctx.Data["SysStatus"] = sysStatus
    +	ctx.HTML(200, tplDashboard)
    +}
    +
    +// DashboardPost run an admin operation
    +func DashboardPost(ctx *context.Context, form auth.AdminDashboardForm) {
    +	ctx.Data["Title"] = ctx.Tr("admin.dashboard")
    +	ctx.Data["PageIsAdmin"] = true
    +	ctx.Data["PageIsAdminDashboard"] = true
    +	ctx.Data["Stats"] = models.GetStatistic()
    +	updateSystemStatus()
    +	ctx.Data["SysStatus"] = sysStatus
     
     	// Run operation.
    -	op, _ := com.StrTo(ctx.Query("op")).Int()
    -	if op > 0 {
    +	if form.Op > 0 {
     		var err error
     		var success string
     
    -		switch Operation(op) {
    +		switch Operation(form.Op) {
     		case cleanInactivateUser:
     			success = ctx.Tr("admin.dashboard.delete_inactivate_accounts_success")
     			err = models.DeleteInactivateUsers()
    @@ -189,15 +203,9 @@ func Dashboard(ctx *context.Context) {
     		} else {
     			ctx.Flash.Success(success)
     		}
    -		ctx.Redirect(setting.AppSubURL + "/admin")
    -		return
     	}
     
    -	ctx.Data["Stats"] = models.GetStatistic()
    -	// FIXME: update periodically
    -	updateSystemStatus()
    -	ctx.Data["SysStatus"] = sysStatus
    -	ctx.HTML(200, tplDashboard)
    +	ctx.Redirect(setting.AppSubURL + "/admin")
     }
     
     // SendTestMail send test mail to confirm mail service is OK
    
  • routers/routes/routes.go+1 0 modified
    @@ -408,6 +408,7 @@ func RegisterRoutes(m *macaron.Macaron) {
     	// ***** START: Admin *****
     	m.Group("/admin", func() {
     		m.Get("", adminReq, admin.Dashboard)
    +		m.Post("", adminReq, bindIgnErr(auth.AdminDashboardForm{}), admin.DashboardPost)
     		m.Get("/config", admin.Config)
     		m.Post("/config/test_mail", admin.SendTestMail)
     		m.Group("/monitor", func() {
    
  • templates/admin/dashboard.tmpl+47 44 modified
    @@ -15,50 +15,53 @@
     			{{.i18n.Tr "admin.dashboard.operations"}}
     		</h4>
     		<div class="ui attached table segment">
    -			<table class="ui very basic table">
    -				<tbody>
    -					<tr>
    -						<td>{{.i18n.Tr "admin.dashboard.delete_inactivate_accounts"}}</td>
    -						<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=1">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
    -					</tr>
    -					<tr>
    -						<td>{{.i18n.Tr "admin.dashboard.delete_repo_archives"}}</td>
    -						<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=2">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
    -					</tr>
    -					<tr>
    -						<td>{{.i18n.Tr "admin.dashboard.delete_missing_repos"}}</td>
    -						<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=3">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
    -					</tr>
    -					<tr>
    -						<td>{{.i18n.Tr "admin.dashboard.git_gc_repos"}}</td>
    -						<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=4">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
    -					</tr>
    -					<tr>
    -						<td>{{.i18n.Tr "admin.dashboard.resync_all_sshkeys"}}</td>
    -						<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=5">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
    -					</tr>
    -					<tr>
    -						<td>{{.i18n.Tr "admin.dashboard.resync_all_hooks"}}</td>
    -						<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=6">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
    -					</tr>
    -					<tr>
    -						<td>{{.i18n.Tr "admin.dashboard.reinit_missing_repos"}}</td>
    -						<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=7">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
    -					</tr>
    -					<tr>
    -						<td>{{.i18n.Tr "admin.dashboard.sync_external_users"}}</td>
    -						<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=8">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
    -					</tr>
    -					<tr>
    -						<td>{{.i18n.Tr "admin.dashboard.git_fsck"}}</td>
    -						<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=9">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
    -					</tr>
    -					<tr>
    -						<td>{{.i18n.Tr "admin.dashboard.delete_generated_repository_avatars"}}</td>
    -						<td><i class="fa fa-caret-square-o-right"></i> <a href="{{AppSubUrl}}/admin?op=10">{{.i18n.Tr "admin.dashboard.operation_run"}}</a></td>
    -					</tr>
    -				</tbody>
    -			</table>
    +			<form method="post" action="{{AppSubUrl}}/admin">
    +				{{.CsrfTokenHtml}}
    +				<table class="ui very basic table">
    +					<tbody>
    +						<tr>
    +							<td>{{.i18n.Tr "admin.dashboard.delete_inactivate_accounts"}}</td>
    +							<td><button type="submit" class="ui green button" name="op" value="1"><i class="fa fa-caret-square-o-right"></i> {{.i18n.Tr "admin.dashboard.operation_run"}}</button></td>
    +						</tr>
    +						<tr>
    +							<td>{{.i18n.Tr "admin.dashboard.delete_repo_archives"}}</td>
    +							<td><button type="submit" class="ui green button" name="op" value="2"><i class="fa fa-caret-square-o-right"></i> {{.i18n.Tr "admin.dashboard.operation_run"}}</button></td>
    +						</tr>
    +						<tr>
    +							<td>{{.i18n.Tr "admin.dashboard.delete_missing_repos"}}</td>
    +							<td><button type="submit" class="ui green button" name="op" value="3"><i class="fa fa-caret-square-o-right"></i> {{.i18n.Tr "admin.dashboard.operation_run"}}</button></td>
    +						</tr>
    +						<tr>
    +							<td>{{.i18n.Tr "admin.dashboard.git_gc_repos"}}</td>
    +							<td><button type="submit" class="ui green button" name="op" value="4"><i class="fa fa-caret-square-o-right"></i> {{.i18n.Tr "admin.dashboard.operation_run"}}</button></td>
    +						</tr>
    +						<tr>
    +							<td>{{.i18n.Tr "admin.dashboard.resync_all_sshkeys"}}</td>
    +							<td><button type="submit" class="ui green button" name="op" value="5"><i class="fa fa-caret-square-o-right"></i> {{.i18n.Tr "admin.dashboard.operation_run"}}</button></td>
    +						</tr>
    +						<tr>
    +							<td>{{.i18n.Tr "admin.dashboard.resync_all_hooks"}}</td>
    +							<td><button type="submit" class="ui green button" name="op" value="6"><i class="fa fa-caret-square-o-right"></i> {{.i18n.Tr "admin.dashboard.operation_run"}}</button></td>
    +						</tr>
    +						<tr>
    +							<td>{{.i18n.Tr "admin.dashboard.reinit_missing_repos"}}</td>
    +							<td><button type="submit" class="ui green button" name="op" value="7"><i class="fa fa-caret-square-o-right"></i> {{.i18n.Tr "admin.dashboard.operation_run"}}</button></td>
    +						</tr>
    +						<tr>
    +							<td>{{.i18n.Tr "admin.dashboard.sync_external_users"}}</td>
    +							<td><button type="submit" class="ui green button" name="op" value="8"><i class="fa fa-caret-square-o-right"></i> {{.i18n.Tr "admin.dashboard.operation_run"}}</button></td>
    +						</tr>
    +						<tr>
    +							<td>{{.i18n.Tr "admin.dashboard.git_fsck"}}</td>
    +							<td><button type="submit" class="ui green button" name="op" value="9"><i class="fa fa-caret-square-o-right"></i> {{.i18n.Tr "admin.dashboard.operation_run"}}</button></td>
    +						</tr>
    +						<tr>
    +							<td>{{.i18n.Tr "admin.dashboard.delete_generated_repository_avatars"}}</td>
    +							<td><button type="submit" class="ui green button" name="op" value="10"><i class="fa fa-caret-square-o-right"></i> {{.i18n.Tr "admin.dashboard.operation_run"}}</button></td>
    +						</tr>
    +					</tbody>
    +				</table>
    +			</form>
     		</div>
     
     		<h4 class="ui top attached header">
    
  • web_src/less/_admin.less+4 0 modified
    @@ -28,6 +28,10 @@
                     }
                 }
             }
    +
    +        form button[type='submit'] {
    +            padding: 5px 8px;
    +        }
         }
     
         .ui.header,
    
4cb18601ff33

Change action GETs to POST (#10462) (#10464)

https://github.com/go-gitea/giteaJohn OlheiserFeb 25, 2020via ghsa
11 files changed · +79 35
  • integrations/release_test.go+1 1 modified
    @@ -20,7 +20,7 @@ func createNewRelease(t *testing.T, session *TestSession, repoURL, tag, title st
     	resp := session.MakeRequest(t, req, http.StatusOK)
     	htmlDoc := NewHTMLParser(t, resp.Body)
     
    -	link, exists := htmlDoc.doc.Find("form").Attr("action")
    +	link, exists := htmlDoc.doc.Find("form.ui.form").Attr("action")
     	assert.True(t, exists, "The template has changed")
     
     	postData := map[string]string{
    
  • routers/routes/routes.go+6 6 modified
    @@ -485,7 +485,7 @@ func RegisterRoutes(m *macaron.Macaron) {
     	}, reqSignIn)
     
     	m.Group("/:username", func() {
    -		m.Get("/action/:action", user.Action)
    +		m.Post("/action/:action", user.Action)
     	}, reqSignIn)
     
     	if macaron.Env == macaron.DEV {
    @@ -517,16 +517,16 @@ func RegisterRoutes(m *macaron.Macaron) {
     			m.Get("/^:type(issues|pulls)$", user.Issues)
     			m.Get("/milestones", reqMilestonesDashboardPageEnabled, user.Milestones)
     			m.Get("/members", org.Members)
    -			m.Get("/members/action/:action", org.MembersAction)
    +			m.Post("/members/action/:action", org.MembersAction)
     
     			m.Get("/teams", org.Teams)
     		}, context.OrgAssignment(true))
     
     		m.Group("/:org", func() {
     			m.Get("/teams/:team", org.TeamMembers)
     			m.Get("/teams/:team/repositories", org.TeamRepositories)
    -			m.Route("/teams/:team/action/:action", "GET,POST", org.TeamsAction)
    -			m.Route("/teams/:team/action/repo/:action", "GET,POST", org.TeamsRepoAction)
    +			m.Post("/teams/:team/action/:action", org.TeamsAction)
    +			m.Post("/teams/:team/action/repo/:action", org.TeamsRepoAction)
     		}, context.OrgAssignment(true, false, true))
     
     		m.Group("/:org", func() {
    @@ -660,7 +660,7 @@ func RegisterRoutes(m *macaron.Macaron) {
     		})
     	}, reqSignIn, context.RepoAssignment(), context.UnitTypes(), reqRepoAdmin, context.RepoRef())
     
    -	m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), context.UnitTypes(), repo.Action)
    +	m.Post("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), context.UnitTypes(), repo.Action)
     
     	m.Group("/:username/:reponame", func() {
     		m.Group("/issues", func() {
    @@ -714,7 +714,7 @@ func RegisterRoutes(m *macaron.Macaron) {
     				Post(bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost)
     			m.Get("/:id/edit", repo.EditMilestone)
     			m.Post("/:id/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.EditMilestonePost)
    -			m.Get("/:id/:action", repo.ChangeMilestonStatus)
    +			m.Post("/:id/:action", repo.ChangeMilestonStatus)
     			m.Post("/delete", repo.DeleteMilestone)
     		}, context.RepoMustNotBeArchived(), reqRepoIssuesOrPullsWriter, context.RepoRef())
     		m.Group("/milestone", func() {
    
  • templates/org/member/members.tmpl+2 2 modified
    @@ -22,10 +22,10 @@
     							{{ $isPublic := index $.MembersIsPublicMember .ID}}
     							{{if $isPublic}}
     								<strong>{{$.i18n.Tr "org.members.public"}}</strong>
    -								{{if or (eq $.SignedUser.ID .ID) $.IsOrganizationOwner}}(<a href="{{$.OrgLink}}/members/action/private?uid={{.ID}}">{{$.i18n.Tr "org.members.public_helper"}}</a>){{end}}
    +								{{if or (eq $.SignedUser.ID .ID) $.IsOrganizationOwner}}(<a class="link-action" href data-url="{{$.OrgLink}}/members/action/private?uid={{.ID}}">{{$.i18n.Tr "org.members.public_helper"}}</a>){{end}}
     							{{else}}
     								<strong>{{$.i18n.Tr "org.members.private"}}</strong>
    -								{{if or (eq $.SignedUser.ID .ID) $.IsOrganizationOwner}}(<a href="{{$.OrgLink}}/members/action/public?uid={{.ID}}">{{$.i18n.Tr "org.members.private_helper"}}</a>){{end}}
    +								{{if or (eq $.SignedUser.ID .ID) $.IsOrganizationOwner}}(<a class="link-action" href data-url="{{$.OrgLink}}/members/action/public?uid={{.ID}}">{{$.i18n.Tr "org.members.private_helper"}}</a>){{end}}
     							{{end}}
     						</div>
     					</div>
    
  • templates/org/team/members.tmpl+4 1 modified
    @@ -27,7 +27,10 @@
     					{{range .Team.Members}}
     						<div class="item">
     							{{if $.IsOrganizationOwner}}
    -								<a class="ui red small button right" href="{{$.OrgLink}}/teams/{{$.Team.LowerName}}/action/remove?uid={{.ID}}">{{$.i18n.Tr "org.members.remove"}}</a>
    +								<form method="post" action="{{$.OrgLink}}/teams/{{$.Team.LowerName}}/action/remove?uid={{.ID}}">
    +									{{$.CsrfTokenHtml}}
    +									<button type="submit" class="ui red small button right" >{{$.i18n.Tr "org.members.remove"}}</button>
    +								</form>
     							{{end}}
     							<a href="{{.HomeLink}}">
     								<img class="ui avatar image" src="{{.RelAvatarLink}}">
    
  • templates/org/team/repositories.tmpl+4 1 modified
    @@ -35,7 +35,10 @@
     					{{range .Team.Repos}}
     						<div class="item">
     							{{if $canAddRemove}}
    -								<a class="ui red small button right" href="{{$.OrgLink}}/teams/{{$.Team.LowerName}}/action/repo/remove?repoid={{.ID}}">{{$.i18n.Tr "remove"}}</a>
    +								<form method="post" action="{{$.OrgLink}}/teams/{{$.Team.LowerName}}/action/repo/remove?repoid={{.ID}}">
    +									{{$.CsrfTokenHtml}}
    +									<button type="submit" class="ui red small button right">{{$.i18n.Tr "remove"}}</button>
    +								</form>
     							{{end}}
     							<a class="member" href="{{AppSubUrl}}/{{$.Org.Name}}/{{.Name}}">
     								<i class="octicon octicon-{{if .IsPrivate}}lock{{else if .IsFork}}repo-forked{{else if .IsMirror}}repo-clone{{else}}repo{{end}}"></i>
    
  • templates/org/team/sidebar.tmpl+8 2 modified
    @@ -3,9 +3,15 @@
     		<strong>{{.Team.Name}}</strong>
     		<div class="ui right">
     			{{if .Team.IsMember $.SignedUser.ID}}
    -				<a class="ui red tiny button" href="{{.OrgLink}}/teams/{{.Team.LowerName}}/action/leave?uid={{$.SignedUser.ID}}&page=home">{{$.i18n.Tr "org.teams.leave"}}</a>
    +				<form method="post" action="{{.OrgLink}}/teams/{{.Team.LowerName}}/action/leave?uid={{$.SignedUser.ID}}&page=home">
    +					{{$.CsrfTokenHtml}}
    +					<button type="submit" class="ui red tiny button">{{$.i18n.Tr "org.teams.leave"}}</button>
    +				</form>
     			{{else if .IsOrganizationOwner}}
    -				<a class="ui blue tiny button" href="{{.OrgLink}}/teams/{{.Team.LowerName}}/action/join?uid={{$.SignedUser.ID}}&page=team">{{$.i18n.Tr "org.teams.join"}}</a>
    +				<form method="post" action="{{.OrgLink}}/teams/{{.Team.LowerName}}/action/join?uid={{$.SignedUser.ID}}&page=team">
    +					{{$.CsrfTokenHtml}}
    +					<button type="submit" class="ui blue tiny button">{{$.i18n.Tr "org.teams.join"}}</button>
    +				</form>
     			{{end}}
     		</div>
     	</h4>
    
  • templates/org/team/teams.tmpl+8 2 modified
    @@ -17,9 +17,15 @@
     						<a class="text black" href="{{$.OrgLink}}/teams/{{.LowerName}}"><strong>{{.Name}}</strong></a>
     						<div class="ui right">
     							{{if .IsMember $.SignedUser.ID}}
    -								<a class="ui red small button" href="{{$.OrgLink}}/teams/{{.LowerName}}/action/leave?uid={{$.SignedUser.ID}}">{{$.i18n.Tr "org.teams.leave"}}</a>
    +								<form method="post" action="{{$.OrgLink}}/teams/{{.LowerName}}/action/leave?uid={{$.SignedUser.ID}}">
    +									{{$.CsrfTokenHtml}}
    +									<button type="submit" class="ui red small button">{{$.i18n.Tr "org.teams.leave"}}</button>
    +								</form>
     							{{else if $.IsOrganizationOwner}}
    -								<a class="ui blue small button" href="{{$.OrgLink}}/teams/{{.LowerName}}/action/join?uid={{$.SignedUser.ID}}">{{$.i18n.Tr "org.teams.join"}}</a>
    +								<form method="post" action="{{$.OrgLink}}/teams/{{.LowerName}}/action/join?uid={{$.SignedUser.ID}}">
    +									{{$.CsrfTokenHtml}}
    +									<button type="submit" class="ui blue small button">{{$.i18n.Tr "org.teams.join"}}</button>
    +								</form>
     							{{end}}
     						</div>
     					</div>
    
  • templates/repo/header.tmpl+22 16 modified
    @@ -20,22 +20,28 @@
     			</div>
     			{{if not .IsBeingCreated}}
     				<div class="repo-buttons">
    -					<div class="ui labeled button" tabindex="0">
    -						<a class="ui compact basic button" href="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}un{{end}}watch?redirect_to={{$.Link}}">
    -							<i class="icon fa-eye{{if not $.IsWatchingRepo}}-slash{{end}}"></i>{{if $.IsWatchingRepo}}{{$.i18n.Tr "repo.unwatch"}}{{else}}{{$.i18n.Tr "repo.watch"}}{{end}}
    -						</a>
    -						<a class="ui basic label" href="{{.Link}}/watchers">
    -							{{.NumWatches}}
    -						</a>
    -					</div>
    -					<div class="ui labeled button" tabindex="0">
    -						<a class="ui compact basic button" href="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}un{{end}}star?redirect_to={{$.Link}}">
    -							<i class="icon star{{if not $.IsStaringRepo}} outline{{end}}"></i>{{if $.IsStaringRepo}}{{$.i18n.Tr "repo.unstar"}}{{else}}{{$.i18n.Tr "repo.star"}}{{end}}
    -						</a>
    -						<a class="ui basic label" href="{{.Link}}/stars">
    -							{{.NumStars}}
    -						</a>
    -					</div>
    +					<form method="post" action="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}un{{end}}watch?redirect_to={{$.Link}}">
    +						{{$.CsrfTokenHtml}}
    +						<div class="ui labeled button" tabindex="0">
    +							<button type="submit" class="ui compact basic button">
    +								<i class="icon fa-eye{{if not $.IsWatchingRepo}}-slash{{end}}"></i>{{if $.IsWatchingRepo}}{{$.i18n.Tr "repo.unwatch"}}{{else}}{{$.i18n.Tr "repo.watch"}}{{end}}
    +							</button>
    +							<a class="ui basic label" href="{{.Link}}/watchers">
    +								{{.NumWatches}}
    +							</a>
    +						</div>
    +					</form>
    +					<form method="post" action="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}un{{end}}star?redirect_to={{$.Link}}">
    +						{{$.CsrfTokenHtml}}
    +						<div class="ui labeled button" tabindex="0">
    +							<button type="submit" class="ui compact basic button">
    +								<i class="icon star{{if not $.IsStaringRepo}} outline{{end}}"></i>{{if $.IsStaringRepo}}{{$.i18n.Tr "repo.unstar"}}{{else}}{{$.i18n.Tr "repo.star"}}{{end}}
    +							</button>
    +							<a class="ui basic label" href="{{.Link}}/stars">
    +								{{.NumStars}}
    +							</a>
    +						</div>
    +					</form>
     					{{if and (not .IsEmpty) ($.Permission.CanRead $.UnitTypeCode)}}
     						<div class="ui labeled button {{if and ($.IsSigned) (not $.CanSignedUserFork)}}disabled-repo-button{{end}}" tabindex="0">
     							<a class="ui compact basic button {{if or (not $.IsSigned) (not $.CanSignedUserFork)}}poping up{{end}}" {{if $.CanSignedUserFork}}href="{{AppSubUrl}}/repo/fork/{{.ID}}"{{else if $.IsSigned}} data-content="{{$.i18n.Tr "repo.fork_from_self"}}" {{ else }} data-content="{{$.i18n.Tr "repo.fork_guest_user" }}" rel="nofollow" href="{{AppSubUrl}}/user/login?redirect_to={{AppSubUrl}}/repo/fork/{{.ID}}" {{end}} data-position="top center" data-variation="tiny">
    
  • templates/repo/issue/milestones.tmpl+2 2 modified
    @@ -71,9 +71,9 @@
     						<div class="ui right operate">
     							<a href="{{$.Link}}/{{.ID}}/edit" data-id={{.ID}} data-title={{.Name}}><i class="octicon octicon-pencil"></i> {{$.i18n.Tr "repo.issues.label_edit"}}</a>
     							{{if .IsClosed}}
    -								<a href="{{$.Link}}/{{.ID}}/open" data-id={{.ID}} data-title={{.Name}}><i class="octicon octicon-check"></i> {{$.i18n.Tr "repo.milestones.open"}}</a>
    +								<a class="link-action" href data-url="{{$.Link}}/{{.ID}}/open" data-id={{.ID}} data-title={{.Name}}><i class="octicon octicon-check"></i> {{$.i18n.Tr "repo.milestones.open"}}</a>
     							{{else}}
    -								<a href="{{$.Link}}/{{.ID}}/close" data-id={{.ID}} data-title={{.Name}}><i class="octicon octicon-x"></i> {{$.i18n.Tr "repo.milestones.close"}}</a>
    +								<a class="link-action" href data-url="{{$.Link}}/{{.ID}}/close" data-id={{.ID}} data-title={{.Name}}><i class="octicon octicon-x"></i> {{$.i18n.Tr "repo.milestones.close"}}</a>
     							{{end}}
     							<a class="delete-button" href="#" data-url="{{$.RepoLink}}/milestones/delete" data-id="{{.ID}}"><i class="octicon octicon-trashcan"></i> {{$.i18n.Tr "repo.issues.label_delete"}}</a>
     						</div>
    
  • templates/user/profile.tmpl+8 2 modified
    @@ -65,9 +65,15 @@
     							{{if and .IsSigned (ne .SignedUserName .Owner.Name)}}
     							<li class="follow">
     								{{if .SignedUser.IsFollowing .Owner.ID}}
    -								<a class="ui basic red button" href="{{.Link}}/action/unfollow?redirect_to={{$.Link}}"><i class="octicon octicon-person"></i> {{.i18n.Tr "user.unfollow"}}</a>
    +									<form method="post" action="{{.Link}}/action/unfollow?redirect_to={{$.Link}}">
    +										{{$.CsrfTokenHtml}}
    +										<button type="submit" class="ui basic red button"><i class="octicon octicon-person"></i> {{.i18n.Tr "user.unfollow"}}</button>
    +									</form>
     								{{else}}
    -								<a class="ui basic green button" href="{{.Link}}/action/follow?redirect_to={{$.Link}}"><i class="octicon octicon-person"></i> {{.i18n.Tr "user.follow"}}</a>
    +									<form method="post" action="{{.Link}}/action/follow?redirect_to={{$.Link}}">
    +										{{$.CsrfTokenHtml}}
    +										<button type="submit" class="ui basic green button"><i class="octicon octicon-person"></i> {{.i18n.Tr "user.follow"}}</button>
    +									</form>
     								{{end}}
     							</li>
     							{{end}}
    
  • web_src/js/index.js+14 0 modified
    @@ -2479,6 +2479,7 @@ $(document).ready(() => {
       // Helpers.
       $('.delete-button').click(showDeletePopup);
       $('.add-all-button').click(showAddAllPopup);
    +  $('.link-action').click(linkAction);
     
       $('.delete-branch-button').click(showDeletePopup);
     
    @@ -2736,6 +2737,19 @@ function showAddAllPopup() {
       return false;
     }
     
    +function linkAction() {
    +  const $this = $(this);
    +  $.post($this.data('url'), {
    +    _csrf: csrf
    +  }).done((data) => {
    +    if (data.redirect) {
    +      window.location.href = data.redirect;
    +    } else {
    +      window.location.reload();
    +    }
    +  });
    +}
    +
     function initVueComponents() {
       const vueDelimeters = ['${', '}'];
     
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

10

News mentions

0

No linked articles in our index yet.