デバッグ Proto 表現のデシリアライズ処理

Protocol Buffers でデバッグ情報をログに記録する方法。

バージョン 30.x 以降、Protobuf の DebugString API (Message::DebugStringMessage::ShortDebugStringMessage::Utf8DebugString)、追加の Protobuf API (proto2::ShortFormatproto2::Utf8Format)、Abseil 文字列関数 (absl::StrCatabsl::StrFormatabsl::StrAppendabsl::Substitute など )、および Abseil ロギング API は、proto 引数を新しいデバッグ形式に自動的に変換し始めます。関連する発表についてはこちらをご覧ください。

Protobuf DebugString 出力形式とは異なり、新しいデバッグ形式では、機密フィールドの値を文字列「[REDACTED]」(引用符なし) に置き換えることで、機密フィールドを自動的にリダクションします。さらに、この新しい出力形式が、基になる proto に SPII フィールドが含まれているかどうかに関わらず、Protobuf TextFormat パーサーによってデシリアライズされないようにするために、この記事を指すランダム化されたリンクのセットと、ランダム化された長さの空白シーケンスを追加します。新しいデバッグ形式は次のようになります。

goo.gle/debugstr
spii_field: [REDACTED]
normal_field: "value"

新しいデバッグ形式は、DebugString 形式の出力形式と 2 つの点で異なることに注意してください。

  • URL プレフィックス
  • SPII フィールドの値は「[REDACTED]」(引用符なし) に置き換えられます

新しいデバッグ形式はフィールド名を削除することは決してありません。フィールドが機密と見なされる場合にのみ、値を「[REDACTED]」に置き換えます。 出力に特定のフィールドが表示されない場合は、それらのフィールドが proto に設定されていないためです。

ヒント: URL しか表示されない場合は、proto が空です!

なぜここに URL があるのですか?

システムをデバッグする人間向けに意図された protobuf メッセージの人間可読な表現を誰もデシリアライズしないようにしたいと考えています。歴史的に、.DebugString()TextFormat は互換性があり、既存のシステムは DebugString を使用してデータを転送および保存しています。

機密データが誤ってログに記録されないようにしたいと考えています。そのため、protobuf メッセージを文字列 ("[REDACTED]") に変換する前に、一部のフィールド値を透過的にリダクションしています。これにより、誤ったロギングのセキュリティとプライバシーのリスクが軽減されますが、他のシステムがメッセージをデシリアライズするとデータ損失のリスクがあります。このリスクに対処するために、ログメッセージで使用される人間可読なデバッグ形式から機械可読な TextFormat を意図的に分離しています。

これは意図的なものであり、protos の「デバッグ表現」(たとえば、ロギングによって生成される) を TextFormat と互換性のないものにするためです。デバッグメカニズムに依存してプログラム間でデータを転送することを防ぎたいと考えています。歴史的に、デバッグ形式 (DebugString API によって生成される) と TextFormat は、互換性のある方法で誤って使用されてきました。この意図的な取り組みが今後それを防ぐことを願っています。

コンテキストを提供する機会を得るために、目立たない形式の変更ではなく、意図的にリンクを選択しました。これは、Web ページのテーブルにステータス情報を表示する場合など、UI で目立つ可能性があります。代わりに TextFormat::PrintToString を使用できます。これは、情報をリダクションせず、フォーマットを保持します。ただし、この API は慎重に使用してください。組み込みの保護機能はありません。経験則として、データをデバッグログに書き込む場合、またはステータスメッセージを生成する場合は、リンク付きのデバッグ形式を引き続き使用する必要があります。現在機密データを処理していなくても、システムが変更され、コードが再利用される可能性があることに注意してください。

このメッセージを TextFormat に変換しようとしましたが、プロセスを再起動するたびに形式が変わることに気づきました。

これは意図的なものです。このデバッグ形式の出力を解析しようとしないでください。予告なしに構文を変更する権利を留保します。デバッグ形式の構文は、不注意な依存関係を防ぐためにプロセスごとにランダムに変更されます。デバッグ形式の構文の変更によってシステムが破損する場合、proto のデバッグ表現を使用するのではなく、TextFormat API を使用する必要がある可能性が高くなります。

FAQ

どこでも TextFormat を使用できますか?

ログメッセージの生成に TextFormat を使用しないでください。これはすべての組み込み保護をバイパスし、機密情報を誤ってログに記録するリスクがあります。システムが現在機密データを処理していなくても、これは将来変更される可能性があります。

デバッグ表現または TextFormat のいずれかを適切に使用して、ログを他のシステムによるさらなる処理を目的とした情報と区別します。

人間可読性と機械可読性の両方が必要な構成ファイルを作成したい

このユースケースでは、TextFormat を明示的に使用できます。構成ファイルに PII が含まれていないことを確認するのはあなたの責任です。

ユニットテストを作成しており、テストアサーションで DebugString を比較したい

protobuf の値を比較する場合は、次のように MessageDifferencer を使用してください。

using google::protobuf::util::MessageDifferencer;
...
MessageDifferencer diff;
...
diff.Compare(foo, bar);

フォーマットとフィールド順序の違いを無視することに加えて、より良いエラーメッセージも得られます。