Skip to content

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

Open
kumarak wants to merge 4 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 4 commits into
github:mainfrom
trail-of-forks:kumarak/cpp-protobuf-flow-models

Conversation

@kumarak

@kumarak kumarak commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

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
Comment thread cpp/ql/test/library-tests/dataflow/external-models/protobuf.cpp Outdated
Comment thread cpp/ql/lib/change-notes/2026-08-27-protobuf-models.md Outdated

@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.

Some further comments. I think the .yml file looks good now. I would still significantly reduce the number of comments, which don't seem to add much.

Comment thread cpp/ql/lib/change-notes/2026-08-27-protobuf-models.md Outdated
Comment thread cpp/ql/lib/ext/Protobuf.model.yml Outdated
Comment thread cpp/ql/lib/ext/Protobuf.model.yml Outdated
Comment on lines +12 to +15
# Deserialization: the encoded input taints the message (`this`). The `*FromString` methods each
# have a `string_view` overload (the buffer is the by-value argument, so `Argument[0]`) and a
# `const Cord &` overload (the buffer is behind a reference, so `Argument[*0]`). The remaining
# inputs below are pointers or references, so they take `Argument[*0]`.

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.

Suggested change
# Deserialization: the encoded input taints the message (`this`). The `*FromString` methods each
# have a `string_view` overload (the buffer is the by-value argument, so `Argument[0]`) and a
# `const Cord &` overload (the buffer is behind a reference, so `Argument[*0]`). The remaining
# inputs below are pointers or references, so they take `Argument[*0]`.
# Deserialization

Comment thread cpp/ql/lib/ext/Protobuf.model.yml Outdated
Comment thread cpp/ql/lib/ext/Protobuf.model.yml Outdated
Comment thread cpp/ql/test/library-tests/dataflow/external-models/protobuf.cpp Outdated
Comment on lines +59 to +61
// A faithful subset of `MessageLite`. The string/Cord/stream signatures mirror the real
// `message_lite.h`; the iostream-based methods are declared on `Message` in the real headers
// but are modeled here on `MessageLite` (with `subtypes` covering `Message`).

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 read like a shortcut was taken that does not accurately represent actual protobuf. This should be fixed.


// Every modeled method is called below so its summary step is covered by `steps.ql`. Endpoint
// mistakes and rows that fail to bind show up as missing lines in `steps.expected`.
void test_step_coverage() {

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.

None of the "tests" below tell me that any of this is actually working. Ideally there should be sink calls here with // $ ir annotations.

Replace the step-coverage function with one sink test per model row
using a template source, declare the Cord overloads of the ToString
methods in the stub, drop the incorrect istream comment from the
fixture, and shorten the model-file and change-note comments per review.
@jketema

jketema commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

cpp/ql/test/library-tests/dataflow/taint-tests/test_mad-signatures.ql fails. Otherwise this LGTM. I'll run some more internal testing.

@jketema

jketema commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Internal testing showed nothing out of the ordinary. So if you fix the test, then this can be merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants