Enabled default credentials - Go

Enabled default credentials - Go

Need

Implementation of strong, unique credentials for all system resources

Context

  • Usage of Go 1.15 for building efficient and scalable applications
  • Usage of gin-gonic/gin for building web applications and APIs in Go
  • Usage of gorm for Object-Relational Mapping (ORM) in Go programming
  • Usage of GORM with PostgreSQL dialect for database operations

Description

Non compliant code

        package main

import (
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/postgres"
)

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

	db, err := gorm.Open("postgres", "host=localhost user=postgres dbname=postgres sslmode=disable password=postgres")
	if err != nil {
		panic("failed to connect database")
	}
	defer db.Close()

	r.Run() 
}
        
        

In the above code, we are using the Gin framework in a Go application to connect to a PostgreSQL database. The vulnerability lies in the database connection string, where we are using default credentials (username: "postgres", password: "postgres") to connect to the database.

This is a serious vulnerability as it allows anyone who can access the connection string to gain full access to your database. They can read, modify, or delete any data they want, leading to potential data loss, corruption, or unauthorized access to sensitive information.

The connection string with the default credentials is visible in the following line:

                db, err := gorm.Open("postgres", "host=localhost user=postgres dbname=postgres sslmode=disable password=postgres")

            


Here, gorm.Open is used to open a database connection with the specified driver ("postgres") and data source (the connection string). The connection string includes the host, user, database name, SSL mode, and password.

The user and password are both set to "postgres", which are default credentials for a PostgreSQL database. This is the main source of the vulnerability.

Steps

  • Step 1: Avoid using default credentials.
  • Step 2: Create a separate user with strong credentials for accessing the database.
  • Step 3: Store the database credentials securely, such as in environment variables or a configuration file.
  • Step 4: Update the code to use the secure credentials when connecting to the database.
  • Step 5: Ensure that the secure credentials are not exposed in any logs or error messages.
  • Step 6: Regularly review and update the database credentials to maintain security.

Compliant code

        package main

import (
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/postgres"
	"os"
)

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

	dbHost := os.Getenv("DB_HOST")
	dbUser := os.Getenv("DB_USER")
	dbName := os.Getenv("DB_NAME")
	dbPassword := os.Getenv("DB_PASSWORD")

	db, err := gorm.Open("postgres", "host="+dbHost+" user="+dbUser+" dbname="+dbName+" sslmode=disable password="+dbPassword)
	if err != nil {
		panic("failed to connect database")
	}
	defer db.Close()

	r.Run() 
}
        
        

The updated code now securely retrieves the database credentials from environment variables instead of using default credentials. This is done using the os.Getenv function, which retrieves the value of the environment variable specified by its string argument.

The DB_HOST, DB_USER, DB_NAME, and DB_PASSWORD environment variables are used to store the host, username, database name, and password for the database, respectively. These environment variables should be set in the environment where the application is running.

The connection string for the gorm.Open function is then constructed using these environment variables. This ensures that the application uses the secure credentials when connecting to the database.

This approach has several advantages:

1. It avoids the use of default credentials, which can be easily guessed by attackers. 2. It allows for the use of strong, unique credentials for each database, improving security. 3. It keeps the credentials out of the codebase, preventing them from being exposed in version control systems or logs. 4. It allows for easy rotation of credentials, as they can be changed in the environment without needing to update the code.

Remember to never hard-code sensitive information such as database credentials in your code. Always use secure methods like environment variables or secure configuration files to store this kind of data.

References