Use Response::denyAsNotFound() in policies to return a 404 Not Found response instead of 403 Forbidden, concealing the existence of private resources.
Returning HTTP 403 Forbidden on confidential resources (such as private repositories, draft invoices, or secret project boards) tells attackers that the resource exists, leaking information.
Laravel policies support Response::denyAsNotFound() to return a 404 response directly from authorization checks.
Policy Implementation
namespace App\Policies;
use App\Models\Project;
use App\Models\User;
use Illuminate\Auth\Access\Response;
class ProjectPolicy
{
public function view(User $user, Project $project): Response
{
if ($project->is_confidential && $project->owner_id !== $user->id) {
// Returns HTTP 404 instead of 403 Forbidden
return Response::denyAsNotFound('Project not found.');
}
return Response::allow();
}
}
Summary
- Throws a
NotFoundHttpException(404) rather thanAuthorizationException(403). - Prevents resource enumeration attacks on private URL identifiers.
- Keeps authorization logic centralized inside Policy classes.
Related Tips
View all tips →Avoid Duplicating Authorization Logic with Gate::define() and Gate::authorize()
Centralize authorization checks in Gate::define() and call Gate::authorize() in controllers instead of repeating manual if checks.
Grant Global Super Admin Permissions with Gate::before()
Use Gate::before() in AppServiceProvider to grant master administrator privileges across all policies and authorization checks.