Skip to content

Commit 4f6fad1

Browse files
authored
krate/publish: Avoid panic for truncated payloads (#6393)
`cargo` should not send such requests, but apparently some clever user with their Postman app has figured out that this is a great way to have the request handler panic... 😄 on the bright side, tokio/hyper/axum/something is catching it correctly and transforming it into an internal server error without actually crashing our server. 🎉
1 parent ab0e3c3 commit 4f6fad1

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

src/controllers/krate/publish.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,11 @@ fn split_body<R: RequestPartsExt>(mut bytes: Bytes, req: &R) -> AppResult<(Bytes
327327
// .crate tarball length
328328
// .crate tarball file
329329

330+
if bytes.len() < 4 {
331+
// Avoid panic in `get_u32_le()` if there is not enough remaining data
332+
return Err(cargo_err("invalid metadata length"));
333+
}
334+
330335
let json_len = bytes.get_u32_le() as usize;
331336
req.request_log().add("metadata_length", json_len);
332337

@@ -338,6 +343,11 @@ fn split_body<R: RequestPartsExt>(mut bytes: Bytes, req: &R) -> AppResult<(Bytes
338343

339344
let json_bytes = bytes.split_to(json_len);
340345

346+
if bytes.len() < 4 {
347+
// Avoid panic in `get_u32_le()` if there is not enough remaining data
348+
return Err(cargo_err("invalid metadata length"));
349+
}
350+
341351
let tarball_len = bytes.get_u32_le() as usize;
342352
if tarball_len > bytes.len() {
343353
return Err(cargo_err(&format!(

src/tests/krate/publish.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,3 +1023,15 @@ fn new_krate_sorts_deps() {
10231023
assert_eq!(deps[0].name, "dep-a");
10241024
assert_eq!(deps[1].name, "dep-b");
10251025
}
1026+
1027+
#[test]
1028+
fn empty_payload() {
1029+
let (_, _, user) = TestApp::full().with_user();
1030+
1031+
let response = user.put::<()>("/api/v1/crates/new", &[]);
1032+
assert_eq!(response.status(), StatusCode::OK);
1033+
assert_eq!(
1034+
response.into_json(),
1035+
json!({ "errors": [{ "detail": "invalid metadata length" }] })
1036+
);
1037+
}

0 commit comments

Comments
 (0)