Sensitive information sent insecurely - Go

Sensitive information sent insecurely - Go

Need

Secure transmission of sensitive information

Context

  • Usage of Go 1.16 for building efficient and scalable applications
  • Usage of gin-gonic/gin 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")

		// Assume these are correct credentials
		c.JSON(200, gin.H{
			"username": username,
			"password": password,
		})
	})

	r.Run() 
}
        
        

In the above Go code, we are using the Gin Web Framework to create a simple server with a login route. The /login route accepts a POST request with a form data containing username and password.

The vulnerability lies in the fact that the server sends back the username and password in the response JSON. This is a bad practice as it exposes sensitive information, in this case, the user's credentials. If the communication channel is not secure (like HTTP instead of HTTPS), the data can be easily intercepted by malicious actors.

Furthermore, even if the channel is secure, the sensitive information should not be returned back to the client as it could be logged or stored in places where it shouldn't be.

Steps

  • Step 1: Use HTTPS instead of HTTP to ensure secure communication.
  • Step 2: Implement SSL/TLS certificates to encrypt the data transmitted over the network.
  • Step 3: Use secure protocols such as TLS 1.2 or higher to establish a secure connection.
  • Step 4: Avoid sending sensitive information in the request body or URL parameters.
  • Step 5: Hash and salt passwords before storing them in the database.
  • Step 6: Use secure authentication mechanisms such as JWT (JSON Web Tokens) or OAuth.
  • Step 7: Implement proper access controls and authorization mechanisms to restrict access to sensitive information.
  • Step 8: Regularly update and patch the server and framework to address any security vulnerabilities.
  • Step 9: Perform security testing and code reviews to identify and fix any potential vulnerabilities.
  • Step 10: Educate developers about secure coding practices and the importance of protecting sensitive information.

Compliant code

        package main

import (
	"github.com/gin-gonic/gin"
	"golang.org/x/crypto/bcrypt"
)

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

	r.POST("/login", func(c *gin.Context) {
		username := c.PostForm("username")
		password := c.PostForm("password")

		// Hash and salt password
		hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)

		// Assume these are correct credentials
		c.JSON(200, gin.H{
			"username": username,
			"password": string(hashedPassword),
		})
	})

	r.RunTLS(":443", "/path/to/ssl/cert.pem", "/path/to/ssl/key.pem") 
}
        
        

The updated code now uses HTTPS for secure communication by calling r.RunTLS() instead of r.Run(). This method requires the paths to the SSL certificate and key files as arguments.

Sensitive information, in this case the password, is now hashed and salted using the bcrypt package before being sent in the response. This ensures that even if the data is intercepted, the actual password will not be exposed.

Please note that this is a basic example and real-world applications would require additional security measures. For instance, the hashed password should be compared with the stored hash in the database for authentication. Also, the actual paths to the SSL certificate and key files should be used in the r.RunTLS() method.

Furthermore, it's important to avoid sending sensitive information in the response. This example still includes the hashed password in the response for illustrative purposes, but in a real-world application, you would typically not include it.

Lastly, remember to use secure authentication mechanisms such as JWT (JSON Web Tokens) or OAuth, implement proper access controls and authorization mechanisms, regularly update and patch the server and framework, perform security testing and code reviews, and educate developers about secure coding practices.

References