Enforce content-length validation on sender and size limits on payjoin-cli
This PR follows up on #770 and addresses the remaining improvements in comment. It implements stricter content-length validation and removes MAX_CONTENT_LENGTH from the sender side, moving it to payjoin-cli.
Summary of changes
-
Sender-side validation
- Mirrors the receiver-side logic by removing
MAX_CONTENT_LENGTHand validating that the actual body length matches theContent-Lengthheader.
- Mirrors the receiver-side logic by removing
-
payjoin-clireceiver- Adds a size limit when collecting the body using
.collect(), to avoid unbounded memory allocations from a potentially malicious counterparty.
- Adds a size limit when collecting the body using
-
payjoin-clisender- Enforces a similar limit when handling response bodies using
response.bytes()fromreqwest.
- Enforces a similar limit when handling response bodies using
Ref: #770 Closes: #756
Pull Request Test Coverage Report for Build 17460319220
Details
- 72 of 81 (88.89%) changed or added relevant lines in 5 files are covered.
- 2 unchanged lines in 2 files lost coverage.
- Overall coverage increased (+0.09%) to 86.033%
| Changes Missing Coverage | Covered Lines | Changed/Added Lines | % |
|---|---|---|---|
| payjoin-cli/src/app/mod.rs | 13 | 14 | 92.86% |
| payjoin-cli/src/app/v1.rs | 12 | 20 | 60.0% |
| <!-- | Total: | 72 | 81 |
| Files with Coverage Reduction | New Missed Lines | % |
|---|---|---|
| payjoin/src/core/send/error.rs | 1 | 33.14% |
| payjoin/src/core/send/v1.rs | 1 | 92.31% |
| <!-- | Total: | 2 |
| Totals | |
|---|---|
| Change from base Build 17446213698: | 0.09% |
| Covered Lines: | 8248 |
| Relevant Lines: | 9587 |
💛 - Coveralls
I have implemented the changes suggested. However, I had to introduce about two dependencies, which are:
- futures
- bytes
as a result of that I attempted to update the lock files using the update-lock-files.sh script. However, I kept getting can't find crate for serde`` for bitcoin-0.32.5 and for rustls-0.22.4.
I want you to review what I have thus far, let me know if I am going in the right direction, as I find a solution to the error I am having.
I implemented the suggestions you gave, however, for the utility function, putting it in mod.rs of app, I am encountering a challenge where I am unable to access the hyper dependencies, I really don't know why. And I will be needing it, since I will need to make use of Bytes from it for the utility function.
I didn't quite understand your last comment about hyper & bytes, but i think the
read_limited_bodyfunction is in the right place?similar limiting for
app/v2.rscan be added in a separate PR, with a fixed response size, and reusing this function, but moving it to the top levelmod.rsshould be straightforward (just making itpub(crate)and bringing in the necessary imports, namelyhyper::body::Bytes)anyway this is getting close, i only have some fairly small cleanup suggestions
Moving the function to mod.rs, I always have issue bringing in the hyper dependency. This is the error I always get, despite hyper being present in the Cargo.toml file.
error[E0433]: failed to resolve: use of unresolved module or unlinked crate `hyper`
--> payjoin-cli/src/app/mod.rs:5:5
|
5 | use hyper::body::Bytes;
| ^^^^^ use of unresolved module or unlinked crate `hyper`
|
= help: if you wanted to use a crate named `hyper`, use `cargo add hyper` to add it to your `Cargo.toml`
I have been trying to figure out where the problem is, but till now nothing.
This PR addresses the hyper crate issue and also all the suggestions given. Thank you.
Resolved merge conflicts.
Whenever this gets merged I suggest it get squashed rather than have all $n$ commits used.
Lint is failing with this:
error[E0599]: no variant or associated item named `Parse` found for enum `core::send::error::InternalValidationError` in the current scope
--> payjoin/src/core/send/mod.rs:699:90
|
699 | let res_str = std::str::from_utf8(response).map_err(|_| InternalValidationError::Parse)?;
| ^^^^^ variant or associated item not found in `core::send::error::InternalValidationError`
|
::: payjoin/src/core/send/error.rs:94:1
|
94 | pub(crate) enum InternalValidationError {
| --------------------------------------- variant or associated item `Parse` not found for this enum
error[E0599]: no variant or associated item named `parse` found for enum `core::send::error::ResponseError` in the current scope
--> payjoin/src/core/send/mod.rs:700:75
|
700 | let proposal = Psbt::from_str(res_str).map_err(|_| ResponseError::parse(res_str))?;
| ^^^^^ variant or associated item not found in `core::send::error::ResponseError`
|
::: payjoin/src/core/send/error.rs:250:1
|
250 | pub enum ResponseError {
| ---------------------- variant or associated item `parse` not found for this enum
I don't really know, I observed that the Parse is actually present, but it was feature gated to v1, I don't know if that is what is causing the lint to fail here? Same thing with the parse too in the ResponseError.
Resolved merge conflict.