Non-encrypted confidential information - Base 64 - Go

Non-encrypted confidential information - Base 64 - Go

Need

Secure storage of confidential information

Context

  • Usage of Go 1.16 for building high-performance and concurrent applications
  • Usage of gin-gonic/gin for building web applications in Go
  • Usage of net/http for creating HTTP servers in a Node.js application

Description

Non compliant code

        package main

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

var credentials = "QWxhZGRpbjpPcGVuU2VzYW1l" // "Aladdin:OpenSesame" in Base64

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

	r.GET("/secret", func(c *gin.Context) {
		user, password, _ := c.Request.BasicAuth()

		if user == "Aladdin" && password == "OpenSesame" {
			c.JSON(http.StatusOK, gin.H{"secret": "You have accessed the secret endpoint!"})
		} else {
			c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
		}
	})

	r.Run()
}
        
        

In the above code snippet, we have a simple Gin server with a /secret endpoint that checks for basic HTTP authentication.

The vulnerability lies in the credentials variable where the Base64-encoded string of the username and password ("Aladdin:OpenSesame") is stored directly in the source code. This is a security risk as anyone who has access to the source code can easily decode the Base64 string to retrieve the username and password.

The use of Base64 encoding is not a secure method of storing sensitive data because it can be easily decoded. It does not provide any form of encryption or obfuscation.

In this case, if an attacker gains access to the source code, they can easily decode the Base64 string and gain unauthorized access to the /secret endpoint.

Steps

  • Remove the hardcoded credentials from the source code.
  • Store the credentials securely, such as in a configuration file or environment variables.
  • Encrypt the confidential information before storing it.
  • Use a secure authentication mechanism, such as OAuth or JWT, instead of Basic Authentication.
  • Implement proper access control and authorization mechanisms to restrict access to sensitive endpoints.
  • Regularly review and update the security measures in place to protect confidential information.

Compliant code

        package main

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

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

	r.GET("/secret", func(c *gin.Context) {
		user, password, _ := c.Request.BasicAuth()

		if user == os.Getenv("USERNAME") && password == os.Getenv("PASSWORD") {
			c.JSON(http.StatusOK, gin.H{"secret": "You have accessed the secret endpoint!"})
		} else {
			c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
		}
	})

	r.Run()
}
        
        

The updated code removes the hardcoded Base64 credentials from the source code and instead retrieves them from environment variables. This is a more secure practice as it prevents the credentials from being exposed in the source code.

The environment variables USERNAME and PASSWORD should be set in the environment where the application is running. These can be set in a secure manner by the system administrator and can be changed regularly without needing to update the application code.

This is a simple fix for the given code snippet and context. However, for a more secure application, consider using a secure authentication mechanism such as OAuth or JWT instead of Basic Authentication. Also, implement proper access control and authorization mechanisms to restrict access to sensitive endpoints. Regularly review and update the security measures in place to protect confidential information.

References