|
| 1 | ++++ |
| 2 | +title = "Deserializing Debug Proto Representations" |
| 3 | +weight = 89 |
| 4 | +description = "How to log debugging information in Protocol Buffers." |
| 5 | +type = "docs" |
| 6 | ++++ |
| 7 | + |
| 8 | +From version 29.x, `DebugString` APIs (`proto2::DebugString`, |
| 9 | +`proto2::ShortDebugString`, `proto2::Utf8DebugString`) are deprecated. |
| 10 | +DebugString users should migrate to some Abseil string functions (such as |
| 11 | +`absl::StrCat`, `absl::StrFormat`, `absl::StrAppend`, AND `absl::Substitute`), |
| 12 | +Abseil logging API, and some Protobuf APIs (`proto2::ShortFormat`, |
| 13 | +`proto2::Utf8Format`) to automatically convert proto arguments into a new |
| 14 | +debugging format . |
| 15 | + |
| 16 | +Unlike the Protobuf DebugString output format, the new debugging format |
| 17 | +automatically redacts sensitive fields by replacing their values with the string |
| 18 | +"[REDACTED]" (without the quotation marks). In |
| 19 | +addition, to ensure that this new output format cannot be deserialized by |
| 20 | +Protobuf TextFormat parsers, regardless of whether the underlying proto contains |
| 21 | +SPII fields, we add a set of randomized links pointing to this article |
| 22 | +and a randomized-length whitespace sequence. The new debugging format looks as |
| 23 | +follows: |
| 24 | + |
| 25 | +```none |
| 26 | +go/nodeserialize |
| 27 | +spii_field: [REDACTED] |
| 28 | +normal_field: "value" |
| 29 | +``` |
| 30 | + |
| 31 | +Note that the new debugging format is only different from the output format of |
| 32 | +DebugString format in two ways: |
| 33 | + |
| 34 | +* The URL prefix |
| 35 | +* The values of SPII fields are replaced by |
| 36 | + "[REDACTED]" (without the quotes) |
| 37 | + |
| 38 | +The new debugging format never removes any field names; it only replaces the |
| 39 | +value with |
| 40 | +"[REDACTED]" if the field is considered sensitive. |
| 41 | +**If you don't see certain fields in the output, it is because those fields are |
| 42 | +not set in the proto.** |
| 43 | + |
| 44 | +**Tip:** If you see only the URL and nothing else, your proto is empty! |
| 45 | + |
| 46 | +## Why is this URL here? |
| 47 | + |
| 48 | +We want to make sure nobody deserializes human-readable representations of a |
| 49 | +protobuf message intended for humans debugging a system. Historically, |
| 50 | +`.DebugString()` and `TextFormat` were interchangeable, and existing systems use |
| 51 | +DebugString to transport and store data. |
| 52 | + |
| 53 | +We want to make sure sensitive data does not accidentally end up in logs. |
| 54 | +Therefore, we are transparently redacting some field values from protobuf |
| 55 | +messages before turning them into a string |
| 56 | +("[REDACTED]"). This reduces the security & privacy |
| 57 | +risk of accidental logging, but risks data loss if other systems deserialize |
| 58 | +your message. To address this risk, we are intentionally splitting the |
| 59 | +machine-readable TextFormat from the human-readable debug format to be used in |
| 60 | +log messages. |
| 61 | + |
| 62 | +### Why are there links in my web page? Why is my code producing this new "debug representation"? |
| 63 | + |
| 64 | +This is intentional, to make the "debug representation" of your protos |
| 65 | +(produced, for example, by logging) incompatible with TextFormat. We want to |
| 66 | +prevent anyone from depending on debugging mechanisms to transport data between |
| 67 | +programs. Historically, the debug format (generated by the DebugString APIs) and |
| 68 | +TextFormat have been incorrectly used in a interchangeable fashion. We hope this |
| 69 | +intentional effort will prevent that going forward. |
| 70 | + |
| 71 | +We intentionally picked a link over less visible format changes to get an |
| 72 | +opportunity to provide context. This might stand out in UIs, such as if you |
| 73 | +display status information on a table in a webpage. You may use |
| 74 | +`TextFormat::PrintToString` instead, which will not redact any information and |
| 75 | +preserves formatting. However, use this API cautiously -- there are no built in |
| 76 | +protections. As a rule of thumb, if you are writing data to debug logs, or |
| 77 | +producing status messages, you should continue to use the Debug Format with the |
| 78 | +link. Even if you are currently not handling sensitive data, keep in mind that |
| 79 | +systems can change and code gets re-used. |
| 80 | + |
| 81 | +### I tried converting this message into TextFormat, but I noticed the format changes every time my process restarts. |
| 82 | + |
| 83 | +This is intentional. Don't attempt to parse the output of this debug format. We |
| 84 | +reserve the right to change the syntax without notice. The debug format syntax |
| 85 | +randomly changes per process to prevent inadvertent dependencies. If a syntactic |
| 86 | +change in the debug format would break your system, chances are you shouldn't |
| 87 | +use the debug representation of a proto. |
| 88 | + |
| 89 | +## FAQ |
| 90 | + |
| 91 | +### Can I Just Use TextFormat Everywhere? |
| 92 | + |
| 93 | +Don't use TextFormat for producing log messages. This will bypass all built-in |
| 94 | +protections, and you risk accidentally logging sensitive information. Even if |
| 95 | +your systems are currently not handling any sensitive data, this can change in |
| 96 | +the future. |
| 97 | + |
| 98 | +Distinguish logs from information that's meant for further processing by other |
| 99 | +systems by using either the debug representation or TextFormat as appropriate. |
| 100 | + |
| 101 | +### I Want to Write Configuration Files That Need to Be Both Human-Readable And Machine-Readable |
| 102 | + |
| 103 | +For this use case, you can use TextFormat explicitly. You are responsible for |
| 104 | +making sure your configuration files don't contain any PII. |
| 105 | + |
| 106 | +### I Am Writing a Unit Test, and Want to Compare Debugstring in a Test Assertion |
| 107 | + |
| 108 | +If you want to compare protobuf values, use `MessageDifferencer` like in the |
| 109 | +following: |
| 110 | + |
| 111 | +```cpp |
| 112 | +using google::protobuf::util::MessageDifferencer; |
| 113 | +... |
| 114 | +MessageDifferencer diff; |
| 115 | +... |
| 116 | +diff.Compare(foo, bar); |
| 117 | +``` |
| 118 | + |
| 119 | +Besides ignoring formatting and field order differences, you will also get |
| 120 | +better error messages. |
0 commit comments