Skip to content

cpp: model Protocol Buffers parse/serialize taint flow - #22448

Open
kumarak wants to merge 3 commits into
github:mainfrom
trail-of-forks:kumarak/cpp-protobuf-flow-models
Open

cpp: model Protocol Buffers parse/serialize taint flow#22448
kumarak wants to merge 3 commits into
github:mainfrom
trail-of-forks:kumarak/cpp-protobuf-flow-models

Conversation

@kumarak

@kumarak kumarak commented Aug 27, 2026

Copy link
Copy Markdown

Add flow summaries for the protobuf C++ API on google::protobuf::MessageLite (subtypes=true, so Message and all generated messages are covered):

  • ParseFrom*/MergeFrom* (string, array, Cord, istream, zero-copy and coded-stream forms) propagate taint from the encoded input to the message.
  • SerializeTo*/AppendTo* propagate taint from the message to the output buffer or stream; SerializeAs*/AppendTo* to the return value.
  • File-descriptor variants are omitted (the fd is an int, not a buffer).

Add flow summaries for the protobuf C++ API on
google::protobuf::MessageLite (subtypes=true, so Message and all
generated messages are covered):

- ParseFrom*/MergeFrom* (string, array, Cord, istream, zero-copy and
  coded-stream forms) propagate taint from the encoded input to the
  message.
- SerializeTo*/AppendTo* propagate taint from the message to the output
  buffer or stream; SerializeAs*/... to the return value.

File-descriptor variants are omitted (the fd is an int, not a buffer).
@kumarak
kumarak requested a review from a team as a code owner August 27, 2026 15:30
Copilot AI balanced review requested due to automatic review settings August 27, 2026 15:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds C++ taint-flow summaries for Protocol Buffers MessageLite APIs and inherited generated message types.

Changes:

  • Models parse/merge and serialization flows.
  • Adds representative flow tests and expected results.
  • Documents the analysis improvement.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
cpp/ql/lib/ext/Protobuf.model.yml Defines protobuf flow summaries.
cpp/ql/test/library-tests/dataflow/external-models/protobuf.cpp Adds protobuf test fixtures.
cpp/ql/test/library-tests/dataflow/external-models/flow.expected Updates flow expectations.
cpp/ql/test/library-tests/dataflow/external-models/steps.expected Updates summary-step expectations.
cpp/ql/lib/change-notes/2026-08-27-protobuf-models.md Records the new models.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +25 to +29
- ["google::protobuf", "MessageLite", True, "ParseFromZeroCopyStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
- ["google::protobuf", "MessageLite", True, "ParsePartialFromZeroCopyStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
- ["google::protobuf", "MessageLite", True, "ParseFromBoundedZeroCopyStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
- ["google::protobuf", "MessageLite", True, "ParsePartialFromBoundedZeroCopyStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
- ["google::protobuf", "MessageLite", True, "MergeFromBoundedZeroCopyStream", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]

@jketema jketema left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this. I made a brief first pass over this, which should hopefully put you on the right path.

Comment thread cpp/ql/lib/ext/Protobuf.model.yml Outdated
# the descriptor is an `int`, not a data buffer, so there is no buffer argument to model.

# Deserialization: the encoded input (`Argument[*0]`) taints the message (`this`).
- ["google::protobuf", "MessageLite", True, "ParseFromString", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]

@jketema jketema Aug 28, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have only looked at this one for now, but this seems incorrect, as protobuf specifies the following prototypes:

bool ParseFromString(absl::string_view data);
bool ParseFromString(const absl::Cord& data);

As the first of the string_view parameter is not a reference, Argument[*0] is incorrect, as the * indicates there is a pointer that needs to be dereferenced to get to the tainted data (a reference like in const absl::Cord& counts as one).

This means that this will need to be split up in two lines:

["google::protobuf", "MessageLite", True, "ParseFromString", "(string_view)", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
["google::protobuf", "MessageLite", True, "ParseFromString", "(const Cord &)", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]

Observe that the input arguments are different.

// in the real headers (message_lite.h), including the iostream-based ones.
class MessageLite {
public:
bool ParseFromString(const std::string &data);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks incorrect. The correct prototypes seem to be:

bool ParseFromString(absl::string_view data);
bool ParseFromString(const absl::Cord& data);

There are similar problems with at least some of the below prototypes too.

Comment thread cpp/ql/lib/change-notes/2026-08-27-protobuf-models.md Outdated
注册 for free to join this conversation on GitHub. Already have an account? 登录 to comment

项目

None yet

Development

Successfully merging this pull request may close these issues.

3 participants