The filename is always optional and must not be used blindly by the application, i.e., path information should be stripped, and you should do the conversion to the server's file system rules before using it.
Example below shows the insecure usage of the filename before sanitizing.
router.POST("/upload", func(c *gin.Context) {
// single file
file, _ := c.FormFile("file")
fmt.Fprintln(os.Stderr, file.Filename) // do not use file.Filename before sanitizing
}
router := gin.Default()
router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.POST("/upload", func(c *gin.Context) {
name, email := c.PostForm("name"), c.PostForm("email")
file, _ := c.FormFile("file")
// NOTE: file.Filename is very risky to use as it not
// sanitized.
c.SaveUploadedFile(file, file.Filename)
c.String(http.StatusOK, fmt.Sprintf(
"success: file=%s, name=%s, email=%s",
file.Filename, name, email),
)
})
router.Run(":8080")
router := gin.Default()
router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.POST("/upload", func(c *gin.Context) {
name, email := c.PostForm("name"), c.PostForm("email")
file, _ := c.FormFile("file")
// NOTE: We are sanitizing file.Filename here, i.e., filepath.Base
// returns the last element of the path. So we are stripping
// the path and returning just the last element of the
// path (separated by path separator).
filename := filepath.Base(file.Filename)
c.SaveUploadedFile(file, filename)
c.String(http.StatusOK, fmt.Sprintf(
"success: file=%s, name=%s, email=%s",
filename, name, email),
)
})
router.Run(":8080")