如何在Laravel的Whoops输出中隐藏.env密码?

75

如何在Laravel的whoops输出中隐藏我的密码和其他敏感的环境变量?

有时其他人会查看我的开发工作。如果抛出异常,我不希望他们看到这些机密信息,但我也不想一直开关调试或启动专用站点进行快速预览。

显示密码的 whoops 输出截图

12个回答

112

截至于 Laravel 5.5.13 版本,您可以通过在 config/app.php 中将变量列在关键字 debug_blacklist 下来进行变量的遮蔽。当抛出异常时,Whoops 将用星号 * 掩盖这些值的每个字符。

例如,给定此 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',
        ],
    ],
];

此输出结果中包含:

错误异常页面


1
可能有用的是为Laravel文档提交pull request。 - Christophvh
@JeffPuckett 哦,你说得对,我错误地认为.13比.4低,就像小数位一样。 - ii7scw
这在 Laravel 5.7 中不起作用的原因是什么?我在 Laravels Foundations 下找到了 WhoosHander 中的 registerBlacklist,但据我所知它并没有被使用。 - Adam Patterson

79

首先,感谢Jeff提出的解决方案。

其次,如果像我一样想要隐藏所有环境变量但仍然使用Whoops,则可以使用以下解决方案:

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

输出:

enter image description here

编辑: 传说自laravel 7版本起,需要使用debug_hide密钥代替。


24
谢谢您。我仍然困惑为什么人们希望在每个错误时在屏幕上打印所有环境变量。 - warmwhisky
6
没错,也许有10%的人想要它,但不是90%的Laravel开发者! - Raheel Hasan
8
听听!几个月前我不小心泄露了我的邮件枪API密钥,导致超过1200封网络钓鱼邮件通过我的账户发送出去。太可怕了!如果我需要查看我的环境变量,我会老派地打开它来查看! - warmwhisky
4
没错!如果我想要了解我的环境变量,我会打开环境变量文件,而不是意外地在一个我完全不知道的页面上暴露环境变量一周左右。 - Raheel Hasan
1
谢谢。非常好的答案。 - user2094178
显示剩余5条评论

12

感谢Jeff和Raheel的帮助,但是我刚刚发现了一个小问题:

即使我从_ENV中清除了所有环境变量键,相同的键仍然通过列出的_SERVER变量被暴露出来。

config/app.php中添加以下代码将隐藏所有环境变量从whoops页面中:

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

除了您的代码中少了 cookie 行之外,这与 Raheel 的答案有什么不同吗?或者他是在您的回答之后编辑过他的答案吗? - Marcel Cozma
5
"_SERVER" => array_keys($_SERVER) 和 "_SERVER" => array_keys($_ENV) 之间有微妙但重要的区别。 - erlangsec

8
我已经制作了一个解决这个问题的软件包

只需使用以下命令进行安装:

composer require glaivepro/hidevara

大多数服务器和所有环境变量将被删除。在$_POST中类似密码的字段将被隐藏其值。

您还可以根据黑名单或白名单方式自定义,以显示/混淆/移除字段,以满足您的需求。


8

@jeff和@raheel提出的解决方案非常好!最近,在一个项目中,我们发现有时想要列出一两个属性,因此在上述基础上,您可以使用以下方式列出您想要调试的特定属性:

'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()),
],

如果你想通过.env文件配置列表,你可以像这样做:
'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', ""))
    ),
],

然后在你的 .env 文件中,做如下修改:

DEBUG_SERVER_WHITELIST="APP_URL,QUERY_STRING"

干杯!


我想提一下,这可以添加在 app.php 中。 - Jesse Orange

6

通常在本地开发中,我们应该将 APP_DEBUG 环境变量设置为true,这样我们可以更好地了解调试错误和警告信息。

但是在生产环境中,该值应始终为false。如果在生产环境中将该值设置为true,则可能会将敏感的环境密码暴露给应用程序的最终用户。

Laravel 5.5.x也提供了一个解决方案

您只需要在 config/app.php 配置文件中添加 debug_blacklist 选项即可。添加此选项后,Laravel 将使用星号黑名单选项中提到的所有密钥。

您可以使用以下两种方法之一:

方法1-黑名单选择性的 ENV 键和密码

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

方法二 - 将所有ENV密钥和密码列入黑名单

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

参考来源: https://techjeni.com/how-to-secure-and-hide-env-passwords-from-laravel-debug-output/

本文介绍如何从Laravel调试输出中安全隐藏.env密码。

4
我的 Laravel 5.6 无法正常工作。 但是这个可以:
$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,
    ],
];

我希望能得到更好的解决方案。


2

只需更改

APP_DEBUG=true 

To:

APP_DEBUG=false

在 .env 文件中。

是的,在生产环境中很不错,但问题陈述指出我现在处于开发阶段,因此我希望在这种环境下获得 Whoops 提供的所有其他便利。 - Jeff Puckett

0

我在生产环境中也遇到了这个问题,Laravel 5.7 https://laravel.com/docs/5.7/configuration

这里有三种方法可以解决这个问题。

config/app.php 文件中添加以下代码行

TIPS #1: 所有变量的阻止列表

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

提示 #2: 针对特定变量的块级列表(最佳实践)

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',
      ],
 ]

提示 #3:调试变量

将 APP_DEBUG=true 改为 APP_DEBUG=false

注意:

生产环境始终保持调试关闭状态


0
这里有很多优秀的答案(感谢@Jeff,@Raheel和@Benjamin以及其他人的贡献),但是我想要一个更加灵活和通用的解决方案。我进一步扩展了这个片段,适用于config/app.php文件:
$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,
];

然后你可以直接在.env中黑名单和白名单,只保留你需要的内容。

所以如果你不需要$_ENV中的任何内容,你可以阻止所有变量,例如只保留$_POST中的密码,但是显示$_SERVER中的APP_URLQUERY_STRING

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接