広告が嫌いですか? 行く 広告なし 今日

.envファイル — GitHubに秘密情報を漏らす6つの誤り

更新日

.envファイルの漏洩は、ハッカーによるものではなく、.gitignoreが設定される前に入力された開発者や、ライブデータを含む.env.exampleファイルを配布した、またはフレームワークがクライアントJSにサーバーの秘密情報を静かにバンドルした開発者が原因です。ここに実際に起こる6つの誤りを紹介します。

.env ファイル — GitHubにセレクトが漏れる6つの誤り 1

GitGuardianの2023年「セクレットの広がり」報告書によると、公開GitHubリポジトリに1200万件以上のセクレットがコミットされていることが判明した。多くは盗まれたものではなく、開発者が実際にそれを適切に扱ったと思い込んでアップロードしたものである。これらが原因となるパターンは以下の通りである。

1. 1回目のコミット後に.gitignoreを追加する

.gitignore は、未トラッキングファイルのみを追加するのを防ぎます。ファイルがすでにGitの履歴に含まれている場合、 に追加しても何も起こりません。Gitはそのファイルをまだトラッキングし、変更をコミットします。 ステージングされないファイル。一度ファイルが追跡されたら——たとえ一時的にでも——Gitの歴史に記録される。もしファイルを作成し .env、実行し git add . && git commit、その後に .env.gitignore を追加した場合、その変更以前のすべてのコミットにファイルが含まれている。

すでに歴史に存在するか確認する:

git log --all -- .env

それがコミットを返す場合、セクレットは歴史に存在している。まず認証情報を回転させ、その後、 git-filter-repogit filter-branch):

pip install git-filter-repo
git filter-repo --path .env --invert-paths

の推奨代替品)を使用して歴史からファイルを削除する。すべてのリモートに強制プッシュし、チームメンバーに再クローンを通知する。この処理により、その削除前のすべてのクローン(自動CIシステムを含む)にコミットが存在する。

2. .envを.env.exampleにコピーするが、値をクリーンアップしない

標準的なワークフロー:実際の値を持つ .env を作成し、それを .env.example にコピーして、チームメンバーにプロジェクトが必要なキーを示す。コピーが問題の所在である。

cp .env .env.example はすべてをコピーする——キー 値。そして .env.example はコミットされるべきである。それがその目的である。実際の値は .env.example に意図的に入っている。

❌ gitに残る内容:

DATABASE_URL=postgres://admin:supersecretpassword@prod-db.example.com/appdb
STRIPE_SECRET_KEY=sk_live_51AbcDefGhiJklMnopQrstUvwx...
JWT_SECRET=my-actual-production-jwt-secret

✅ 本来の内容: .env.example はプレースホルダー値で作成し、コミットした後、それを

DATABASE_URL=postgres://user:password@localhost:5432/appdb
STRIPE_SECRET_KEY=sk_live_YOUR_KEY_HERE
JWT_SECRET=generate-a-random-secret-min-32-chars

作成する .env.example にコピーし、実際の認証情報を埋め込む——逆の順序ではいけない。 .env 3. エラーハンドラーでプロセス.envをログ出力する

これはインシデント中に「一時的なデバッグ」として始まり、削除されない。あるいは、一般的なエラーメディエートで無害に見える。

実行時には、dotenvが読み込んだすべての変数およびシステム変数を含む。ログを出力する全オブジェクトを渡すことで、ログアグレゲーター、エラートレーキングサービス(Sentry、Datadog、Rollbar)、およびエラーナレッジ通知メールやWebhookに記録される。多くのサービスは、自社のアクセス制御を持つ第三者ストレージにデータを転送する。

// Classic debug line that makes it to production
console.log('Starting with config:', process.env);

// Generic error handler that dumps everything
app.use((err, req, res, next) => {
  logger.error({ config: process.env, error: err.message });
  res.status(500).json({ error: 'Internal server error' });
});

process.env 診断に必要な特定の値のみをログ出力する:

4. Dockerイメージレイヤーにセクレットを組み込む

logger.error({
  nodeEnv: process.env.NODE_ENV,
  appVersion: process.env.APP_VERSION,
  error: err.message,
  stack: err.stack
});

Dockerイメージの歴史に永続的にセクレットを埋め込む2つのパターン:

ファイルを後続のレイヤーで削除(

# Pattern 1: COPY bakes the entire .env into a layer
COPY .env .

# Pattern 2: ARG/ENV burns values into build metadata
ARG DATABASE_URL
ENV DATABASE_URL=$DATABASE_URL

)しても、値はイメージの歴史に読み取れる。画像のプルアクセスを持つ誰もが実行できる:RUN rm .envと、ビルド時のARG値を回収できる。Docker BuildKitのセクレットは、ビルド中にセクレットをマウントし、レイヤーに書かれない正しいツールである:

docker history --no-trunc your-image:tag

