Security controls bypass or absence - Fingerprint - Go

Security controls bypass or absence - Fingerprint - Go

Need

Enhancement of security controls for fingerprint identification

Context

  • Usage of Go 1.16 for building high-performance and scalable applications
  • Usage of Gin framework for building web applications in Go

Description

Non compliant code

        package main

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

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

	r.POST("/auth", func(c *gin.Context) {
		var user User
		if err := c.ShouldBindJSON(&user); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}

		// Authentication without fingerprint
		if user.Username == "admin" && user.Password == "password" {
			c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
		} else {
			c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
		}

	})

	r.Run()
}

type User struct {
	Username string `json:"username"`
	Password string `json:"password"`
}
        
        

In the above code, we have a simple authentication endpoint /auth which accepts a JSON payload with username and password fields. The application checks if the username and password match a hardcoded admin user and password. If they match, the server responds with a success message, if not, it responds with an unauthorized message.

The vulnerability here is that the application is not using any form of fingerprinting to identify the client. This means that any client can send a request with the correct username and password and they will be authenticated as the admin user. This is a security risk as it allows an attacker to bypass any form of client identification and impersonate the admin user.

An additional security risk is that the password is hardcoded and stored in plaintext in the source code. This makes it easy for an attacker to discover the password and use it to authenticate as the admin user.

The application should be updated to include some form of client fingerprinting, such as device fingerprinting or IP address tracking, to ensure that only authorized clients can authenticate as the admin user. The password should also be stored in a secure manner, such as hashed and salted, to prevent it from being discovered by an attacker.

Steps

  • Implement fingerprint authentication as an additional security control.
  • Integrate a fingerprint recognition library or API to capture and verify the user's fingerprint.
  • Modify the authentication logic to include fingerprint verification along with username and password.
  • If the fingerprint verification fails, return an unauthorized response.
  • Ensure that the fingerprint data is securely stored and handled to protect user privacy.
  • Regularly update and patch the fingerprint recognition library or API to address any security vulnerabilities.

Compliant code

        package main

import (
	"github.com/gin-gonic/gin"
	"github.com/fingerprintRecognition/fingerprint" // hypothetical fingerprint recognition library
	"net/http"
)

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

	r.POST("/auth", func(c *gin.Context) {
		var user User
		if err := c.ShouldBindJSON(&user); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}

		// Authentication with fingerprint
		if user.Username == "admin" && user.Password == "password" {
			// Verify the fingerprint
			if fingerprint.Verify(user.Fingerprint) {
				c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
			} else {
				c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
			}
		} else {
			c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
		}

	})

	r.Run()
}

type User struct {
	Username    string `json:"username"`
	Password    string `json:"password"`
	Fingerprint string `json:"fingerprint"`
}
        
        

The updated code now includes fingerprint authentication as an additional security control.

A hypothetical fingerprint recognition library fingerprintRecognition/fingerprint is imported to handle the fingerprint verification. This library should provide a function Verify that takes a fingerprint data and returns a boolean indicating whether the fingerprint is valid or not.

The User struct is updated to include a Fingerprint field. This field should contain the user's fingerprint data, which is sent in the JSON request body along with the username and password.

The authentication logic is modified to include fingerprint verification. If the username and password are correct, the server then verifies the fingerprint. If the fingerprint verification fails, the server returns an unauthorized response.

Please note that the fingerprint data should be securely stored and handled to protect user privacy. Also, the fingerprint recognition library or API should be regularly updated and patched to address any security vulnerabilities.

References