I've recently switched to environment based application deployments for Laravel and I've decided to store credentials for my local and production server in .env files using $_ENV however I've discovered when debugging is turned on and an exception is thrown the error displays the environment variables exposing database credentials.
Now I'm certain debugging will always be off on production because that's what I have it default to, then I override it in a local folder for my local environment however, what if somehow someway debugging is turned on on production and a user forces a 404 exception, all they need to do is read down the page until they see the environment variables in plain view exposing credentials. In the docs, it said it's best practice for any 'real' application to keep database credentials away from the actual config. I may be a bit paranoid here.
Is there a way I can limit what is shown in the debug screen displayed by laravel?
I just recently bumped into the same problem, while a project I was working on required me to temporarily open up my dev machine to the evil outside world to test some API callbacks.
Hereby, I exposed all my precious keys and passwords whenever whoops
was triggered. Even if it was a blind API callback machine, chances of them logging responses to their requests and some engineer sifting through them and finding some AWS keys, no thanks.
This is what I'm using now:
App::error(function (Exception $exception, $code)
{
// Never, ever, use environment variables in responses, not even when debugging
$_SERVER = array_except($_SERVER, array_keys($_ENV));
$_ENV = [];
});
Laravel uses Whoops (filp/whoops
) to create the debugging page, and you can see here that it uses $_ENV
to get the environment variables. While not ideal at all, you could simply empty $_ENV
in case an error is thrown in any environment other than local.
That is pretty straightforward to do by simply rewriting App::error
(and probably App::fatal
too) in app/start/global.php
to something like this:
App::error(function(Exception $exception, $code) {
Log::error($exception);
if (App::environment() !== 'local') {
$_ENV = [];
}
});
This works because the exception handler is called before the Whoops handler.
Now, the right, better way to do it would be to create a class extending Whoops\Handler\PrettyPageHandler
which would not display the environment variables or changing any other unwanted behavior and, based on the environment, register it as the whoops.handler
component for your app, similarly to how it's done on Illuminate\Exception\ExceptionServiceProvider:registerPrettyWhoopsHandler
. I don't think this is worth all that trouble, though.