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
⚠️
Important: This is an old article, and there is a new Prohibitable trait in Laravel 11 which solves this problem in a more elegant way. Head over to Security Tip #83 to learn more about it.

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;
    }
}

Found this security tip helpful? Don't forget to subscribe to receive new Security Tips each week, and upgrade to a premium subscription to receive monthly In Depth articles, or toss a coin in the tip jar.

Reach out if you're looking for a Laravel Security Audit and Penetration Test or a budget-friendly Security Review, and find me on the various socials through Pinkary. Finally, don't forget to check out Practical Laravel Security, my interactive security course.