Insecure encryption algorithm - Default encryption - Go

Insecure encryption algorithm - Default encryption - Go

Need

Implementation of secure encryption algorithms and the use of customer-controlled keys for enhanced data protection.

Context

  • Usage of Go 1.16 for building high-performance and concurrent applications
  • Usage of the AWS SDK for Go to interact with the AWS services
  • Usage of AWS SDK Go's session package for managing AWS sessions
  • Usage of AWS Key Management Service (KMS) for encryption and decryption in Go
  • Usage of gin-gonic/gin for building web applications in Go

Description

Non compliant code

        package main

import (
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/kms"
	"github.com/gin-gonic/gin"
)

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

	r.GET("/encrypt", func(c *gin.Context) {
		sess, _ := session.NewSession(&aws.Config{
			Region: aws.String("us-west-2")},
		)

		svc := kms.New(sess)

		input := &kms.EncryptInput{
			KeyId:     aws.String("alias/aws/kms"), // using default AWS managed key
			Plaintext: []byte("exampleplaintext"),
		}

		result, _ := svc.Encrypt(input)

		c.JSON(200, gin.H{
			"ciphertext": result.CiphertextBlob,
		})
	})

	r.Run()
}
        
        

In the above Go code, we are using the AWS Key Management Service (KMS) to encrypt some plaintext. The EncryptInput struct is being initialized with a KeyId of "alias/aws/kms", which corresponds to the default AWS managed key.

This is insecure because it means that AWS has control over the encryption and decryption keys. If AWS were to be compromised, or if an AWS employee were to act maliciously, they could potentially decrypt your data.

The code is also not taking full advantage of the KMS service. AWS KMS allows you to create and manage your own customer master keys (CMKs), which give you more control over your encryption keys. For example, you can define your own key rotation policy, and you can choose to disable a key to make the data it was used to encrypt irretrievable.

In addition, using a CMK allows you to audit key usage, because every use of the key is logged in AWS CloudTrail. This is not possible when using the default AWS managed key.

Steps

  • Replace the default AWS managed key with a Customer Managed Key (CMK) in the KeyId field of the EncryptInput struct.
  • Create a Customer Managed Key (CMK) in the AWS Key Management Service (KMS) console.
  • Update the KeyId field in the code with the ARN (Amazon Resource Name) of the CMK.
  • Ensure that the IAM role or user associated with the application has the necessary permissions to use the CMK.
  • Test the application to verify that it is now using the Customer Managed Key (CMK) for encryption.

Compliant code

        package main

import (
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/kms"
	"github.com/gin-gonic/gin"
)

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

	r.GET("/encrypt", func(c *gin.Context) {
		sess, _ := session.NewSession(&aws.Config{
			Region: aws.String("us-west-2")},
		)

		svc := kms.New(sess)

		input := &kms.EncryptInput{
			KeyId:     aws.String("arn:aws:kms:us-west-2:111122223333:key/abcd1234a1234b56c123d1234e123456"), // using Customer Managed Key (CMK)
			Plaintext: []byte("exampleplaintext"),
		}

		result, _ := svc.Encrypt(input)

		c.JSON(200, gin.H{
			"ciphertext": result.CiphertextBlob,
		})
	})

	r.Run()
}
        
        

The above code is a fixed version of the vulnerable code. The vulnerability was that the code was using the default AWS managed key for encryption, which is less secure than using a Customer Managed Key (CMK).

In the fixed code, the KeyId field of the EncryptInput struct is updated to use a CMK. The KeyId is set to the ARN (Amazon Resource Name) of the CMK, which is created in the AWS Key Management Service (KMS) console.

The ARN in the code is a placeholder and should be replaced with the ARN of your actual CMK. The format of the ARN is "arn:aws:kms:region:account-id:key/key-id".

Please ensure that the IAM role or user associated with the application has the necessary permissions to use the CMK.

After updating the code, test the application to verify that it is now using the CMK for encryption.

References