Security Tip: Disable Dev & Test Commands in Production

[Tip#6] Because sometimes being paranoid is a good thing.

Security Tip: Disable Dev & Test Commands in Production

👉 Looking to dive deeper into Laravel security? Check out Practical Laravel Security, my hands-on security course that uses interactive hacking challenges to teach you about how vulnerabilities work, so you can avoid them in your own code! 🕵️

Worried about your app being hacked? Book in a Laravel Security Audit and Penetration Test! I can find the vulnerabilities before a hacker does, and help you fix them! 🕵️


If you’re like me, you’ll have some Artisan commands in your projects that run development and/or testing tasks. These commands manipulate data in some way and are definitely not safe to run on production.

This is what I do to stop dev & test Artisan commands being accidently run:

  1. Block execution of the command within the `handle()` method by checking the environment. I usually throw an error message and return an invalid response.
public function handle()
{
    if (! app()->isLocal()) {
        $this->error('This command can only be used in dev!');
        return Command::INVALID;
    }

    // ...
}
  1. Hide the command from `php artisan` by returning `true` from a `isHidden()` method on the command. This just keeps Artisan a bit cleaner.
public function isHidden()
{
    return ! app()->isLocal();
}
  1. There is no step three. 😎

Depending on the environments you need to target, there are a few different conditionals you can use:

// By name
app()->environment('local')

// Multiple by name
app()->environment('local', 'testing')

// 'local'
app()->isLocal()

// 'testing'
app()->runningUnitTests()

// 'production'
app()->isProduction()

Finally, putting it all together into a command so you can see all the pieces in action:

<?php
namespace App\Console\Commands;

use Illuminate\Console\Command;

class DevHelper extends Command
{
    /** @var string */
    protected $signature = 'dev:helper';

    /** @var string */
    protected $description = 'Perform an important dev task.';

    public function isHidden()
    {
        return ! app()->isLocal();
    }

    public function handle()
    {
        if ($this->isHidden()) {
            $this->error('This command can only be used in dev!');
            return Command::INVALID;
        }

        // ...

        return Command::SUCCESS;
    }
}