Skip to content

fix: use bounded read for workflow catalog HTTP responses - #3766

Open
Quratulain-bilal wants to merge 2 commits into
github:mainfrom
Quratulain-bilal:fix/unbounded-workflow-catalog-response
Open

Quratulain-bilal wants to merge 2 commits into
github:mainfrom
Quratulain-bilal:fix/unbounded-workflow-catalog-response

Conversation

@Quratulain-bilal

Copy link
Copy Markdown
Contributor

Summary

The workflow catalog fetch (WorkflowCatalog._fetch_single_catalog and StepCatalog._fetch_single_catalog) used unbounded resp.read() to read HTTP responses into memory. A malicious or misconfigured catalog server could return an arbitrarily large response causing OOM.

Changes

  • src/specify_cli/workflows/catalog.py (lines 541, 1214): Replaced resp.read() with read_response_limited(resp, max_bytes=MAX_JSON_METADATA_BYTES) capped at 1 MiB at both call sites, consistent with how other JSON fetch paths in the codebase enforce bounded reads.

Testing

All 176 tests in tests/workflows/ pass after the fix.

Security Impact

This is a Medium severity fix - it closes a potential memory exhaustion vector against the workflow catalog fetch endpoint.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Bounds workflow and step catalog HTTP responses to 1 MiB, mitigating memory-exhaustion risks.

Changes:

  • Uses read_response_limited for both catalog fetch paths.
  • Applies MAX_JSON_METADATA_BYTES as the response limit.
Show a summary per file
File Description
src/specify_cli/workflows/catalog.py Adds bounded reads for workflow and step catalogs.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comments suppressed due to low confidence (1)

src/specify_cli/workflows/catalog.py:1219

  • Please cover the step-catalog fetch path with an oversized streamed response and assert StepCatalogError. StepCatalog has separate fetch/cache handling, and its current fetch tests also exit before reading the body, so they do not verify that this call site actually enforces the new limit.
                data = json.loads(
                    read_response_limited(resp, max_bytes=MAX_JSON_METADATA_BYTES).decode("utf-8")
  • Files reviewed: 1/1 changed files
  • Comments generated: 1
  • Review effort level: Medium

Comment thread src/specify_cli/workflows/catalog.py Outdated

@mnriem mnriem left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address Copilot feedback

The workflow catalog fetch used unbounded resp.read() to read HTTP
responses into memory. A malicious or misconfigured catalog server
could return an arbitrarily large response causing OOM.

Replace with read_response_limited() capped at MAX_JSON_METADATA_BYTES
(1 MiB) at both call sites, consistent with how other JSON fetch
paths in the codebase enforce bounded reads.
@Quratulain-bilal
Quratulain-bilal force-pushed the fix/unbounded-workflow-catalog-response branch from 291d343 to 5c2087c Compare July 27, 2026 22:15
@mnriem
mnriem requested a review from Copilot July 28, 2026 14:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0 new
  • Review effort level: Medium

@mnriem

mnriem commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Please resolve conflicts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

Comments suppressed due to low confidence (6)

tests/test_workflows.py:6843

  • This patch target does not exist: the workflow fetch passes MAX_JSON_CATALOG_BYTES to read_response_limited. As written, the test fails during setup rather than validating recovery after an oversized response.
            "specify_cli.workflows.catalog.MAX_JSON_METADATA_BYTES", 512

tests/test_workflows.py:7675

  • workflows.catalog exposes MAX_JSON_CATALOG_BYTES, not MAX_JSON_METADATA_BYTES, so this monkeypatch fails with AttributeError before exercising StepCatalog._fetch_single_catalog. Patch the constant actually used by that fetch.
            "specify_cli.workflows.catalog.MAX_JSON_METADATA_BYTES", 512

tests/test_workflows.py:7727

  • This test patches a nonexistent module attribute and therefore cannot verify that a healthy step catalog still works after rejection. The production bounded read uses MAX_JSON_CATALOG_BYTES.
            "specify_cli.workflows.catalog.MAX_JSON_METADATA_BYTES", 512

tests/test_workflows.py:7666

  • The step-catalog fetch is bounded by MAX_JSON_CATALOG_BYTES, not the metadata limit. Update the docstring so it documents the actual regression contract.
        MAX_JSON_METADATA_BYTES instead of reading unbounded into memory."""

tests/test_workflows.py:6791

  • workflows.catalog imports MAX_JSON_CATALOG_BYTES, not MAX_JSON_METADATA_BYTES, so monkeypatch.setattr raises AttributeError and this regression test never reaches the fetch. Patch the catalog limit used by the production call instead.

This issue also appears in the following locations of the same file:

  • line 6843
  • line 7675
  • line 7727
            "specify_cli.workflows.catalog.MAX_JSON_METADATA_BYTES", 512

tests/test_workflows.py:6782

  • The implementation now uses the catalog-specific 8 MiB ceiling, so this docstring names the wrong constant and incorrectly describes the behavior under test.

This issue also appears on line 7666 of the same file.

        MAX_JSON_METADATA_BYTES instead of reading unbounded into memory."""
  • Files reviewed: 1/1 changed files
  • Comments generated: 0 new
  • Review effort level: Medium

@mnriem

mnriem commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Please address test & lint errors

This branch has not been deployed

No deployments
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.

3 participants