How to hide .env passwords in Laravel whoops output?

PhpLaravelEnvironment VariablesSecret KeyWhoops

Php Problem Overview


How can I hide my passwords and other sensitive environment variables on-screen in Laravel's whoops output?

Sometimes other people are looking at my development work. I don't want them to see these secrets if an exception is thrown, but I also don't want to have to keep toggling debug on and off, or spin up a dedicated site just for a quick preview.

whoops output screenshot with passwords shown

Php Solutions


Solution 1 - Php

As of Laravel 5.5.13, you can censor variables by listing them under the key debug_blacklist in config/app.php. When an exception is thrown, whoops will mask these values with asterisks * for each character.

For example, given this config/app.php

return [

    // ...

    'debug_blacklist' => [
        '_ENV' => [
            'APP_KEY',
            'DB_PASSWORD',
            'REDIS_PASSWORD',
            'MAIL_PASSWORD',
            'PUSHER_APP_KEY',
            'PUSHER_APP_SECRET',
        ],
        '_SERVER' => [
            'APP_KEY',
            'DB_PASSWORD',
            'REDIS_PASSWORD',
            'MAIL_PASSWORD',
            'PUSHER_APP_KEY',
            'PUSHER_APP_SECRET',
        ],
        '_POST' => [
            'password',
        ],
    ],
];

Results in this output:

whoops exception page

Solution 2 - Php

First of all, love the solution by Jeff above.

2nd, if like me you wanna hide all the env variables while still use whoops, here is a solution:

'debug_blacklist' => [
        '_COOKIE' => array_keys($_COOKIE),
        '_SERVER' => array_keys($_SERVER),
        '_ENV' => array_keys($_ENV),        
    ],

Output:

enter image description here

EDIT: Legend has it that since laravel 7x you would need debug_hide key instead

Solution 3 - Php

Thanks Jeff and Raheel for helping out, but I just found a little gotcha:

Even if I clear out all environment keys from _ENV, the same keys are STILL exposed through the _SERVER variables listed.

Adding the code below in config/app.php would hide all environment variables from the whoops page:

'debug_blacklist' => [
        '_SERVER' => array_keys($_ENV),
        '_ENV' => array_keys($_ENV),        
],

Solution 4 - Php

I've made a package to solve this problem.

Just install it using

composer require glaivepro/hidevara

Most of the server and all the env variables will be removed. Any password-like fields in $_POST will have their values hidden.

You can also customize it in either blacklist or whitelist approach to show/obfuscate/remove fields however you like.

Solution 5 - Php

The solution by @jeff + @raheel is great!!! On a project recently we found we sometimes wanted to whitelist a property or two, so building on the above, you can whitelist specific properties you want to debug with something like:

'debug_blacklist' => [
    '_COOKIE' => array_diff(array_keys($_COOKIE), array()),
    '_SERVER' => array_diff(array_keys($_SERVER), array('APP_URL', 'QUERY_STRING')),
    '_ENV' => array_diff(array_keys($_ENV), array()),
],

If you want to allow that list to be configured via .env, you can do something like:

'debug_blacklist' => [
    '_COOKIE' => array_diff(
        array_keys($_COOKIE),
        explode(",", env('DEBUG_COOKIE_WHITELIST', ""))
    ),
    '_SERVER' => array_diff(
        array_keys($_SERVER),
        explode(",", env('DEBUG_SERVER_WHITELIST', ""))
    ),
    '_ENV' => array_diff(
        array_keys($_ENV),
        explode(",", env('DEBUG_ENV_WHITELIST', ""))
    ),
],

Then in your .env, do something like:

DEBUG_SERVER_WHITELIST="APP_URL,QUERY_STRING"

Cheers!

Solution 6 - Php

Usually for local development, we should set the APP_DEBUG environment variable to true. So that we can have better insights of the debugging error and warnings.

But in the production environment, this value should always be false. If the value is set to true in production, you risk exposing sensitive env passwords to your application’s end users.

As of Laravel 5.5.x also provides a solution for it.

You just need to add the debug_blacklist option in your config/app.php configuration file. After adding this option, Laravel will blacklist all the keys mentioned in debug_blacklist option with asterisk.

You can use it with two ways:

Method 1 – Blacklist selective ENV keys and passwords

return [
    // ...
    'debug_blacklist' => [
        '_ENV' => [
            'APP_KEY',
            'DB_PASSWORD',
        ],
        '_SERVER' => [
            'APP_KEY',
            'DB_PASSWORD',
        ],
        '_POST' => [
            'password',
        ],
    ],
];

Method 2 – Blacklist all the ENV keys and passwords

return [
 // ...
'debug_blacklist' => [
  '_COOKIE' => array_keys($_COOKIE),
  '_SERVER' => array_keys($_SERVER),
  '_ENV' => array_keys($_ENV),
  ],
]

Reference Taken From : https://techjeni.com/how-to-secure-and-hide-env-passwords-from-laravel-debug-output/

Solution 7 - Php

Laravel 5.6 not works for my. but this works:

$envKeys = [];
$serverKeys = [];
$cookieKeys = [];
foreach ( $_ENV as $key => $value ) { if(is_string($value)) $envKeys[] = $key; }
foreach ( $_SERVER as $key => $value ) { if(is_string($value)) $serverKeys[] = $key; }
foreach ( $_COOKIE as $key => $value ) { if(is_string($value)) $cookieKeys[] = $key; }

