CVE-2026-77780 Overview
CVE-2026-77780 is an authorization bypass vulnerability in Roskus Prospero Flow CRM versions 4.9.1 through 5.14.0. The flaw resides in the transaction save endpoint at POST /transaction/save. An authenticated user with transaction and accounting creation permissions can submit a bank_account_id or bank_card_id belonging to another company. The application persists and renders this data without validating company ownership. This exposes another company's bank account name, bank name, and card last four digits [CWE-639].
Critical Impact
Authenticated tenants can disclose cross-tenant financial metadata by supplying arbitrary foreign key identifiers in transaction submissions.
Affected Products
- Roskus Prospero Flow CRM 4.9.1 through 5.14.0
- TransactionSaveController (Laravel controller handling POST /transaction/save)
- TransactionSaveRequest form request validator
Discovery Timeline
- 2026-08-21 - CVE-2026-77780 published to NVD
- 2026-08-21 - Last updated in NVD database
Technical Details for CVE-2026-77780
Vulnerability Analysis
Prospero Flow CRM is a multi-tenant Laravel application where each company owns its own bank accounts, bank cards, customers, and suppliers. The transaction save workflow accepts foreign key identifiers from the authenticated user's request body. The controller wrote these identifiers directly into the transactions table without verifying that the referenced records belonged to the caller's company.
A user with legitimate transaction creation rights in company A can submit a request referencing bank_account_id or bank_card_id values that belong to company B. When the transaction is later rendered, the application loads and displays the related bank account name, bank name, and card last four digits from company B. This is an Insecure Direct Object Reference pattern classified under [CWE-639: Authorization Bypass Through User-Controlled Key].
Root Cause
The root cause is missing tenant scoping on foreign key inputs. The TransactionSaveRequest validation rules did not constrain bank_account_id, bank_card_id, customer_id, supplier_id, or transaction_category_id to records owned by the authenticated user's company. Laravel's default exists rule verifies row existence but not ownership.
Attack Vector
Exploitation requires authenticated access with transaction and accounting creation permissions. The attacker enumerates or guesses numeric identifiers and submits them to the transaction save endpoint. No user interaction from the victim tenant is required. The disclosed data is stored and re-rendered on subsequent views of the transaction.
// Patch: app/Http/Controllers/Transaction/TransactionSaveController.php
use App\Http\Controllers\MainController;
use App\Http\Requests\TransactionSaveRequest;
+use App\Models\Bank\Account as BankAccount;
+use App\Models\BankCard;
+use App\Models\Customer;
+use App\Models\Supplier;
use App\Models\Transaction;
+use App\Models\Transaction\Category as TransactionCategory;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
// Patch: app/Http/Requests/TransactionSaveRequest.php
use App\Http\Requests\Concerns\SanitizesInput;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
+use Illuminate\Validation\Rule;
class TransactionSaveRequest extends FormRequest
{
Source: GitHub Commit 5fd1fe8. The fix imports the related models and Laravel's Rule class to enforce that submitted foreign keys resolve to records owned by the authenticated user's company.
Detection Methods for CVE-2026-77780
Indicators of Compromise
- Transactions with bank_account_id or bank_card_id values that do not resolve to the owning company's records in the bank_accounts or bank_cards tables.
- Application log entries showing POST /transaction/save requests followed by rendered bank metadata not belonging to the caller's tenant.
- Sequential or enumeration-style access patterns against the transaction save endpoint from a single authenticated session.
Detection Strategies
- Run a database audit query joining transactions to bank_accounts and bank_cards on the respective IDs and flag rows where transactions.company_id differs from the referenced record's company_id.
- Review web server access logs for high-frequency POST /transaction/save submissions with varying bank_account_id or bank_card_id values from the same user.
- Add server-side logging that records the resolved company owner of every foreign key referenced on transaction submission.
Monitoring Recommendations
- Alert on any transaction where the referenced bank account, bank card, customer, or supplier belongs to a different company_id than the transaction itself.
- Baseline normal per-user transaction submission rates and alert on deviations that suggest ID enumeration.
How to Mitigate CVE-2026-77780
Immediate Actions Required
- Upgrade Prospero Flow CRM to a version containing the fix from Pull Request 261 that succeeds 5.14.0.
- Audit the transactions table for rows whose bank_account_id, bank_card_id, customer_id, or supplier_id resolve to a different company_id.
- Rotate or mask any disclosed bank account names, bank names, and card last four digits, and notify affected tenants where cross-tenant disclosure is confirmed.
Patch Information
The upstream fix is applied in commit 5fd1fe8 via Pull Request 261. The patch adds imports for BankAccount, BankCard, Customer, Supplier, and TransactionCategory, and uses Laravel's Rule facility in TransactionSaveRequest to constrain foreign key identifiers to records owned by the authenticated user's company. Additional detail is provided in the Securo Security Advisory for CVE-2026-77780.
Workarounds
- Restrict transaction and accounting creation permissions to a minimal set of trusted users until the patch is applied.
- Add a middleware or controller guard that resolves each foreign key on POST /transaction/save and rejects requests where the record's company_id does not match the authenticated user's company.
- Temporarily disable rendering of related bank account and bank card metadata on transaction detail views to limit disclosure while a fix is being deployed.
# Verify installed version and pull the fixed release
cd /path/to/prospero-flow-crm
git fetch --tags
git checkout <fixed-tag-after-5.14.0>
composer install --no-dev --optimize-autoloader
php artisan config:clear && php artisan route:clear
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

