Start here: https://github.com/laravel/framework/security/advisories
But version 6 is no longer supported, I suggest upgrading.
Also secure any file uploads, some good past post on all of this stuff.
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
Hey guys
I've been working with a legacy Laravel 6 codebase (a lot of spaghetti code), and we're having a problem where somebody is inserting a lot of trash, random users in our database sporadically
It has a pattern, like everyday at least one trash user is inserted, and there are somedays that 2 or more are inserted.
So I started investigating and I see that probably it is being done through the actual API endpoint for creating users (POST /admin/users/create), but it is protected by an 'auth' middleware, so it should be protected - I've already tried doing requests into it using Postman but it gives the 419 error because of the XRSF token (I tried adding this cookie forcefully in Postman but it gave the same error).
I believe that the problem is in this endpoint, because I've created a UserObserver to log suspicious users being created, and it is catching correctly the moment that these trash users are being created.
Let's look at it:
UserObserver.php
<?php
namespace App\Observers;
use App\User;
use Illuminate\Support\Str;
class UserObserver
{
public function created(User $user)
{
if (Str::endsWith($user->email, ['@gmail.com', '@yahoo.com'])) {
$creator = auth()->user();
\Log::channel('monitored_users')->info('User created using a suspicious email address', [
'user_id' => $user->id,
'email' => $user->email,
'ip_address' => request()->ip(),
'user_agent' => request()->userAgent(),
'creator_id' => $creator ? $creator->id : null,
'creator_email'=> $creator ? $creator->email : null,
]);
}
}
}
I configured it to display the user that is creating this suspicious user. It works when I do it by myself, logging like this:
[2025-04-01 21:43:47] dev.INFO: User created using a suspicious email address {"user_id":3,"email":"[email protected]","ip_address":"172.18.0.1","user_agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36","creator_id":2,"creator_email":"[email protected]"}
But when the intruder insert, it doesn't display its logged in user:
[2025-04-01 08:31:58] production.INFO: User created using a suspicious email address {"user_id":515,"email":"[email protected]","ip_address":"111.90.176.158","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36","creator_id":null,"creator_email":null}
I'm going to implement a middleware now that asks if the user is an admin of the system (yes, this check didn't exist in this API before - but existed in the interface, client code), but I'm a bit worried if it would have any other possible side effect.
Here goes a piece of my web.php:
<?php
Route::get('/', 'FrontEndController@index');
Auth::routes();
Route::permanentRedirect('/public', '/admin');
/* ADMIN */
Route::group(["prefix" => "admin", 'middleware' => ['auth']], function () {
// a bunch of other route groups
Route::group(['prefix' => 'users'], function () {
Route::get('', ['as' => 'auth', 'uses' => 'LoginController@index']);
Route::post('create', ['as' => 'users.create', 'uses' => 'LoginController@create']);
Route::post('edit', ['as' => 'users.edit', 'uses' => 'LoginController@edit']);
Route::get('{id}/edit', ['as' => 'users.edit', 'uses' => 'LoginController@edit']);
Route::put('{id}/update', ['as' => 'users.update', 'uses' => 'LoginController@update']);
Route::get('{id}/destroy', ['as' => 'users.destroy', 'uses' => 'LoginController@destroy']);
});
// a bunch of other route groups
// basically the whole system is inside this admin group =)
});
So after all of this, I configured the logger to not log only that things but log the whole request.
Maybe with only this information I gave it isn't possible to have conclusive assertions of what is happening, and considering that I might solve it with the 'admin' middleware wouldn't encourage you to answer me
But I'd really like some guidance in securing an Laravel application, so I would be able to check at my side what lead to this exposure, as I've already found other security breaches in this application (e.g., their Redis database was exposed to the internet, with this intruder changing it to read-only mode sporadically and breaking the system)
Thanks for your time =)
@pmattheew I’d instead be checking the server logs for the corresponding POST requests for the created users, which will also show which endpoint is being used to create the users in the first place.
So for example, if a “trash” user is created with the email address [email protected] then look in your raw server logs for the request with that email address in the request body, and you’ll be able to see what URI the request was sent to (and therefore the controller handling that request), and that’s where your vulnerability is.
Please or to participate in this conversation.