Are you an LLM? You can read better optimized documentation at /analyzers/security/filament-navigation.md for this page in Markdown format
Filament Navigation Analyzer
| Analyzer ID | Category | Severity | Time To Fix |
|---|---|---|---|
filament-navigation | 🛡️ Security | Medium | 10 minutes |
What This Checks
Validates that Filament navigation items have proper permission gates. Checks for:
- Resources hidden via
shouldRegisterNavigation()but missingcanAccess()- the URL remains directly reachable canAccess()orshouldRegisterNavigation()that only checks authentication, not authorization (weak gate)- Resources with sensitive navigation groups (e.g., "Admin", "System", "Users") that have no visibility gate
- Navigation badges that may leak count information without authorization
- Custom navigation items in panel providers without visibility controls
Why It Matters
- Security by Obscurity Fails: Hiding a navigation item does not protect the route: users can still reach it via direct URL.
shouldRegisterNavigation()only controls sidebar visibility;canAccess()is required for actual route protection. - Weak Gates:
canAccess()returningtrueorauth()->check()allows any authenticated panel user to access sensitive resources regardless of their role or permissions. - Information Disclosure: Navigation badges showing counts (e.g., "42 Users") leak data to unauthorized users.
- Attack Surface: Visible admin navigation reveals application structure to potential attackers.
How to Fix
Quick Fix (5 minutes)
Add visibility controls to sensitive resources:
php
// app/Filament/Resources/UserResource.php
class UserResource extends Resource
{
public static function shouldRegisterNavigation(): bool
{
return auth()->user()?->hasRole('admin');
}
}Proper Fix (10 minutes)
1. Control badge visibility:
php
class OrderResource extends Resource
{
public static function getNavigationBadge(): ?string
{
if (!auth()->user()?->can('viewAny', Order::class)) {
return null;
}
return static::getModel()::where('status', 'pending')->count();
}
}2. Add visibility to custom navigation items:
php
// In your PanelProvider
->navigationItems([
NavigationItem::make('Analytics')
->url('/analytics')
->icon('heroicon-o-chart-bar')
->visible(fn () => auth()->user()?->hasPermission('view-analytics')),
])3. Control navigation group visibility:
php
class PaymentResource extends Resource
{
protected static ?string $navigationGroup = 'Finance';
public static function shouldRegisterNavigation(): bool
{
return auth()->user()?->hasRole(['admin', 'accountant']);
}
}References
Related Analyzers
- Filament Panel Security - Validates panel authentication
- Filament Custom Pages - Validates page authorization
- Filament Widget Security - Validates widget authorization