Skip to main content

Sensitive information in source code - Credentials

Need

Protection of sensitive information in source code

Context

  • Usage of Go 1.16 for building high-performance and efficient applications
  • Usage of gin-gonic/gin for building web applications in Go

Description

Non compliant code

package main

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

const (
APIKey = "1234567890abcdef"
DBUser = "admin"
DBPassword = "password"
)

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

r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})

r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}

This is a simple Go server using the Gin framework. The server has a single endpoint /ping which responds with a JSON object containing a single key-value pair {"message": "pong"}.

The vulnerability lies in the declaration of sensitive information in the source code. The constants APIKey, DBUser, and DBPassword are storing sensitive information in plain text.

This is a serious security issue as anyone who has access to the source code can see these values. This could be a potential attacker who could use these credentials to gain unauthorized access to associated systems, such as the database or the API.

In addition, if the repository is public, these values can be viewed by anyone, increasing the risk of a security breach.

Even if the repository is private, storing credentials in the source code is still a bad practice as it does not allow for proper access control. For example, a developer who needs access to the code for bug fixing might not necessarily need access to the database credentials.

Furthermore, if these values need to be changed, the source code has to be updated and the server possibly restarted, which can lead to downtime.

In conclusion, sensitive information such as credentials should never be stored in the source code. They should be stored securely and accessed through secure means.

Steps

  • Remove sensitive information from the source code
  • Store sensitive information in a secure location such as environment variables or a configuration file
  • Use a secure method to access the sensitive information at runtime, such as reading from environment variables or a configuration file
  • Ensure that the secure location where the sensitive information is stored is properly protected and access is restricted
  • Regularly review and update the sensitive information to minimize the risk of exposure

Compliant code

package main

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

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

r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})

r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}

The original code contained sensitive information such as API keys and database credentials directly in the source code. This is a security vulnerability as it exposes these credentials to anyone who has access to the source code.

The updated code removes these sensitive details from the source code. Instead of hardcoding these values, they should be stored in environment variables or a secure configuration file. This way, the actual values are not exposed in the source code and can be securely accessed at runtime.

Here's how you can set environment variables in your operating system:

  • On Linux or MacOS, use the export command: export APIKey=your_api_key
  • On Windows, use the set command: set APIKey=your_api_key

Then, in your Go code, you can access these environment variables using the os package:

apiKey := os.Getenv("APIKey")
dbUser := os.Getenv("DBUser")
dbPassword := os.Getenv("DBPassword")

Remember to never store sensitive information in your source code. Always use secure methods to store and access such information.

References