実行時の設定は、コンテナ開始時に

# syntax=docker/dockerfile:1
RUN --mount=type=secret,id=db_url     DATABASE_URL=$(cat /run/secrets/db_url) ./setup.sh

を介して環境変数を注入する。Docker Composeでホスト環境変数を参照する——決してハードコードされた値、決して docker run -e または environment: ‘d secret files。 COPY5. 生産環境に送られる弱いプレースホルダーのセクレットを使用する

は開発用プレースホルダーから始まり、場合によっては置き換えされない。攻撃者がJWT署名をブートフォースする際に、これらの文字列を積極的に試している——GitHub検索で出現するため、特別なワードリストに含まれている。

JWT_SECRET=secret, SESSION_SECRET=keyboard cat, APP_KEY=changeme, ENCRYPTION_KEY=1234567890abcdefを署名し、弱いシークレットを使用したJWTは、c-jwt-crackerなどのツールでオフラインで破られることができる。

1つの検拾された有効なトークンがあれば、シークレットをブートフォースし、任意のトークンを発行できる。 HS256 適切なシークレットは暗号的にランダムで、最小32バイト以上であるべきである。必要になる前に生成する——IO Toolsは、JWTキー、セッションシークレット、APIキーなどの一般的な.envシークレットに対して、設定不要で適切なランダム値を生成する。最初から設定し、プレースホルダーを使用して「プロダクション前に修正する」という計画を立てない。 6. フレームワークの環境変数規則により、セクレットがクライアントに漏れるいくつかのポピュラーなフレームワークは、変数名のプレフィックスを使ってクライアントとサーバーの可視性を決定する。これが間違っていると、アプリを読み込むすべてのブラウザにJavaScriptバンドルにセクレットが明文で送られる。

Next.js: 環境シークレットジェネレーター -prefixed変数はクライアントサイドにバンドルされる。しかし、サーバー側のセクレットは

propsを通じて漏れ、

が返されたすべての値はページHTMLにシリアル化され、ソースコードで読み取れる。

  • Vite: のみ NEXT_PUBLIC_変数が getServerSideProps にプレフィックスされ、クライアントJSにバンドルされる。実際の開発者が「利便性のため」使用するのは誤りである。 props Create React App:
  • 変数はクライアントバンドルに含まれ、例外がない。サーバー側のCRAランタイムは存在しない——すべてがブラウザに送られる。 ビルド後に出力ディレクトリを検索して、既知のセクレット値を確認する: VITE_ もしマッチが返された場合、そのセクレットはすべてのブラウザタブに存在している。すぐに回転し、バンドルされた他の内容を調査する。 VITE_DATABASE_URL 最初に構築すべき習慣
  • セクレットを保持するファイルを作成する前に、まず すべて REACT_APP_ を設定する——後回しにしない。新しいリポジトリの最初のコミットは、プレースホルダー値で

を設定するべきである。これにより、

grep -r "sk_live_" ./dist
grep -r "sk_live_" ./.next/static

は数分以内にフレームワークごとの完全な無視ファイルを生成する。

上記の6つの誤りは、コードを書く前にすべて防げられる。セクレットが暴露された後は、回転が唯一の解決策であり、それはすべての場所で回転する必要がある——サービスプロバイダー、コピーを保持したすべての環境、ログにキャッシュされた値を持つすべてのシステムである。

.envファイル — GitHubにセクレットが漏れる6つの誤り 2 .gitignore .envファイル — GitHubにセクレットが漏れる6つの誤り 1 .gitignore.env.example 多くの.envの漏洩はハッカーから来ていない——開発者が.gitignoreが設定されていない状態でファイルをコミットした、.env.exampleに実際の値を含めて配布した、またはフレームワークがサーバーのセクレットをクライアントJSに静かにバンドルしたことが原因である。以下が実際に起こる6つの誤りである。 .gitignore ジェネレーター 1分以内に、フレームワークごとの無視ファイルを完全に生成します。

上記の6つの誤りは、コードを書く前にすべて回避可能です。セレクトが暴露された後、唯一の解決策は回転することですが、それはすべての場所で行われなければなりません:サービスプロバイダー、コピーを保持していたすべての環境、ログに値がキャッシュされた可能性のあるすべてのシステムです。

広告なしで楽しみたいですか? 今すぐ広告なしで

拡張機能をインストールする

お気に入りのブラウザにIOツールを追加して、すぐにアクセスし、検索を高速化します。

に追加 Chrome拡張機能 に追加 エッジ拡張 に追加 Firefox 拡張機能 に追加 Opera 拡張機能

スコアボードが到着しました!

スコアボード ゲームを追跡する楽しい方法です。すべてのデータはブラウザに保存されます。さらに多くの機能がまもなく登場します!

ニュースコーナー 技術ハイライト付き

参加する

価値ある無料ツールの提供を継続するためにご協力ください

コーヒーを買って