Go

Go

Made by DeepSource

Sanitize insecure filename before use GO-S1000

Security
Critical
a03 sans top 25 owasp top 10

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
}

Bad practice

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")

Recommended

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")

References