Sensitive information stored in logs - Go

Sensitive information stored in logs - Go

Need

Protection of sensitive information in log files

Context

  • Usage of Go 1.16 for building efficient and scalable applications
  • Usage of Gin framework for building web applications in Go

Description

Non compliant code

        package main

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

func main() {
	r := gin.Default()

	r.POST("/login", func(c *gin.Context) {
		username := c.PostForm("username")
		password := c.PostForm("password")
		// some code to authenticate the user...

		// logging the sensitive information
		r.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) gin.LogEntry {
			return gin.LogEntry{
				Time:     param.Time,
				Method:   param.Method,
				Path:     param.Path,
				IP:       param.ClientIP,
				Error:    param.ErrorMessage,
				Username: username,
				Password: password,
			}
		}))
	})

	r.Run()
}
        
        

The above code is an example of a vulnerable backend application written in Go using the Gin framework. The application has a route /login that accepts POST requests. The request should contain a username and password in the form data.

The vulnerability lies in the logging middleware. The application logs sensitive information such as the username and password of the user. This information is logged each time a user tries to login.

The middleware LoggerWithFormatter is used to format the log entries. It returns a LogEntry struct that contains the time of the request, the method used (POST in this case), the path of the request (/login), the client's IP address, any error message, and the sensitive information (username and password).

This practice is highly insecure as it exposes sensitive user information in the application logs. If an attacker gains access to these logs, they can easily obtain the credentials of the users.

Steps

  • Avoid storing sensitive information in log files.
  • Identify the sensitive information that is being logged, such as credentials, bank accounts, and file paths.
  • Remove the logging of sensitive information from the code.
  • Consider using a logging library that supports log filtering or masking sensitive information.
  • If necessary, implement a custom log formatter to exclude sensitive information from the logs.
  • Ensure that the log files are properly secured and access is restricted to authorized personnel.
  • Regularly review and monitor the log files for any potential exposure of sensitive information.

Compliant code

        package main

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

func main() {
	r := gin.Default()

	r.POST("/login", func(c *gin.Context) {
		username := c.PostForm("username")
		password := c.PostForm("password")
		// some code to authenticate the user...

		// Remove the logging of sensitive information
		r.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) gin.LogEntry {
			return gin.LogEntry{
				Time:     param.Time,
				Method:   param.Method,
				Path:     param.Path,
				IP:       param.ClientIP,
				Error:    param.ErrorMessage,
			}
		}))
	})

	r.Run()
}
        
        

The original code was logging sensitive information such as username and password. This is a security vulnerability as it exposes sensitive user information in the logs.

The fixed code removes the logging of sensitive information. The LoggerWithFormatter function is used to format the log entries. However, the username and password are no longer included in the log entries.

This fix ensures that sensitive information is not exposed in the logs, reducing the risk of information leakage.

In addition to this, it is recommended to use a logging library that supports log filtering or masking sensitive information, to ensure that no sensitive information is accidentally logged. Also, the log files should be properly secured and access should be restricted to authorized personnel only. Regularly review and monitor the log files for any potential exposure of sensitive information.

References