Skip to content

fix(workflows): raise catalog error, not raw ValueError, on a malformed catalog URL#3484

Open
Noor-ul-ain001 wants to merge 1 commit into
github:mainfrom
Noor-ul-ain001:fix/workflow-catalog-malformed-url
Open

fix(workflows): raise catalog error, not raw ValueError, on a malformed catalog URL#3484
Noor-ul-ain001 wants to merge 1 commit into
github:mainfrom
Noor-ul-ain001:fix/workflow-catalog-malformed-url

Conversation

@Noor-ul-ain001

Copy link
Copy Markdown
Contributor

Summary

The four catalog URL validators in src/specify_cli/workflows/catalog.py accessed urlparse(url).hostname unguarded:

  • WorkflowCatalog._validate_catalog_url (raises WorkflowValidationError)
  • StepCatalog._validate_catalog_url (raises StepValidationError)
  • the nested fetch-path validators (raise WorkflowCatalogError / StepCatalogError)

A malformed authority — an unterminated IPv6 bracket https://[::1 or a bracketed non-IP host https://[not-an-ip] — makes urlparse / .hostname raise ValueError.

Each validator's contract is to raise its domain error, and the CLI handlers catch only those. So a bad URL leaked a raw ValueError traceback instead of the clean message + exit 1 a bad URL should produce:

$ specify workflow catalog add "https://[::1"
# before: Traceback ... ValueError: Invalid IPv6 URL
# after:  Error: Catalog URL is malformed: https://[::1   (exit 1)

The two fetch-path validators also run on the post-redirect resp.geturl(), so a hostile/broken redirect target could crash the fetch the same way.

Fix

Guard each urlparse / .hostname access with try/except ValueError -> domain error, and read hostname once and reuse it for the host check — mirroring the fixes already applied to specify_cli.catalogs (#3435) and the bundler adapters (#3433). This is the direct workflows/catalog.py twin of those; the same bug class as the auth-config fix (#3437).

Testing

  • Added test_validate_url_malformed_raises_validation_error to both the WorkflowCatalog and StepCatalog test classes (parametrized: unterminated IPv6 bracket, bracketed non-IP host).
  • Verified end-to-end: specify workflow catalog add "https://[::1" now exits 1 with Error: Catalog URL is malformed: ... and no traceback.
  • Full tests/test_workflows.py passes except the 11 pre-existing Windows symlink-guard tests (fail identically on a clean base; require elevation).
  • ruff check clean on the changed files.

🤖 Generated with Claude Code

…ed catalog URL

The four catalog URL validators in `workflows/catalog.py`
(`WorkflowCatalog`/`StepCatalog` `_validate_catalog_url`, and the nested
fetch-path validators) accessed `urlparse(url).hostname` unguarded. A
malformed authority — e.g. an unterminated IPv6 bracket `https://[::1`
or a bracketed non-IP host `https://[not-an-ip]` — makes urlparse /
hostname raise `ValueError`.

Each validator's contract is to raise a domain error
(`WorkflowValidationError` / `StepValidationError` /
`WorkflowCatalogError` / `StepCatalogError`), and the command handlers
catch only those. So `specify workflow catalog add "https://[::1"`
surfaced an uncaught `ValueError` traceback instead of the clean
`Error: Catalog URL is malformed` + exit 1 that a bad URL should give.
The fetch-path validators also run on the post-redirect `resp.geturl()`,
so a hostile redirect target could crash the fetch the same way.

Guard each `urlparse`/`.hostname` access with `try/except ValueError ->
domain error`, mirroring the fixes already applied to
`specify_cli.catalogs` (github#3435) and the bundler adapters (github#3433). Also
read `hostname` once and reuse it for the host check, matching those
siblings.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Noor-ul-ain001 Noor-ul-ain001 requested a review from mnriem as a code owner July 12, 2026 16:35
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