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 →Reusable Migration Fields with Custom Blueprint Macros
Extend Laravel's Blueprint class with custom macros to standardize and reuse common schema columns across database migrations.
Define Custom Macros on the Eloquent Builder
Register reusable query methods directly on the Builder so every model gains access without repeating logic.