Insecurely deleted files - Go

Insecurely deleted files - Go

Need

Secure deletion of files to prevent unauthorized retrieval of sensitive information

Context

  • Usage of Go 1.16 for building high-performance and scalable applications
  • Usage of Gin framework for building web applications in Go
  • Usage of os for accessing operating system-related information and functionalities

Description

Non compliant code

        package main

import (
	"github.com/gin-gonic/gin"
	"os"
)

func main() {
	r := gin.Default()
	r.GET("/deletefile", func(c *gin.Context) {
		filepath := c.Query("filepath")
		err := os.Remove(filepath)
		if err != nil {
			c.JSON(500, gin.H{
				"message": "Failed to delete the file",
			})
			return
		}
		c.JSON(200, gin.H{
			"message": "File deleted successfully",
		})
	})
	r.Run()
}
        
        

The above code is a simple server in Go using the Gin framework. It has a single route, /deletefile, which takes a filepath query parameter and attempts to delete the file at that path.

The vulnerability lies in the os.Remove(filepath) function. This function simply removes the directory entry of the file, but does not securely delete the file data. This means that the data of the file can still be recovered using specialized tools.

This is particularly problematic if the files being deleted contain sensitive information such as personal user data or confidential business information. An attacker who gains access to the physical storage could potentially recover these deleted files and gain access to the sensitive information.

Steps

  • Avoid using the os.Remove() function to delete files as it does not securely delete the files.
  • Instead, use a secure file deletion method that overwrites the file's content before deleting it.
  • One way to securely delete files is by using the shred command-line tool.
  • Before deleting a file, overwrite its content with random data using the shred command.
  • After overwriting the file's content, use the os.Remove() function to delete the file.
  • Ensure that the file path provided by the user is validated and sanitized to prevent directory traversal attacks.
  • Implement proper error handling and return appropriate error messages to the user if the file deletion fails.

Compliant code

        package main

import (
	"github.com/gin-gonic/gin"
	"io/ioutil"
	"os"
	"path/filepath"
)

func main() {
	r := gin.Default()
	r.GET("/deletefile", func(c *gin.Context) {
		filepath := c.Query("filepath")
		// Validate and sanitize the file path
		if !filepath.IsAbs(filepath) {
			c.JSON(400, gin.H{
				"message": "Invalid file path",
			})
			return
		}
		// Overwrite the file's content with random data
		err := ioutil.WriteFile(filepath, []byte("random data"), 0644)
		if err != nil {
			c.JSON(500, gin.H{
				"message": "Failed to overwrite the file",
			})
			return
		}
		// Delete the file
		err = os.Remove(filepath)
		if err != nil {
			c.JSON(500, gin.H{
				"message": "Failed to delete the file",
			})
			return
		}
		c.JSON(200, gin.H{
			"message": "File deleted successfully",
		})
	})
	r.Run()
}
        
        

The updated code includes a secure method for deleting files. Instead of directly deleting the file using os.Remove(), the file's content is first overwritten with random data using ioutil.WriteFile(). This ensures that even if the file is recovered, the original content will not be accessible.

The file path provided by the user is validated and sanitized using filepath.IsAbs(). This function checks if the file path is an absolute path. If it's not, an error message is returned to the user. This prevents directory traversal attacks where an attacker could manipulate the file path to access sensitive files.

Proper error handling is implemented. If overwriting the file's content or deleting the file fails, an error message is returned to the user. This helps in troubleshooting and provides a better user experience.

References