fix: cap the multipart metadata part instead of buffering it unbounded
The `metadata` JSON part in the manga-create and chapter-upload handlers was read with `Field::bytes()`, buffering the whole part before any check — a client could send a multi-hundred-MB metadata blob (up to the 200 MiB request limit) as one allocation. Image parts were already streamed with a cap; metadata was the last unbounded read. Cap it at a shared upload::MAX_METADATA_BYTES (64 KiB) via the read_capped streaming loop (413 on overflow), and remove the now-unused read_field_bytes helper so the unbounded path can't return. Tests: manga + chapter oversized-metadata parts are rejected with 413. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,15 @@ pub struct StagedImage {
|
||||
/// staged page out of this prefix.
|
||||
pub const STAGING_PREFIX: &str = "staging";
|
||||
|
||||
/// Upper bound on a multipart `metadata` JSON part, enforced as bytes arrive
|
||||
/// (via [`read_capped`]). Manga/chapter metadata is title + a few short lists +
|
||||
/// a description — kilobytes at most. Without this, `metadata` was the one
|
||||
/// remaining part read with the unbounded `Field::bytes()`, letting a client
|
||||
/// buffer up to the whole 200 MiB request body in memory as a single JSON blob
|
||||
/// before any validation ran. 64 KiB is generous headroom over any legitimate
|
||||
/// payload while keeping the worst case tiny.
|
||||
pub const MAX_METADATA_BYTES: usize = 64 * 1024;
|
||||
|
||||
/// Read one multipart image part and write it straight to a staging key,
|
||||
/// returning only its metadata. The per-file byte cap is enforced as bytes
|
||||
/// arrive, so an oversized part is rejected (413) without being fully
|
||||
|
||||
Reference in New Issue
Block a user