Skip to main content

Non-encrypted confidential information

Need

Secure storage of confidential information

Context

  • Usage of Go 1.16 for building high-performance and scalable applications
  • Usage of Gin for building web applications in Go
  • Usage of io/ioutil for reading and writing files in Node.js

Description

Non compliant code

package main

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

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

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

// Write the credentials to a file
ioutil.WriteFile("credentials.txt", []byte("Username: "+username+"\\nPassword: "+password), 0644)
})

r.Run() // listen and serve on 0.0.0.0:8080
}

In the above code snippet, a simple server is created using the Gin framework in Go. The server has one endpoint, /login, that accepts POST requests. The username and password from the form data of the POST request are being stored directly in a file called credentials.txt in plain text.

The vulnerability here is that the username and password are stored without any encryption. This means that if an attacker were to gain access to the credentials.txt file, they would be able to read the usernames and passwords without any additional effort.

This is a major security concern as it does not protect the confidentiality of the user's information. It is important to encrypt sensitive information before storing it to ensure it cannot be read if accessed by unauthorized individuals.

Steps

  • Use a secure method to store confidential information, such as passwords.
  • Avoid storing confidential information in plain text.
  • Encrypt the confidential information before storing it.
  • Use a secure storage mechanism, such as a database, to store the confidential information.
  • Implement secure authentication and authorization mechanisms to protect the confidential information.
  • Consider using a secure communication protocol, such as HTTPS, to transmit the confidential information.
  • Regularly review and update the security measures in place to protect the confidential information.

Compliant code

package main

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

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

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

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

// Write the credentials to a file
ioutil.WriteFile("credentials.txt", []byte("Username: "+username+"\\nPassword: "+string(hashedPassword)), 0644)
})

r.Run() // listen and serve on 0.0.0.0:8080
}

The original code was storing user credentials in plain text, which is a serious security vulnerability. If an attacker gains access to the file where the credentials are stored, they would be able to read and misuse them.

The updated code fixes this vulnerability by hashing the password before storing it. This is done using the bcrypt library, which is a powerful password hashing algorithm. Now, even if an attacker gains access to the file, they will only see the hashed password, which is useless without the original password.

In addition, it's recommended to store the hashed passwords in a secure storage mechanism, such as a database, instead of a plain text file. This code is just an example and should not be used in a production environment without further security measures.

Furthermore, it's important to handle errors returned by the bcrypt.GenerateFromPassword function. In this example, the error is ignored for simplicity, but in a real-world application, you should always check and handle errors appropriately.

Finally, consider using a secure communication protocol, such as HTTPS, to transmit the confidential information. This will protect the data in transit and prevent it from being intercepted by attackers.

References