Browse Source

Add file extsnsion check to media uploads.

While file content (MIME) check already existed, the lack of file
extension check allowed arbitrary extensions to be uploaded and
then accessed via the static file server. For instance, a .html file
with JPG content intersperesed with Javascript.

This commit adds a file extension check on top of the MIME type check.
Kailash Nadh 4 years ago
parent
commit
dba47bca28
2 changed files with 22 additions and 26 deletions
  1. 16 10
      cmd/media.go
  2. 6 16
      cmd/utils.go

+ 16 - 10
cmd/media.go

@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"mime/multipart"
 	"net/http"
+	"path/filepath"
 	"strconv"
 
 	"github.com/disintegration/imaging"
@@ -17,13 +18,11 @@ const (
 	thumbnailSize = 90
 )
 
-// imageMimes is the list of image types allowed to be uploaded.
-var imageMimes = []string{
-	"image/jpg",
-	"image/jpeg",
-	"image/png",
-	"image/svg",
-	"image/gif"}
+// validMimes is the list of image types allowed to be uploaded.
+var (
+	validMimes = []string{"image/jpg", "image/jpeg", "image/png", "image/gif"}
+	validExts  = []string{".jpg", ".jpeg", ".png", ".gif"}
+)
 
 // handleUploadMedia handles media file uploads.
 func handleUploadMedia(c echo.Context) error {
@@ -37,9 +36,16 @@ func handleUploadMedia(c echo.Context) error {
 			app.i18n.Ts("media.invalidFile", "error", err.Error()))
 	}
 
-	// Validate MIME type with the list of allowed types.
-	var typ = file.Header.Get("Content-type")
-	if ok := validateMIME(typ, imageMimes); !ok {
+	// Validate file extension.
+	ext := filepath.Ext(file.Filename)
+	if ok := inArray(ext, validExts); !ok {
+		return echo.NewHTTPError(http.StatusBadRequest,
+			app.i18n.Ts("media.unsupportedFileType", "type", ext))
+	}
+
+	// Validate file's mime.
+	typ := file.Header.Get("Content-type")
+	if ok := inArray(typ, validMimes); !ok {
 		return echo.NewHTTPError(http.StatusBadRequest,
 			app.i18n.Ts("media.unsupportedFileType", "type", typ))
 	}

+ 6 - 16
cmd/utils.go

@@ -15,24 +15,14 @@ var (
 	tagRegexpSpaces = regexp.MustCompile(`[\s]+`)
 )
 
-// validateMIME is a helper function to validate uploaded file's MIME type
-// against the slice of MIME types is given.
-func validateMIME(typ string, mimes []string) (ok bool) {
-	if len(mimes) > 0 {
-		var (
-			ok = false
-		)
-		for _, m := range mimes {
-			if typ == m {
-				ok = true
-				break
-			}
-		}
-		if !ok {
-			return false
+// inArray checks if a string is present in a list of strings.
+func inArray(val string, vals []string) (ok bool) {
+	for _, v := range vals {
+		if v == val {
+			return true
 		}
 	}
-	return true
+	return false
 }
 
 // generateFileName appends the incoming file's name with a small random hash.