Protection of sensitive information in source code
package main
import (
"github.com/gin-gonic/gin"
)
type User struct {
Username string `json:"username"`
Password string `json:"password"`
Email string `json:"email"`
}
var users = []User{
{"admin", "123", "admin@example.com"},
{"test", "test", "test@example.com"},
}
func main() {
r := gin.Default()
r.GET("/users", func(c *gin.Context) {
c.JSON(200, users)
})
r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
The above Go code using the Gin framework is a simple server that handles a GET request to "/users" and responds with a JSON array of users. Each user is represented by a struct that contains a username, password, and email. The users are stored in an array in the source code, with the passwords and emails in plaintext.
This is a security vulnerability because sensitive information such as passwords and emails should not be stored in plaintext, especially in the source code. Anyone with access to the source code would have access to this sensitive information, and if the source code is ever exposed (for example, through a repository), that sensitive information would be exposed as well.
Furthermore, the server is exposing this sensitive information to anyone who sends a GET request to "/users". This is another security vulnerability, as this sensitive information should not be exposed to clients. Clients should only receive the minimum amount of information necessary for them to function, and passwords and emails are typically not necessary.
The best practice is to store sensitive information in a secure and encrypted form, such as through hashing passwords and not storing emails in the source code. Sensitive information should also not be exposed to clients unless absolutely necessary.
package main
import (
"github.com/gin-gonic/gin"
"os"
)
type User struct {
Username string `json:"username"`
Password string `json:"password"`
Email string `json:"email"`
}
var users = []User{
{os.Getenv("ADMIN_USERNAME"), os.Getenv("ADMIN_PASSWORD"), os.Getenv("ADMIN_EMAIL")},
{os.Getenv("TEST_USERNAME"), os.Getenv("TEST_PASSWORD"), os.Getenv("TEST_EMAIL")},
}
func main() {
r := gin.Default()
r.GET("/users", func(c *gin.Context) {
c.JSON(200, users)
})
r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
The original code had sensitive information such as usernames, passwords, and email addresses hardcoded into the source code. This is a security vulnerability as it exposes sensitive information to anyone who has access to the source code.
The fixed code removes these hardcoded values and instead retrieves them from environment variables using the
os.Getenv
function. This is a more secure practice as it allows sensitive information to be stored outside of the source code in a secure and encrypted manner.
In a production environment, these environment variables would be set through a secure secrets management solution, ensuring that sensitive information is not exposed.
It's important to note that sensitive information should never be logged or printed in error messages, and the source code repository should be regularly reviewed and audited for any accidental inclusion of sensitive information.
Remember to set the environment variables in your production environment before running the application.