Skip to content

Commit 8c77179

Browse files
committed
temp: fix permission check
1 parent c98714d commit 8c77179

File tree

1 file changed

+20
-20
lines changed

1 file changed

+20
-20
lines changed

services/mailer/mail.go

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package mailer
66

77
import (
88
"bytes"
9+
"context"
910
"encoding/base64"
1011
"fmt"
1112
"html/template"
@@ -16,9 +17,7 @@ import (
1617
"strings"
1718
texttmpl "text/template"
1819

19-
access_model "code.gitea.io/gitea/models/perm/access"
2020
repo_model "code.gitea.io/gitea/models/repo"
21-
"code.gitea.io/gitea/models/unit"
2221
user_model "code.gitea.io/gitea/models/user"
2322
"code.gitea.io/gitea/modules/log"
2423
"code.gitea.io/gitea/modules/setting"
@@ -54,11 +53,20 @@ func sanitizeSubject(subject string) string {
5453
return mime.QEncoding.Encode("utf-8", string(runes))
5554
}
5655

57-
func Base64InlineImages(body string, ctx *mailCommentContext) (string, error) {
56+
type mailAttachmentBase64Embedder struct {
57+
doer *user_model.User
58+
repo *repo_model.Repository
59+
maxSize int64
60+
}
61+
62+
func newMailAttachmentBase64Embedder(doer *user_model.User, repo *repo_model.Repository, maxSize int64) *mailAttachmentBase64Embedder {
63+
return &mailAttachmentBase64Embedder{doer: doer, repo: repo, maxSize: maxSize}
64+
}
65+
66+
func (b64embedder *mailAttachmentBase64Embedder) Base64InlineImages(ctx context.Context, body string) (string, error) {
5867
doc, err := html.Parse(strings.NewReader(body))
5968
if err != nil {
60-
log.Error("Failed to parse HTML body: %v", err)
61-
return "", err
69+
return "", fmt.Errorf("%w", err)
6270
}
6371

6472
var totalEmbeddedImagesSize int64
@@ -70,7 +78,7 @@ func Base64InlineImages(body string, ctx *mailCommentContext) (string, error) {
7078
for i, attr := range n.Attr {
7179
if attr.Key == "src" {
7280
attachmentPath := attr.Val
73-
dataURI, err := AttachmentSrcToBase64DataURI(attachmentPath, ctx, &totalEmbeddedImagesSize)
81+
dataURI, err := b64embedder.AttachmentSrcToBase64DataURI(ctx, attachmentPath, &totalEmbeddedImagesSize)
7482
if err != nil {
7583
log.Trace("attachmentSrcToDataURI not possible: %v", err) // Not an error, just skip. This is probably an image from outside the gitea instance.
7684
continue
@@ -98,7 +106,7 @@ func Base64InlineImages(body string, ctx *mailCommentContext) (string, error) {
98106
return buf.String(), nil
99107
}
100108

101-
func AttachmentSrcToBase64DataURI(attachmentPath string, ctx *mailCommentContext, totalEmbeddedImagesSize *int64) (string, error) {
109+
func (b64embedder *mailAttachmentBase64Embedder) AttachmentSrcToBase64DataURI(ctx context.Context, attachmentPath string, totalEmbeddedImagesSize *int64) (string, error) {
102110
if !strings.HasPrefix(attachmentPath, setting.AppURL) { // external image
103111
return "", fmt.Errorf("external image")
104112
}
@@ -113,14 +121,8 @@ func AttachmentSrcToBase64DataURI(attachmentPath string, ctx *mailCommentContext
113121
return "", err
114122
}
115123

116-
// "Doer" is theoretically not the correct permission check (as Doer created the action on which to send), but as this is batch processed the receipants can't be accessed.
117-
// Therefore, we check the Doer, with which we counter leaking information as a Doer brute force attack on attachments would be possible.
118-
perm, err := access_model.GetUserRepoPermission(ctx, ctx.Issue.Repo, ctx.Doer)
119-
if err != nil {
120-
return "", err
121-
}
122-
if !perm.CanRead(unit.TypeIssues) {
123-
return "", fmt.Errorf("no permission")
124+
if attachment.RepoID != b64embedder.repo.ID {
125+
return "", fmt.Errorf("attachment does not belong to the repository")
124126
}
125127

126128
fr, err := storage.Attachments.Open(attachment.RelativePath())
@@ -129,15 +131,13 @@ func AttachmentSrcToBase64DataURI(attachmentPath string, ctx *mailCommentContext
129131
}
130132
defer fr.Close()
131133

132-
maxSize := setting.MailService.Base64EmbedImagesMaxSizePerEmail // at maximum read the whole available combined email size, to prevent maliciously large file reads
133-
134-
lr := &io.LimitedReader{R: fr, N: maxSize + 1}
134+
lr := &io.LimitedReader{R: fr, N: b64embedder.maxSize + 1}
135135
content, err := io.ReadAll(lr)
136136
if err != nil {
137137
return "", err
138138
}
139-
if len(content) > int(maxSize) {
140-
return "", fmt.Errorf("file size exceeds the embedded image max limit \\(%d bytes\\)", maxSize)
139+
if int64(len(content)) > b64embedder.maxSize {
140+
return "", fmt.Errorf("file size exceeds the embedded image max limit \\(%d bytes\\)", b64embedder.maxSize)
141141
}
142142

143143
if *totalEmbeddedImagesSize+int64(len(content)) > setting.MailService.Base64EmbedImagesMaxSizePerEmail {

0 commit comments

Comments
 (0)