
2026/08/18 2:55
dotenvy を fork して dotenv-ng にしました
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
SecretSpec が dotenv-ng 1.0 をリリースしました。これは、従来のツールに見つかった重大なセキュリティ欠陥を修正し、
bcrypt のパスワードハッシュに含まれるドル記号($)を誤って変数トリガーと解釈するといった問題を特に対処することを目的とした、安全に .env ファイルを解析・レンダリングするための Rust ライブラリです。本リリースは、互換性よりも安全性を最優先しています。メンテナンスされていない dotenvy(2023 年以降更新なし)や廃止された dotenv crate と異なり、dotenv-ng はドル記号をデフォルトで文字列として扱う、厳密なソース対応型のパーサーを採用しています。置換処理は呼び出し側が明示的に有効化した場合のみ利用可能であり、プロセス環境の変更の前に検証が行われ、明示的な unsafe 境界によって保護されています。さらに、このライブラリはダッシュや先頭の数字、ドット、ユニコード名を含むより広いキーの文法をサポートし、値をそのまま復元できる新しいレンダラーを採用しています。パーサーとレンダラー両方で 100% の行被率を持つプロパティテストを用いて構築されたこの根本的な改修では、ユーザーが従来の構成処理に伴うセキュリティリスクを回避するために、アクティブな移行が必要となります。本文
「dotenv-ng」1.0 リリース:機密情報管理のためのモダンな Rust インプールーム
私たちは、**「dotenv-ng」**1.0 をリリースしました。これは
.env ファイルを読み込み、レンダリングするための新たな Rust 実装です。本プロジェクトは、パース処理中に機密情報が誤って変更・露出する問題を解消するため、既存の dotenvy からフォークして始まりました。
背景と動機
SecretSpec のミッション
- 環境変数と機密情報の分離: 環境変数を機密情報のインターフェースとして廃止することが目標です。
- 現状の問題点:
ファイルそのものが問題を抱えています。.env - 移行の第一歩: 機密情報を最終的な保存場所にすべきではありませんが、移行を開始するにはまず .env ファイルを正しく読み込むことから始まります。
dotenvy をフォークした理由
直ちに解決が必要だったのは SecretSpec Issue #73 です。
.env ファイル内に bcrypt フラグメントを含む値が含まれていた場合のリスクについてです。
TEST="foo:$2a$10$TWoviNHS27HJMw1PKe4tBeIMlms6tWdYS9hKoHANKCQhluDlEt/gu"
- 問題の本質: ファイル自体には不備はありませんでした。
- dotenvy の欠陥:
プロバイダを通じてファイルを読み込ませた際、dotenv
がドル記号 (dotenvy
) で始まるフラグメントを**「変数置換」**として誤って処理しました。$ - 結果: 返された値が元の値と異なり、認証エラーという形で後から表面化しました。
メインテナンスのギャップ
Rust の公式
dotenv クレイトは 2020 年以来リリースされておらず、RustSec は dotenvy を「メンテナンスされていない」代替案として挙げています。
- 現状の実情:
の説明欄には「よくメンテナンスされたフォークである」と記載されていますが、最新バージョン (0.15.7) は 2023 年 3 月 22 日のリリースです。dotenvy - リリースギャップ: コミュニティ議論では 2 年以上のリリース不足が指摘されており、bcrypt のバグが発覚した時点ですでにその期間を超えていました。
- 皮肉な状況: メンテナンスされているフォーク自体が、上流クレイトーに見られる「リリース不足」を繰り返す事態になっています。
SecretSpec 側ではスケジュールを我々がコントロールする必要があるため、壊れやすい修正が求められており、期待に応えるメンテナーには頼むことができません。
dotenv-ng が向上させた点
当初は小さなパッチでの対応を検討しましたが、パース器の監査を通じて以下のような重大な問題が見つかりました:
- JSON 処理の不備
- Windows パス形式への対応不足
- ユニコード文字名の扱い
- 優先順位の誤り
- 部分的な環境変数の変更に関する不具合
これらを踏まえ、**
dotenv-ng は dotenvy 0.15.7 をベースとしつつ、「正解を得るために必要な場合に限って意図的に互換性を破る」**方針で開発されています。
バージョン 1.0 の主な新機能
- ソース情報の追跡: パース器にソース情報を考慮した機能と、構造化されたエラー報告機能を追加。
- 明示的な置換処理: デフォルトではドル記号 (
) をリテラルとして扱い、置換処理は呼び出し側が明示的に有効にする場合のみ実行します。$ - 拡張されたキー文法: ダッシュ字、先頭数字、先頭ドット、ユニコード文字を含むより広範なキーに対応。
- 安全なレンダリング: バリューをパースした状態を不変に戻すために必要なクォーテーションとエスケープ処理のみを追加する新しいレンダラーを採用。
- 書き換えの検証: プロセス環境への書き換えを行う前に、値を検証します。
- 安全性の境界定義: 書き換え処理を取り巻く明示的な**「非安全性 (unsafe) の境界」**を設定。
品質保証とコード品質
- プロパティテスト: 任意のユニコード文字や複雑な構文を持つ値を網羅的に検証し、クォーテーションが本当に必要な場合にのみ使用されることを確認。完全なドキュメントのラウンドトリップ(書き出し→読み込み)もチェックします。
- コードカバレッジ: パース器とレンダラーは、どちらもコードラインカバレッジ 100% を達成しています。
- 変更ログ: 完全な互換性と API の詳細な変更内容は、「dotenv-ng」1.0 の 変更ログ に記載されています。
dotenv-ng 1.0 を試してみる
このパッケージは crates.io で入手可能です。依存関係のエイリアスを使用することで、従来のクレイト名をそのまま維持して利用できます:
[dependencies] dotenv = { package = "dotenv-ng", version = "1" }
SecretSpec 0.20 以降では、
dotenv-ng が SecretSpec 全体での .env のパースおよびレンダリングを支えています。