Lack of protection against deletion
Need
Implementation of safeguards to prevent accidental deletion of critical objects
Context
- Usage of Go 1.16 for building high-performance and scalable applications
- Usage of gin-gonic/gin for building web applications in Go
Description
Non compliant code
package main
import (
"github.com/gin-gonic/gin"
)
type Object struct {
ID string `json:"id"`
}
var objects = make(map[string]Object)
func deleteObject(c *gin.Context) {
id := c.Param("id")
delete(objects, id)
c.JSON(200, gin.H{"status": "object deleted"})
}
func main() {
r := gin.Default()
r.DELETE("/object/:id", deleteObject)
r.Run()
}
This is a simple Gin application written in Go. It has a single endpoint /object/:id
that accepts DELETE requests. The deleteObject
function retrieves the id
from the request parameters and deletes the corresponding object from the objects
map.
The vulnerability lies in the deleteObject
function. It does not perform any checks before deleting an object. This means any object can be deleted, even if it's critical. If an attacker discovers the ID of a critical object, they can send a DELETE request to remove it. This could lead to loss of important data.
Additionally, there is no mechanism to prevent accidental deletion. A simple mistake could lead to the removal of critical objects. This also makes it hard to recover deleted objects since there is no backup or versioning system in place.
Steps
- Implement authentication and authorization mechanisms to ensure that only authorized users can delete objects.
- Add validation checks to ensure that the object being deleted is not critical or important.
- Implement a confirmation mechanism to prevent accidental deletion of objects.
- Consider implementing a soft delete mechanism instead of directly deleting objects, allowing for recovery if needed.
- Regularly backup the data to prevent permanent loss in case of accidental deletion.
Compliant code
package main
import (
"github.com/gin-gonic/gin"
)
type Object struct {
ID string `json:"id"`
IsCritical bool `json:"isCritical"`
}
var objects = make(map[string]Object)
func deleteObject(c *gin.Context) {
id := c.Param("id")
object, exists := objects[id]
if !exists {
c.JSON(404, gin.H{"status": "object not found"})
return
}
if object.IsCritical {
c.JSON(403, gin.H{"status": "cannot delete critical object"})
return
}
delete(objects, id)
c.JSON(200, gin.H{"status": "object deleted"})
}
func main() {
r := gin.Default()
r.DELETE("/object/:id", deleteObject)
r.Run()
}
The updated code includes several changes to address the vulnerability:
-
Object Structure: The
Object
struct now includes aIsCritical
boolean field. This field is used to mark objects that are critical and should not be deleted. -
Delete Function: The
deleteObject
function now includes checks to ensure that the object exists and is not marked as critical before deletion. If the object does not exist, a 404 status code is returned. If the object is marked as critical, a 403 status code is returned.
This code does not include authentication or authorization mechanisms, as these would depend on the specifics of your application. However, you should ensure that only authorized users can access the deleteObject
function.
Additionally, this code does not include a soft delete mechanism or regular backups. These are important considerations for preventing data loss, but they would also depend on the specifics of your application and are not included in this example.