Insufficient data authenticity validation - Checksum verification - Go

Insufficient data authenticity validation - Checksum verification - Go

Need

Ensure data authenticity through proper checksum verification

Context

  • Usage of Go 1.16 for building efficient and scalable applications
  • Usage of gin-gonic/gin for building web applications in Go
  • Usage of net/http for creating HTTP servers in a Node.js application
  • Usage of io/ioutil for reading and writing files in Node.js

Description

Non compliant code

        package main

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

func main() {
	r := gin.Default()
	
	r.GET("/loadExternalResources", func(c *gin.Context) {
		resp, err := http.Get("http://external-server/resource")
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Unable to load resource"})
			return
		}
		defer resp.Body.Close()

		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Unable to read resource"})
			return
		}
		c.JSON(http.StatusOK, body)
	})

	r.Run() 
}
        
        

This Go code snippet represents a simple server using the Gin framework. The server has a single endpoint, /loadExternalResources, which loads a resource from an external server.

The vulnerability lies in the /loadExternalResources handler. This handler makes a GET request to an external server to retrieve a resource. However, it does not perform any validation or verification of the received resource.

The lack of validation makes it susceptible to the "Insufficient data authenticity validation
- Checksum verification" vulnerability. An attacker could potentially intercept the request and replace the resource with malicious content. The server would then use this malicious resource, thinking it's the original one.

The server should instead verify the authenticity and integrity of the received resource, for example by comparing a checksum of the received resource with a known good checksum. If the checksums do not match, the server should not use the received resource.

Steps

  • Implement checksum verification for the loaded resource
  • Generate a checksum for the resource before loading it
  • Compare the generated checksum with the received checksum
  • If the checksums do not match, reject the resource
  • Use a secure hashing algorithm for generating the checksum

Compliant code

        package main

import (
	"crypto/sha256"
	"encoding/hex"
	"io/ioutil"
	"net/http"
	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	
	r.GET("/loadExternalResources", func(c *gin.Context) {
		resp, err := http.Get("http://external-server/resource")
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Unable to load resource"})
			return
		}
		defer resp.Body.Close()

		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Unable to read resource"})
			return
		}

		// Generate the checksum for the received resource
		hash := sha256.Sum256(body)
		receivedChecksum := hex.EncodeToString(hash[:])

		// Get the expected checksum from the external server
		resp, err = http.Get("http://external-server/resource/checksum")
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Unable to get checksum"})
			return
		}
		defer resp.Body.Close()

		expectedChecksum, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Unable to read checksum"})
			return
		}

		// Compare the received checksum with the expected checksum
		if receivedChecksum != string(expectedChecksum) {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Checksum verification failed"})
			return
		}

		c.JSON(http.StatusOK, body)
	})

	r.Run() 
}
        
        

The updated code now includes a checksum verification process for the resources loaded from the external server. This is done to ensure the integrity and authenticity of the resources.

The process is as follows:

1. The resource is loaded from the external server. 2. A SHA-256 checksum is generated for the loaded resource. 3. The expected checksum is retrieved from the external server. 4. The generated checksum is compared with the expected checksum. 5. If the checksums match, the resource is accepted and returned in the response. 6. If the checksums do not match, an error message is returned in the response.

This way, the application can ensure that the resources loaded from the external server have not been tampered with during transmission.

References