Skip to content

Bound gRPC frame sizes#220

Open
benthecarman wants to merge 4 commits into
lightningdevkit:mainfrom
benthecarman:fix-bounded-grpc-stream-frames
Open

Bound gRPC frame sizes#220
benthecarman wants to merge 4 commits into
lightningdevkit:mainfrom
benthecarman:fix-bounded-grpc-stream-frames

Conversation

@benthecarman
Copy link
Copy Markdown
Collaborator

Reject oversized server-streaming gRPC messages as soon as their frame
header is available. Also reject compressed stream frames consistently
and avoid unchecked frame length arithmetic before slicing buffers.

Read unary client responses incrementally and reject bodies above the
configured limit before protobuf decoding. Preallocate only after a
valid Content-Length has been checked.

tested with all the graph clis and they still fit within the limit

Reject oversized server-streaming gRPC messages as soon as their frame
header is available. Also reject compressed stream frames consistently
and avoid unchecked frame length arithmetic before slicing buffers.
Read unary client responses incrementally and reject bodies above the
configured limit before protobuf decoding. Preallocate only after a
valid Content-Length has been checked.
@ldk-reviews-bot
Copy link
Copy Markdown

ldk-reviews-bot commented May 23, 2026

👋 Thanks for assigning @tnull as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.


// Applies to complete unary gRPC responses. The server applies the same cap to unary request
// bodies before protobuf decoding.
const MAX_GRPC_UNARY_RESPONSE_LEN: usize = 10 * 1024 * 1024;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

wdyt about having the unit explicit in the const name? _BYTES instead of _LEN?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

i think that is implied

Ok(payload)
}

fn check_grpc_unary_response_len(len: u64) -> Result<(), LdkServerError> {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

if you drop the content_size path, you can change this to receive usize and avoid the as castings both on L535 and L542

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

if we do that then we need to either cast the content_length before validating it which is unsafe, or do a try_into which ends up being more ugly than these casts.

content_length as usize
} else {
0
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think the Some path is essentially useless as ldk-server doesn't set the content length header. It actually could't even if it wanted to. In gRPC the body streams and you can't compute a length.

Also, maybe worth noting that having Vec::with_capacity(0) hardcoded it's kinda bad because it will always have to allocate. Given the context where this is running it seems like not that big of a deal. You could initialize for something different than zero, or maybe use some BytesMut trickery to alloc exactly what you need.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Vec::with_capacity(0) is the same as Vec::new() so this is still an improvement from the pervious version but yeah, I should make sure we return the content length from the server

@ldk-reviews-bot
Copy link
Copy Markdown

🔔 1st Reminder

Hey @valentinewallace! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@ldk-reviews-bot
Copy link
Copy Markdown

🔔 2nd Reminder

Hey @valentinewallace! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@joostjager
Copy link
Copy Markdown
Contributor

We hand-rolled gRPC to reduce exposure to supply chain risk, but I think this PR demonstrates that it is a trade-off because we might introduce vulnerabilities ourselves. Hopefully we can keep the gRPC feature set small enough that the balance does not shift unfavourably.

@benthecarman
Copy link
Copy Markdown
Collaborator Author

added 2 commits where we make sure we always send the content length on both client and server to make the handling cleaner

Copy link
Copy Markdown
Contributor

@valentinewallace valentinewallace left a comment

Choose a reason for hiding this comment

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

I'm not sure I'm the right person to review this, don't have a lot of context on gRPC. Claude seems to think this is fine.

@benthecarman benthecarman requested a review from tnull May 28, 2026 09:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants