デバッグ Proto 表現のデシリアライズ
バージョン 30.x から、Protobuf の DebugString API (Message::DebugString、Message::ShortDebugString、Message::Utf8DebugString)、追加の Protobuf API (proto2::ShortFormat、proto2::Utf8Format)、Abseil の文字列関数 (absl::StrCat、absl::StrFormat、absl::StrAppend、absl::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があるのですか?
私たちは、システムをデバッグする人間を意図したプロトバフメッセージの人間が読める表現を誰も逆シリアル化しないようにしたいと考えています。歴史的に、.DebugString() と TextFormat は交換可能であり、既存のシステムは DebugString をデータの転送と保存に使用していました。
機密データが誤ってログに記録されないようにしたいと考えています。そのため、プロトコルバッファメッセージを文字列 (「[REDACTED]」) に変換する前に、一部のフィールド値を透過的に編集しています。これにより、誤ったログ記録によるセキュリティとプライバシーのリスクが軽減されますが、他のシステムがメッセージを逆シリアル化した場合にデータ損失のリスクが生じます。このリスクに対処するため、機械可読な TextFormat と、ログメッセージで使用される人間可読なデバッグ形式を意図的に分割しています。
なぜ私のWebページにリンクがあるのですか?なぜ私のコードはこの新しい「デバッグ表現」を生成するのですか?
これは意図的なもので、プロトの「デバッグ表現」(例えば、ログ記録によって生成される)をTextFormatと互換性のないものにしています。私たちは、プログラム間でデータを転送するためにデバッグメカニズムに誰も依存しないようにしたいと考えています。歴史的に、デバッグ形式(DebugString APIによって生成される)とTextFormatは、誤って交換可能な方法で使用されてきました。この意図的な取り組みが、今後それを防ぐことを願っています。
文脈を提供する機会を得るため、目立たない書式変更よりもリンクを意図的に選択しました。これは、ウェブページ上のテーブルにステータス情報を表示する場合など、UIで際立つ可能性があります。代わりにTextFormat::PrintToStringを使用できます。これは情報を編集せず、書式を保持します。ただし、このAPIは慎重に使用してください。組み込みの保護機能はありません。経験則として、デバッグログにデータを書き込む場合やステータスメッセージを生成する場合は、リンク付きのデバッグ形式を引き続き使用する必要があります。現在機密データを扱っていない場合でも、システムは変更される可能性があり、コードは再利用されることを忘れないでください。
このメッセージをTextFormatに変換しようとしましたが、プロセスを再起動するたびに形式が変わることに気づきました。
これは意図的なものです。このデバッグ形式の出力を解析しようとしないでください。当社は予告なく構文を変更する権利を留保します。デバッグ形式の構文は、不注意な依存関係を防ぐため、プロセスごとにランダムに変更されます。デバッグ形式の構文変更によりシステムが破損する場合、プロトのデバッグ表現を使用するのではなく、TextFormat APIを使用すべきである可能性が高いです。
FAQ
TextFormatをどこでも使用できますか?
ログメッセージの生成にはTextFormatを使用しないでください。これにより、組み込みのすべての保護が迂回され、機密情報が誤ってログに記録されるリスクがあります。現在、システムが機密データを処理していないとしても、将来的に変更される可能性があります。
デバッグ表現またはTextFormatを適切に使用して、ログと、他のシステムによるさらなる処理を意図した情報を区別します。
人間が読める形式と機械が読める形式の両方が必要な設定ファイルを作成したい
このユースケースでは、TextFormat を明示的に使用できます。設定ファイルに PII が含まれていないことを確認する責任はユーザーにあります。
単体テストを作成中で、テストアサーションでDebugstringを比較したい
protobuf の値を比較したい場合は、以下のように MessageDifferencer を使用してください。
using google::protobuf::util::MessageDifferencer;
...
MessageDifferencer diff;
...
diff.Compare(foo, bar);
書式設定とフィールド順序の違いを無視するだけでなく、より良いエラーメッセージも得られます。