Atlas Capital
CS
🟠 HIGH HAVOC-2026-001 Authorization Coverage Analyzer Open

Missing Authorization Gate — bulkConfirm()

app/Http/Controllers/TransactionController.php:142 coopers98/atlas-abs
app/Http/Controllers/TransactionController.php Lines 133–155
133class TransactionController extends Controller
134{
135 public function index(Project $project): View
136 {
137 $this->authorize('view', $project);
138 return view('transactions.index', compact('project'));
139 }
140
141 public function bulkConfirm(Request $request, Project $project): JsonResponse
142 {
143 // ⚠ HAVOC: No authorization check found
144 $validated = $request->validate([
145 'transaction_ids' => 'required|array',
146 'transaction_ids.*' => 'uuid|exists:transactions,id',
147 ]);
148
149 Transaction::whereIn('id', $validated['transaction_ids'])->
150 update(['status' => 'confirmed']);
151
152 return response()->json(['message' => 'Transactions confirmed']);
153 }
154
155 public function show(Project $project, Transaction $transaction): View

What is this vulnerability?

The bulkConfirm() method on TransactionController modifies the status of multiple transactions but contains no authorization check.

While the method validates that the transaction IDs exist in the database, it does not verify that the authenticated user has permission to confirm those transactions — or that those transactions belong to the project being accessed.

Impact: An authenticated user could confirm transactions belonging to a different project or organization by crafting a request with transaction IDs they don't own. This is a classic Insecure Direct Object Reference (IDOR) vulnerability with privilege escalation potential.

Recommended Fix

Add an authorization check before processing the request. Laravel's authorization gate should verify the user can perform bulk confirmations on this project:

Suggested fix — TransactionController.php +2 lines
public function bulkConfirm(Request $request, Project $project): JsonResponse
{
+   $this->authorize('bulkConfirm', $project);
+
    $validated = $request->validate([
        'transaction_ids' => 'required|array',
        'transaction_ids.*' => 'uuid|exists:transactions,id',
    ]);

+   // Also scope to this project to prevent IDOR
    Transaction::whereIn('id', $validated['transaction_ids'])
+       ->where('project_id', $project->id)
        ->update(['status' => 'confirmed']);

Also add the corresponding policy method to app/Policies/ProjectPolicy.php:

ProjectPolicy.php
public function bulkConfirm(User $user, Project $project): bool
{
    return $project->organization_id === $user->organization_id
        && $user->hasRole(['ORG_ADMIN', 'PROJECT_MANAGER']);
}
Finding Details
Severity HIGH
Status Open
Analyzer Authorization Coverage
Repository coopers98/atlas-abs
File TransactionController.php
Line 142
First Seen Mar 1, 2026 — scan #118
Last Seen Mar 4, 2026 — scan #127
Scan Count 10 scans
Confidence
97%
🤖 AI Analysis

This is a true positive with high confidence. The pattern matches a classic missing authorization gate before a state-changing bulk operation. The surrounding code shows other methods properly use $this->authorize(), making this an oversight rather than intentional design.

Analyzed by Claude Sonnet · Mar 4, 2026