Replace CSRF cookie with CrossOriginProtection (#36183)

Removes the CSRF cookie in favor of
[`CrossOriginProtection`](https://pkg.go.dev/net/http#CrossOriginProtection)
which relies purely on HTTP headers.

Fixes: https://github.com/go-gitea/gitea/issues/11188
Fixes: https://github.com/go-gitea/gitea/issues/30333
Helps: https://github.com/go-gitea/gitea/issues/35107

TODOs:

- [x] Fix tests
- [ ] Ideally add tests to validates the protection

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
silverwind
2025-12-25 11:33:34 +01:00
committed by GitHub
parent eddf875992
commit 42d294941c
207 changed files with 178 additions and 1196 deletions
@@ -6,7 +6,6 @@
<div class="header"></div>
<div class="content">
<form class="ui form ignore-dirty form-fetch-action" method="post">
{{.CsrfTokenHtml}}
<input name="id" type="hidden">
<div class="required field">
<label for="name">{{ctx.Locale.Tr "repo.issues.label_title"}}</label>
@@ -2,7 +2,6 @@
<div class="twelve wide computer column">
<p>{{ctx.Locale.Tr "repo.issues.label_templates.info"}}</p>
<form class="ui form center" action="{{.Link}}/initialize" method="post">
{{.CsrfTokenHtml}}
<div class="field">
<div class="ui selection dropdown">
<input type="hidden" name="template_name" value="Default">
-1
View File
@@ -22,7 +22,6 @@
</h2>
{{template "base/alert" .}}
<form class="ui form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<div class="field {{if .Err_Title}}error{{end}}">
<label>{{ctx.Locale.Tr "repo.milestones.title"}}</label>
<input name="title" placeholder="{{ctx.Locale.Tr "repo.milestones.title"}}" value="{{.title}}" autofocus required maxlength="50">
-1
View File
@@ -1,6 +1,5 @@
{{template "base/alert" .}}
<form class="issue-content ui comment form form-fetch-action" id="new-issue" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<div class="issue-content-left">
<div class="ui comments">
<div class="comment">
@@ -21,7 +21,6 @@
<form class="ui fluid action input issue-due-form form-fetch-action tw-mt-2 {{if .Issue.DeadlineUnix}}tw-hidden{{end}}"
method="post" action="{{AppSubUrl}}/{{PathEscape .Repository.Owner.Name}}/{{PathEscape .Repository.Name}}/issues/{{.Issue.Index}}/deadline"
>
{{$.CsrfTokenHtml}}
<input required type="date" name="deadline" placeholder="{{ctx.Locale.Tr "repo.issues.due_date_form"}}" {{if .Issue.DeadlineUnix}}value="{{.Issue.DeadlineUnix.FormatDate}}"{{end}}>
<button class="ui icon button">{{Iif .Issue.DeadlineUnix (svg "octicon-pencil") (svg "octicon-plus")}}</button>
</form>
@@ -110,7 +110,6 @@
{{if and .CanCreateIssueDependencies (not .Repository.IsArchived)}}
<div>
<form method="post" action="{{.Issue.Link}}/dependency/add" id="addDependencyForm">
{{$.CsrfTokenHtml}}
<div class="ui fluid action input">
<div class="ui search selection dropdown" id="new-dependency-drop-list" data-issue-id="{{.Issue.ID}}" data-issue-cross-repo-search="{{.AllowCrossRepositoryDependencies}}">
<input name="newDependency" type="hidden">
@@ -131,7 +130,6 @@
<form id="issue-remove-dependency-confirm" class="ui g-modal-confirm modal" method="post" action="{{.Issue.Link}}/dependency/delete">
<div class="header">{{svg "octicon-trash"}} {{ctx.Locale.Tr "repo.issues.dependency.remove_header"}}</div>
<div class="content">
{{$.CsrfTokenHtml}}
<input type="hidden" value="" name="removeDependencyID" class="remove-dependency-id">
<input type="hidden" value="" name="dependencyType" class="dependency-type">
<p>
@@ -4,7 +4,6 @@
{{/* Pin issue */}}
{{if or .PinEnabled .Issue.IsPinned}}
<form class="tw-mt-1 form-fetch-action single-button-form" method="post" {{if $.NewPinAllowed}}action="{{.Issue.Link}}/pin"{{else}}data-tooltip-content="{{ctx.Locale.Tr "repo.issues.max_pinned"}}"{{end}}>
{{$.CsrfTokenHtml}}
<button class="fluid ui button {{if not $.NewPinAllowed}}disabled{{end}}">
{{if not .Issue.IsPinned}}
{{svg "octicon-pin"}}
@@ -46,7 +45,6 @@
</div>
<form class="ui form form-fetch-action" method="post" action="{{.Issue.Link}}{{if .Issue.IsLocked}}/unlock{{else}}/lock{{end}}">
{{.CsrfTokenHtml}}
{{if not .Issue.IsLocked}}
<div class="field">
@@ -103,7 +101,6 @@
</p>
</div>
<form action="{{.Issue.Link}}/delete" method="post">
{{.CsrfTokenHtml}}
{{template "base/modal_actions_confirm" .}}
</form>
</div>
@@ -115,7 +115,6 @@
{{ctx.Locale.Tr "repo.issues.dismiss_review_warning"}}
</div>
<form class="ui form" action="{{$pageMeta.RepoLink}}/issues/dismiss_review" method="post">
{{ctx.RootData.CsrfTokenHtml}}
<input type="hidden" class="reviewer-id" name="review_id">
<div class="field">
<label for="issue-sidebar-dismiss-review-message">{{ctx.Locale.Tr "action.review_dismissed_reason"}}</label>
@@ -39,7 +39,6 @@
<div class="header">{{ctx.Locale.Tr "repo.issues.time_estimate_set"}}</div>
<form method="post" class="ui form form-fetch-action" action="{{.Issue.Link}}/time_estimate">
<div class="content">
{{$.CsrfTokenHtml}}
<input name="time_estimate" placeholder="1h 2m" value="{{TimeEstimateString .Issue.TimeEstimate}}">
<div class="actions">
<button class="ui cancel button">{{ctx.Locale.Tr "cancel"}}</button>
@@ -54,7 +53,6 @@
<div class="header">{{ctx.Locale.Tr "repo.issues.add_time_manually"}}</div>
<form method="post" class="ui form form-fetch-action" action="{{.Issue.Link}}/times/add">
<div class="content flex-text-block">
{{$.CsrfTokenHtml}}
<input placeholder='{{ctx.Locale.Tr "repo.issues.add_time_hours"}}' type="number" name="hours">:
<input placeholder='{{ctx.Locale.Tr "repo.issues.add_time_minutes"}}' type="number" name="minutes">
</div>
-1
View File
@@ -81,7 +81,6 @@
<div class="ui segment avatar-content-left-arrow">
<form class="ui form form-fetch-action" id="comment-form" action="{{$.RepoLink}}/issues/{{.Issue.Index}}/comments" method="post">
{{template "repo/issue/comment_tab" .}}
{{.CsrfTokenHtml}}
<div class="field footer">
<div class="flex-text-block tw-justify-end">
{{if and (or .HasIssuesOrPullsWritePermission .IsIssuePoster) (not .DisableStatusChange)}}
@@ -384,7 +384,6 @@
{{if and $.StillCanManualMerge (not $showGeneralMergeForm)}}
<div class="divider"></div>
<form class="ui form form-fetch-action" action="{{.Issue.Link}}/merge" method="post">{{/* another similar form is in PullRequestMergeForm.vue*/}}
{{.CsrfTokenHtml}}
<div class="field">
<input type="text" name="merge_commit_id" placeholder="{{ctx.Locale.Tr "repo.pulls.merge_commit_id"}}">
</div>
@@ -4,7 +4,6 @@
</div>
<div class="content">
<form class="ui form form-fetch-action" action="{{.Repository.Link}}/issues/new" method="post">
{{.CsrfTokenHtml}}
<div class="field">
<label><strong>{{ctx.Locale.Tr "repository"}}</strong></label>
<div class="ui search selection dropdown issue_reference_repository_search ellipsis-text-items">
@@ -26,7 +26,6 @@
{{end}}
{{if and $.UpdateAllowed (not $.UpdateByRebaseAllowed)}}
<form action="{{$.Issue.Link}}/update" method="post" class="ui update-branch-form">
{{$.CsrfTokenHtml}}
<button class="ui compact button">
<span class="ui text">{{ctx.Locale.Tr "repo.pulls.update_branch"}}</span>
</button>