Skip to content

fix(CrawlService): Validate actual response body size in archiveFile - #2579

Open
Huge wants to merge 1 commit into
nextcloud:masterfrom
Huge:fix/archive-file-size-guard
Open

Huge wants to merge 1 commit into
nextcloud:masterfrom
Huge:fix/archive-file-size-guard

Conversation

@Huge

@Huge Huge commented Oct 14, 2026

Copy link
Copy Markdown

Problem

When archiving non-HTML bookmark content in CrawlService::archiveFile(), the service checked the Content-Length header against MAX_BODY_LENGTH (90 MB):

$contentLengthHeader = $resp->getHeader('Content-Length');
$contentLength = $contentLengthHeader !== '' ? (int)$contentLengthHeader : 0;

if ($contentLength < self::MAX_BODY_LENGTH) {
    ...
    $file->putContent($resp->getBody());
}

If a remote server returns chunked transfer-encoding (omitting the Content-Length header entirely) or provides a falsified low header value (e.g., Content-Length: 10), $contentLength evaluated to 0 or a small integer. As a result, the condition evaluated to true, and the entire unbounded response body could be written to user storage.

Solution

  1. Check Content-Length early; return immediately if reported as >= MAX_BODY_LENGTH.
  2. Inspect the actual response body size (strlen($body)) before creating a file and writing it to user storage.
  3. Skip archiving payloads whose actual byte size reaches or exceeds MAX_BODY_LENGTH.

Tests

  • Added unit tests in tests/CrawlServiceTest.php:
    • testArchiveFileRejectsMissingContentLengthWhenBodyOversized: verifies that chunked responses with missing Content-Length exceeding MAX_BODY_LENGTH are not saved.
    • testArchiveFileRejectsSpoofedContentLengthWhenBodyOversized: verifies that responses with a spoofed small Content-Length exceeding MAX_BODY_LENGTH are not saved.
    • testArchiveFileSavesValidBodyWithinLimit: verifies that legitimate files within the limit continue to be archived correctly.
  • All unit tests pass cleanly (202 passed, 18 skipped circles).
  • Code style check (composer cs:check) passes without issues.

Previously, archiveFile checked the Content-Length response header against
MAX_BODY_LENGTH, defaulting to 0 when the header was missing (such as with
chunked transfer-encoding) or trusting a spoofed low Content-Length. This
allowed oversized payloads to bypass the limit and be written to disk.

Verify both the Content-Length header and the actual response body length
against MAX_BODY_LENGTH before writing the file.

Reported-by: BS.ehlas.cz
Assisted-by: Antigravity:gemini-3.8-flash
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.

1 participant