return [

    // ...

    'debug_blacklist' => [
        '_COOKIE'   => $cookieKeys,
        '_SERVER'   => $serverKeys,
        '_ENV'      => $envKeys,
    ],
];

I would be grateful for a better solution.

Solution 8 - Php

Just Change

APP_DEBUG=true 

To:

APP_DEBUG=false

In the .env file.

Solution 9 - Php

For Laravel 5.6-5.8:

'debug_blacklist' => [
    '_COOKIE'   => array_keys(array_filter($_COOKIE, function($value) {return is_string($value);})),
    '_SERVER'   => array_keys(array_filter($_SERVER, function($value) {return is_string($value);})),
    '_ENV'      => array_keys(array_filter($_ENV, function($value) {return is_string($value);})),
],

Solution 10 - Php

I am also facing this issue in production environment, Laravel 5.7 https://laravel.com/docs/5.7/configuration

Here 3 ways we can reslove this issue.

config/app.php file add below line of code

TIPS #1: Block List for all variable

'debug_blacklist' => [
    '_COOKIE' => array_keys($_COOKIE),
    '_SERVER' => array_keys($_SERVER),
    '_ENV' => array_keys($_ENV),        
],

TIPS #2: Block List for specific varaibles (Best Practice)

return [

    // ...
    '_ENV' => [
          'APP_KEY',
          'DB_PASSWORD',
          'REDIS_PASSWORD',
          'MAIL_PASSWORD',
          'PUSHER_APP_KEY',
          'PUSHER_APP_SECRET',
          'AWS_APP_SECRET',
          'S3_BUCKET_SECRET',
          'SOCKET_APP_SECRET',
          'TWILIO_APP_SECRET',
     ],
     '_SERVER' => [
          'APP_KEY',
          'DB_PASSWORD',
      ],
      '_POST' => [
          'password',
      ],
 ]

TIPS #3: Debug variable

APP_DEBUG=true to APP_DEBUG=false

NOTE:

> Production enviroment keep always Debug False

Solution 11 - Php

There's a lot of great answers here (credits to @Jeff and @Raheel and @Benjamin and everyone else), but I would like to have a bit more flexible and universal solution. I extended this snippet intended for the config/app.php file even further:

$debug_blacklist=array();
if(env("DEBUG_VAR_LISTING")!==null)
    foreach(explode(",", env("DEBUG_VAR_LISTING", "")) as $i){
        global ${"_{$i}"};
        if(env("DEBUG_VAR_BLACKLIST_{$i}")!==null)
            $debug_blacklist["_{$i}"]=explode(",", env("DEBUG_VAR_BLACKLIST_{$i}", ""));
        elseif(env("DEBUG_VAR_WHITELIST_{$i}")!==null)
            $debug_blacklist["_{$i}"]=array_diff(
                array_keys(${"_{$i}"}),
                explode(",", env("DEBUG_VAR_WHITELIST_{$i}", ""))
            );
    }

return [
    'debug_blacklist' => $debug_blacklist,
];

Then you can blacklist and whitelist directly in .env and only if and what you need.

So if you don't really need anything from $_ENV you can block all variables and for example just passwords in $_POST, but show APP_URL and QUERY_STRING from $_SERVER:

DEBUG_VAR_LISTING="SERVER,ENV,POST,COOKIE"
DEBUG_VAR_WHITELIST_SERVER="APP_URL,QUERY_STRING"
DEBUG_VAR_WHITELIST_ENV=""
DEBUG_VAR_BLACKLIST_POST="password"

Solution 12 - Php

I struggled with this too for a bit on a dev machine. my solution was to edit vendor/filp/whoops/src/Whoops/Handler/PrettyPageHandler.php and add in:

public function sanitizePrivate($data, $badwords){
    foreach ($data as $key=>$value) {
       
        foreach ($badwords as $keyword) {
               // dd($key);
            if (strpos(strtolower($key), $keyword) !== FALSE) {
                $data[$key] = "***************";
            }
        }
    }
    return $data;
}

This converts all the incoming data to lowercase and then searches for partial matches so you don't have to specify every variation of password variable names. Then in the handle() function, define terms you want to exclude.

$badwords = array("password", "pwd", "secret", "key", "token", "salt", "mail");
$_SERVER=$this->sanitizePrivate($_SERVER, $badwords);
$_ENV=$this->sanitizePrivate($_ENV, $badwords);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJeff PuckettView Question on Stackoverflow
Solution 1 - PhpJeff PuckettView Answer on Stackoverflow
Solution 2 - PhpRaheel HasanView Answer on Stackoverflow
Solution 3 - PhperlangsecView Answer on Stackoverflow
Solution 4 - PhpDžurisView Answer on Stackoverflow
Solution 5 - PhpBenjamin ListwonView Answer on Stackoverflow
Solution 6 - PhpJenis PatelView Answer on Stackoverflow
Solution 7 - PhpOhne Not SilasView Answer on Stackoverflow
Solution 8 - PhpTest CheckView Answer on Stackoverflow
Solution 9 - Phpuser1576840View Answer on Stackoverflow
Solution 10 - PhpvenkatskpiView Answer on Stackoverflow
Solution 11 - PhpGGetsView Answer on Stackoverflow
Solution 12 - PhpAlanView Answer on Stackoverflow