還原序列化偵錯 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]」(不含引號)。此外,為了確保這種新的輸出格式無法被 Protobuf TextFormat 剖析器還原序列化,無論底層 proto 是否包含 SPII 欄位,我們都會加入一組隨機連結,指向本文和隨機長度的空白字元序列。新的偵錯格式如下所示
goo.gle/debugstr
spii_field: [REDACTED]
normal_field: "value"
請注意,新的偵錯格式與 DebugString 格式的輸出格式只有兩個不同之處
- URL 前置字串
- SPII 欄位的值會替換為「[REDACTED]」(不含引號)
新的偵錯格式永遠不會移除任何欄位名稱;只有在欄位被視為敏感時,才會將值替換為「[REDACTED]」。如果您在輸出中看不到某些欄位,那是因為這些欄位未在 proto 中設定。
提示:如果您只看到 URL 而沒有其他內容,則表示您的 proto 是空的!
這個 URL 為何在此?
我們希望確保沒有人會還原序列化 protobuf 訊息的人工可讀表示法,這些表示法旨在供人類偵錯系統。從歷史上看,.DebugString()
和 TextFormat
是可互換的,而且現有系統使用 DebugString 來傳輸和儲存資料。
我們希望確保敏感資料不會意外地出現在記錄中。因此,我們會在將 protobuf 訊息轉換為字串 ("[REDACTED]") 之前,透明地編輯某些欄位值。這降低了意外記錄的安全性和隱私風險,但如果其他系統還原序列化您的訊息,則會造成資料遺失的風險。為了應對此風險,我們有意將機器可讀的 TextFormat 與用於記錄訊息的人工可讀偵錯格式分開。
我的網頁中為何有連結?為何我的程式碼會產生這個新的「偵錯表示法」?
這是故意的,目的是讓您的 proto 的「偵錯表示法」(例如,由記錄產生) 與 TextFormat 不相容。我們希望防止任何人依賴偵錯機制在程式之間傳輸資料。從歷史上看,偵錯格式 (由 DebugString API 產生) 和 TextFormat 一直被錯誤地以可互換的方式使用。我們希望這種刻意的努力能夠防止未來再次發生這種情況。
我們有意選擇連結,而不是不太明顯的格式變更,以便有機會提供背景資訊。這可能會在 UI 中脫穎而出,例如,如果您在網頁的表格上顯示狀態資訊。您可以改用 TextFormat::PrintToString
,這樣就不會編輯任何資訊,並保留格式。但是,請謹慎使用此 API – 沒有內建的保護措施。根據經驗法則,如果您要將資料寫入偵錯記錄或產生狀態訊息,則應繼續使用帶有連結的偵錯格式。即使您目前沒有處理敏感資料,也要記住系統可能會變更,而且程式碼會被重複使用。
我嘗試將這個訊息轉換為 TextFormat,但我注意到每次重新啟動程序時,格式都會變更。
這是故意的。請勿嘗試剖析此偵錯格式的輸出。我們保留在不另行通知的情況下變更語法的權利。偵錯格式語法會針對每個程序隨機變更,以防止意外的相依性。如果偵錯格式中的語法變更會破壞您的系統,那麼您應該使用 TextFormat API,而不是使用 proto 的偵錯表示法。
常見問題
我可以到處都使用 TextFormat 嗎?
請勿使用 TextFormat 來產生記錄訊息。這會繞過所有內建的保護措施,而且您可能會意外記錄敏感資訊。即使您的系統目前沒有處理任何敏感資料,未來也可能會變更。
區分記錄與其他系統進一步處理的資訊,方法是視情況使用偵錯表示法或 TextFormat。
我想要撰寫需要同時具備人類可讀和機器可讀性的組態檔
對於這種使用案例,您可以明確使用 TextFormat。您有責任確保您的組態檔不包含任何 PII。
我正在撰寫單元測試,並想要在測試判斷提示中比較 Debugstring
如果您想要比較 protobuf 值,請使用 MessageDifferencer
,如下所示
using google::protobuf::util::MessageDifferencer;
...
MessageDifferencer diff;
...
diff.Compare(foo, bar);
除了忽略格式和欄位順序差異之外,您還會獲得更好的錯誤訊息。