Add mimetype check for images

This commit is contained in:
kolaente 2020-08-02 13:59:51 +02:00
parent 27ca9a9169
commit 7cbded8990
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
6 changed files with 45 additions and 2 deletions

1
go.mod
View File

@ -31,6 +31,7 @@ require (
github.com/disintegration/imaging v1.6.2
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835
github.com/gabriel-vasile/mimetype v1.1.1
github.com/getsentry/sentry-go v0.7.0
github.com/go-redis/redis/v7 v7.4.0
github.com/go-sql-driver/mysql v1.5.0

2
go.sum
View File

@ -136,6 +136,8 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835 h1:roDmqJ4Qes7hrDOsWsMCce0vQHz3xiMPjJ9m4c2eeNs=
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835/go.mod h1:BjL/N0+C+j9uNX+1xcNuM9vdSIcXCZrQZUYbXOFbgN8=
github.com/gabriel-vasile/mimetype v1.1.1 h1:qbN9MPuRf3bstHu9zkI9jDWNfH//9+9kHxr9oRBBBOA=
github.com/gabriel-vasile/mimetype v1.1.1/go.mod h1:6CDPel/o/3/s4+bp6kIbsWATq8pmgOisOPG40CJa6To=
github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc=
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=

View File

@ -68,6 +68,11 @@ func (f *File) LoadFileMetaByID() (err error) {
// Create creates a new file from an FileHeader
func Create(f io.ReadCloser, realname string, realsize uint64, a web.Auth) (file *File, err error) {
return CreateWithMime(f, realname, realsize, a, "")
}
// CreateWithMime creates a new file from an FileHeader and sets its mime type
func CreateWithMime(f io.ReadCloser, realname string, realsize uint64, a web.Auth, mime string) (file *File, err error) {
// Get and parse the configured file size
var maxSize datasize.ByteSize
@ -84,6 +89,7 @@ func Create(f io.ReadCloser, realname string, realsize uint64, a web.Auth) (file
Name: realname,
Size: realsize,
CreatedByID: a.GetID(),
Mime: mime,
}
_, err = x.Insert(file)

View File

@ -31,6 +31,10 @@ func (p *Provider) GetAvatar(u *user.User, size int64) (avatar []byte, mimeType
return nil, "", err
}
if err := f.LoadFileMetaByID(); err != nil {
return nil, "", err
}
avatar, err = ioutil.ReadAll(f.File)
return avatar, f.Mime, err
}

View File

@ -25,9 +25,12 @@ import (
v1 "code.vikunja.io/api/pkg/routes/api/v1"
"code.vikunja.io/web"
"code.vikunja.io/web/handler"
"github.com/gabriel-vasile/mimetype"
"github.com/labstack/echo/v4"
"io"
"net/http"
"strconv"
"strings"
)
// BackgroundProvider represents a thing which holds a background provider
@ -132,7 +135,18 @@ func (bp *BackgroundProvider) UploadBackground(c echo.Context) error {
}
defer src.Close()
f, err := files.Create(src, file.Filename, uint64(file.Size), auth)
// Validate we're dealing with an image
mime, err := mimetype.DetectReader(src)
if err != nil {
return handler.HandleHTTPError(err, c)
}
if !strings.HasPrefix(mime.String(), "image") {
return c.JSON(http.StatusBadRequest, models.Message{Message: "Uploaded file is no image."})
}
src.Seek(0, io.SeekStart)
// Save the file
f, err := files.CreateWithMime(src, file.Filename, uint64(file.Size), auth, mime.String())
if err != nil {
if files.IsErrFileIsTooLarge(err) {
return echo.ErrBadRequest

View File

@ -27,9 +27,12 @@ import (
"code.vikunja.io/api/pkg/modules/avatar/upload"
"code.vikunja.io/api/pkg/user"
"code.vikunja.io/web/handler"
"github.com/gabriel-vasile/mimetype"
"github.com/labstack/echo/v4"
"io"
"net/http"
"strconv"
"strings"
)
// GetAvatar returns a user's avatar
@ -107,7 +110,20 @@ func UploadAvatar(c echo.Context) (err error) {
}
defer src.Close()
f, err := files.Create(src, file.Filename, uint64(file.Size), u)
// Validate we're dealing with an image
mime, err := mimetype.DetectReader(src)
if err != nil {
return handler.HandleHTTPError(err, c)
}
if !strings.HasPrefix(mime.String(), "image") {
return c.JSON(http.StatusBadRequest, models.Message{Message: "Uploaded file is no image."})
}
src.Seek(0, io.SeekStart)
// Remove the old file if one exists
// Save the file
f, err := files.CreateWithMime(src, file.Filename, uint64(file.Size), u, mime.String())
if err != nil {
if files.IsErrFileIsTooLarge(err) {
return echo.ErrBadRequest