Limit response sizes for v1#586
Conversation
e8b8c6d to
f484552
Compare
Pull Request Test Coverage Report for Build 15169166399Details
💛 - Coveralls |
f484552 to
6ecf617
Compare
benalleng
left a comment
There was a problem hiding this comment.
Looking good, I left a comment about cleaning up the test to make sure we don't get any false positives. The private errors can make it difficult to drill down to get the precise error but for now I think string matches are ok.
This comment was marked as resolved.
This comment was marked as resolved.
c94ce03 to
0937da7
Compare
benalleng
left a comment
There was a problem hiding this comment.
Thanks for cleaning up the naming on those test-utils consts! I have another approach that I have decided I think is better with regards to the test cases. Sorry to lead you on a goose chase with these
payjoin/src/send/v1.rs
Outdated
| let expected_error = | ||
| "The receiver sent an invalid response: couldn't decode as PSBT or JSON"; | ||
| match response { | ||
| Ok(_) => panic!("Expected error, got success"), | ||
| Err(error) => { | ||
| assert!(matches!(error, ResponseError::Validation(_))); | ||
| assert_eq!(format!("{}", error), expected_error) | ||
| } | ||
| } |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
There was a problem hiding this comment.
This error is being mapped to InternalValidationError::Parse, so we won't see the same error message from the rust std lib. Instead, we'll see
let expected_error =
"The receiver sent an invalid response: couldn't decode as PSBT or JSON";defined here:
impl fmt::Display for ValidationError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use InternalValidationError::*;
match &self.0 {
Parse => write!(f, "couldn't decode as PSBT or JSON",),
Io(e) => write!(f, "couldn't read PSBT: {}", e),
ContentTooLarge => write!(f, "content is larger than {} bytes", MAX_CONTENT_LENGTH),
Proposal(e) => write!(f, "proposal PSBT error: {}", e),
#[cfg(feature = "v2")]
V2Encapsulation(e) => write!(f, "v2 encapsulation error: {}", e),
}
}
}
There was a problem hiding this comment.
You're totally right, I got my wires crossed somehow. So we could use the same match code as above in that case to not rely on this expected_error string.
There was a problem hiding this comment.
Done. Good idea on comparing the strings since the PartialEq stuff is kinda hairy with the internal/external stuff
There was a problem hiding this comment.
My last suggestion as it was just pointed out to me as a better practice is Ithat we should probably improve the panic strings here when something goes wrong. Something like.
Ok(_) => panic!("PSBT is malformed and should error") and
Ok(_) => panic!("Response string is malformed and should error")
7c5ff17 to
3725c02
Compare
benalleng
left a comment
There was a problem hiding this comment.
tACK everything is looking good. I maybe would like a unit test specifically for the MAX_CONTENT_LENGTH but that's something we can catch when we come back through for send mutants
|
rats. This one needs rebase |
3725c02 to
2f430ef
Compare
|
done 👍🏼 |
DanGould
left a comment
There was a problem hiding this comment.
Thanks for the rebase. I do have one additional comment you might be able to clear up for me
payjoin-cli/src/app/mod.rs
Outdated
| #[cfg(feature = "v1")] | ||
| pub(crate) const MAX_CONTENT_LENGTH: usize = 4_000_000 * 4 / 3; |
There was a problem hiding this comment.
Since I assume this mitigation would need to be implemented on all senders, wouldn't it make more sense to expose the constant defined in payjoin::send::v1 and use that here?
There was a problem hiding this comment.
I added this at the lib level cause it made sense to me that if we were sending something with the max size of MAX_CONTENT_LENGTH, we would also receive something with that same limit. Exposing it in payjoin and using it here makes sense and would be better to just have it defined in one place
payjoin/src/lib.rs
Outdated
| /// 4M block size limit with base64 encoding overhead => maximum reasonable size of content-length | ||
| /// 4_000_000 * 4 / 3 fits in u32 | ||
| #[cfg(feature = "_core")] | ||
| pub(crate) const MAX_CONTENT_LENGTH: usize = 4_000_000 * 4 / 3; |
There was a problem hiding this comment.
Would it not make sense to expose this as pub const for use in the implementation? Or to make it `pub(crate) for _core and NOT(v1) but pub for v1?
There was a problem hiding this comment.
you're right, it does. Updated to expose this in lib and use in the implementation
1784002 to
77a95bf
Compare
Pull out the test constant commit from #586 into its own PR
BIP 78 doesn't enforce a size on the response, only that the content length must be included. However, if there is not a limit, then some of the send logic could make unbounded allocations.
77a95bf to
29ffade
Compare
spacebear21
left a comment
There was a problem hiding this comment.
ACK - I took the liberty to rebase onto latest master.
Add content length checks in v1 send and payjoin-cli.
Fixes #483