Insecure object reference - User deletion - Go

Insecure object reference - User deletion - Go

Need

Enhancement of user deletion process and session management

Context

  • Usage of Go 1.16 for building high-performance and scalable applications
  • Usage of gin-gonic/gin for building web applications and APIs in Go
  • Usage of net/http for building HTTP servers in a Node.js application

Description

Non compliant code

        package main

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

type User struct {
	ID string `json:"id"`
}

var Users = []User{
	{ID: "1"},
	{ID: "2"},
	{ID: "3"},
}

func deleteUser(c *gin.Context) {
	id := c.Param("id")
	for i, user := range Users {
		if user.ID == id {
			Users = append(Users[:i], Users[i+1:]...)
			c.JSON(http.StatusOK, gin.H{"status": "user deleted"})
			return
		}
	}
	c.JSON(http.StatusNotFound, gin.H{"status": "user not found"})
}

func main() {
	r := gin.Default()
	r.DELETE("/users/:id", deleteUser)
	r.Run()
}
        
        

This code defines a simple web server using the Gin framework in Go. It has an array of users and a function deleteUser that deletes a user with a given ID from the array.

The deleteUser function is vulnerable to insecure object reference because it does not verify if the user who is trying to delete a user is authorized to do so. Any user can delete any other user just by knowing their ID.

Furthermore, after a user is deleted, the user's session is not terminated. The user can continue to interact with the application until their session expires naturally. This could lead to unexpected behavior as the application might still consider the deleted user as authenticated and authorized.

Steps

  • Implement authentication and authorization mechanisms to ensure that only authorized users can delete other users.
  • Validate the user's session or token before allowing the deletion of a user.
  • Ensure that the user deleting the account is the owner of the account or has the necessary permissions.
  • Update the deletion logic to also invalidate the user's session or token to prevent further access.
  • Consider implementing a soft delete mechanism instead of permanently removing the user from the system.
  • Regularly review and update the code to address any new vulnerabilities or security risks.

Compliant code

        package main

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

type User struct {
	ID string `json:"id"`
}

var Users = []User{
	{ID: "1"},
	{ID: "2"},
	{ID: "3"},
}

func deleteUser(c *gin.Context) {
	// Validate the user's session or token
	if !validateSession(c) {
		c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
		return
	}

	id := c.Param("id")
	for i, user := range Users {
		if user.ID == id {
			// Ensure that the user deleting the account is the owner of the account or has the necessary permissions
			if !hasPermission(c, user) {
				c.JSON(http.StatusForbidden, gin.H{"status": "forbidden"})
				return
			}

			Users = append(Users[:i], Users[i+1:]...)
			// Invalidate the user's session or token
			invalidateSession(c)
			c.JSON(http.StatusOK, gin.H{"status": "user deleted"})
			return
		}
	}
	c.JSON(http.StatusNotFound, gin.H{"status": "user not found"})
}

func validateSession(c *gin.Context) bool {
	// Implement your session validation logic here
	return true
}

func hasPermission(c *gin.Context, user User) bool {
	// Implement your permission checking logic here
	return true
}

func invalidateSession(c *gin.Context) {
	// Implement your session invalidation logic here
}

func main() {
	r := gin.Default()
	r.DELETE("/users/:id", deleteUser)
	r.Run()
}
        
        

The updated code now includes several security measures to prevent unauthorized deletion of users and to ensure the integrity of the system.

Firstly, we validate the user's session or token before allowing the deletion of a user. This is done in the validateSession function, which should contain your session validation logic. If the session or token is not valid, we return a 401 Unauthorized status.

Next, we check if the user has the necessary permissions to delete the account. This is done in the hasPermission function, which should contain your permission checking logic. If the user does not have the necessary permissions, we return a 403 Forbidden status.

After the user is deleted, we invalidate the user's session or token to prevent further access. This is done in the invalidateSession function, which should contain your session invalidation logic.

These measures help to ensure that only authorized users can delete other users, and that once a user is deleted, they can no longer access the system.

References