-
Notifications
You must be signed in to change notification settings - Fork 616
Description
Summary
The Invoice model is missing the HasTenantScope trait, allowing users from Team A to access, modify, and delete invoices belonging to Team B.
Root Cause
All multi-tenant models in the application correctly use the HasTenantScope trait to scope queries to the current team:
| Model | HasTenantScope | Status |
|---|---|---|
| Client | ✅ Yes (line 14) | Secure |
| Project | ✅ Yes | Secure |
| Task | ✅ Yes | Secure |
| Status | ✅ Yes | Secure |
| WorkSession | ✅ Yes | Secure |
| Contractor | ✅ Yes | Secure |
| Invoice | ❌ No | Vulnerable |
Vulnerable file: app/Models/Invoice.php (lines 10-14)
The Invoice model uses HasFactory, SoftDeletes, and HasUlids, but NOT HasTenantScope. It has a team_id foreign key and a team() relationship, but without the global scope, Filament resource queries don't filter by team.
Impact
Any authenticated user in a different team can:
- View another team's invoices (financial data disclosure)
- Edit another team's invoices (data manipulation)
- Delete another team's invoices (data destruction)
This affects the InvoiceResource in the Filament panel, where getEloquentQuery() only removes SoftDeletingScope but doesn't add team filtering.
Fix
Add the missing HasTenantScope trait to the Invoice model:
use App\Models\Scopes\HasTenantScope;
class Invoice extends Model
{
use HasFactory;
use SoftDeletes;
use HasUlids;
use HasTenantScope; // <-- Add thisThis is a one-line fix that brings Invoice in line with all other multi-tenant models in the application.