|
1 | 1 | package r0
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "bytes" |
4 | 5 | "errors"
|
| 6 | + "io" |
5 | 7 | "net/http"
|
6 | 8 | "path/filepath"
|
7 | 9 |
|
8 | 10 | "github.com/getsentry/sentry-go"
|
| 11 | + "github.com/h2non/filetype" |
9 | 12 | "github.com/sirupsen/logrus"
|
10 | 13 | "github.com/t2bot/matrix-media-repo/api/_apimeta"
|
11 | 14 | "github.com/t2bot/matrix-media-repo/api/_responses"
|
12 | 15 | "github.com/t2bot/matrix-media-repo/api/_routers"
|
13 | 16 | "github.com/t2bot/matrix-media-repo/common"
|
14 | 17 | "github.com/t2bot/matrix-media-repo/common/rcontext"
|
15 | 18 | "github.com/t2bot/matrix-media-repo/pipelines/pipeline_upload"
|
| 19 | + "github.com/t2bot/matrix-media-repo/util" |
16 | 20 | )
|
17 | 21 |
|
18 | 22 | func UploadMediaAsync(r *http.Request, rctx rcontext.RequestContext, user _apimeta.UserInfo) interface{} {
|
19 | 23 | server := _routers.GetParam("server", r)
|
20 | 24 | mediaId := _routers.GetParam("mediaId", r)
|
21 | 25 | filename := filepath.Base(r.URL.Query().Get("filename"))
|
22 |
| - |
23 | 26 | rctx = rctx.LogWithFields(logrus.Fields{
|
24 | 27 | "mediaId": mediaId,
|
25 | 28 | "server": server,
|
26 | 29 | "filename": filename,
|
27 | 30 | })
|
28 |
| - |
29 |
| - if r.Host != server { |
| 31 | + // GK CUSTOMIZATION: Sanitize the filename |
| 32 | + if len(filename) > rctx.Config.Uploads.MaxFilenameLength { |
| 33 | + rctx.Log.Info("Filename too long") |
30 | 34 | return &_responses.ErrorResponse{
|
31 |
| - Code: common.ErrCodeNotFound, |
32 |
| - Message: "Upload request is for another domain.", |
33 |
| - InternalCode: common.ErrCodeForbidden, |
| 35 | + Code: common.ErrCodeBadRequest, |
| 36 | + Message: "Filename too long.", |
| 37 | + InternalCode: common.ErrCodeBadRequest, |
34 | 38 | }
|
35 | 39 | }
|
36 | 40 |
|
37 | 41 | contentType := r.Header.Get("Content-Type")
|
38 | 42 | if contentType == "" {
|
39 | 43 | contentType = "application/octet-stream" // binary
|
| 44 | + } else { |
| 45 | + // GK CUSTOMIZATION: Check if the file type is supported |
| 46 | + buf, err := io.ReadAll(r.Body) |
| 47 | + r.Body = io.NopCloser(bytes.NewBuffer(buf)) |
| 48 | + if err != nil { |
| 49 | + return &_responses.ErrorResponse{ |
| 50 | + Code: common.ErrCodeBadRequest, |
| 51 | + Message: "Error reading file.", |
| 52 | + InternalCode: common.ErrCodeBadRequest, |
| 53 | + } |
| 54 | + } |
| 55 | + kind, err := filetype.Match(buf) |
| 56 | + if err != nil { |
| 57 | + return &_responses.ErrorResponse{ |
| 58 | + Code: common.ErrCodeBadRequest, |
| 59 | + Message: "Error matching file type.", |
| 60 | + InternalCode: common.ErrCodeBadRequest, |
| 61 | + } |
| 62 | + } |
| 63 | + if !util.IsSupportedFileType(kind.Extension, rctx.Config.Uploads.SupportedFileTypes) { |
| 64 | + rctx.Log.Info("Unsupported file type: ", kind.Extension) |
| 65 | + return &_responses.ErrorResponse{ |
| 66 | + Code: common.ErrCodeBadRequest, |
| 67 | + Message: "Unsupported file type.", |
| 68 | + InternalCode: common.ErrCodeBadRequest, |
| 69 | + } |
| 70 | + } |
| 71 | + } |
| 72 | + |
| 73 | + if r.Host != server { |
| 74 | + return &_responses.ErrorResponse{ |
| 75 | + Code: common.ErrCodeNotFound, |
| 76 | + Message: "Upload request is for another domain.", |
| 77 | + InternalCode: common.ErrCodeForbidden, |
| 78 | + } |
40 | 79 | }
|
41 | 80 |
|
42 | 81 | // Early sizing constraints (reject requests which claim to be too large/small)
|
|
0 commit comments