Skip to content

fix: harden failure bundle artifact downloads#60

Open
merlinsantiago982-cmd wants to merge 2 commits into
TestSprite:mainfrom
merlinsantiago982-cmd:fix/failure-bundle-download-safety
Open

fix: harden failure bundle artifact downloads#60
merlinsantiago982-cmd wants to merge 2 commits into
TestSprite:mainfrom
merlinsantiago982-cmd:fix/failure-bundle-download-safety

Conversation

@merlinsantiago982-cmd

@merlinsantiago982-cmd merlinsantiago982-cmd commented Jun 30, 2026

Copy link
Copy Markdown

Summary

  • disable automatic redirects when downloading failure bundle artifacts
  • add a focused regression test that asserts fetchImpl receives redirect: "error"

Testing

  • npm test -- src/lib/bundle.test.ts
  • npm run typecheck
  • npm run format:check
  • npm run lint
  • npm run build

Related to #59

Summary by CodeRabbit

  • Bug Fixes
    • Improved download error messages to avoid exposing sensitive URL query values.
    • Error details now show only the safe part of a download URL, or a generic placeholder when the URL is invalid.
    • Downloads now block automatic redirects, helping prevent unexpected retrieval behavior and reducing the chance of leaking sensitive access links.

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b1f49db6-8d84-421c-b260-fe7e8b67a148

📥 Commits

Reviewing files that changed from the base of the PR and between 113acfe and bded499.

📒 Files selected for processing (2)
  • src/lib/bundle.test.ts
  • src/lib/bundle.ts

📝 Walkthrough

Walkthrough

streamUrlToFile now redacts artifact URLs in surfaced errors, forces fetch redirects to fail, and updates tests to verify secret URL data is not exposed.

Changes

Artifact Download Hardening

Layer / File(s) Summary
Error URL redaction
src/lib/bundle.ts
streamUrlToFile computes a redacted artifactUrl and uses it in transport and API error details across fetch, non-OK response, buffered fallback, and streaming failure paths.
Error and redirect tests
src/lib/bundle.test.ts
The retry failure tests now check that secret URL data is not exposed, and a new test verifies that fetchImpl receives redirect: 'error'.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 I hopped through logs and sniffed the breeze,
No secret strings went through the seams.
Redirects stopped at the burrow door,
And safe error crumbs spilled out no more.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: hardening failure bundle artifact downloads.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/bundle.ts`:
- Around line 737-745: streamUrlToFile currently validates only the initial
artifact URL, but fetchImpl can still follow redirects to unsafe destinations.
Update the fetch path in streamUrlToFile to block redirects, either by passing
redirect: 'error' on the fetchImpl call or by revalidating any Location target
before following it, and keep the existing validateArtifactUrl guard as the
initial check.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2437fef4-fb8d-4416-a071-8dcfe4884377

📥 Commits

Reviewing files that changed from the base of the PR and between 15e95de and b99c3f7.

📒 Files selected for processing (2)
  • src/lib/bundle.test.ts
  • src/lib/bundle.ts

Comment thread src/lib/bundle.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/bundle.ts (1)

866-866: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Avoid putting raw presigned artifact URLs in error details.

These errors can be surfaced or persisted by the bundle failure path, so including the full url risks leaking signed query params. Store a redacted origin/path, or omit the URL entirely.

🔒 Proposed redaction
-          details: { ...err.details, field: 'artifact-url', url },
+          details: { ...err.details, field: 'artifact-url', artifactOrigin: artifactUrlOrigin(url) },
         },
       });
@@
-      details: { url, bytes, maxBytes: STREAM_URL_MAX_BYTES },
+      details: { artifactOrigin: artifactUrlOrigin(url), bytes, maxBytes: STREAM_URL_MAX_BYTES },
     },
   });
 }
+
+function artifactUrlOrigin(url: string): string {
+  try {
+    return new URL(url).origin;
+  } catch {
+    return '<invalid-url>';
+  }
+}

Also applies to: 913-913

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/bundle.ts` at line 866, The bundle failure details currently include
the raw presigned artifact URL in the `details` object, which can leak signed
query parameters when surfaced or persisted. Update the error handling in
`bundle.ts` around the `err.details` construction (including the other affected
location) to avoid storing the full `url`; instead keep only a redacted
origin/path or remove the URL field entirely while preserving the `artifact-url`
context.
🧹 Nitpick comments (1)
src/lib/bundle.test.ts (1)

856-859: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert malformed evidence kind rejects before any fetch.

This validation test can reuse throwIfFetched; otherwise a future reorder that downloads before validating kind is less obvious from the failure.

🧪 Proposed test tightening
-    const okFetch = (async () =>
-      new Response('planted', { status: 200 })) as unknown as typeof globalThis.fetch;
     await expect(
-      writeBundle(forged, { dir, failedOnly: false, fetchImpl: okFetch }),
+      writeBundle(forged, { dir, failedOnly: false, fetchImpl: throwIfFetched }),
     ).rejects.toMatchObject({
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/bundle.test.ts` around lines 856 - 859, The validation test in
writeBundle should fail before any network call when the evidence kind is
malformed. Update the test around writeBundle and throwIfFetched so it uses the
fetch-guarding helper instead of okFetch, and assert the rejection happens
before any fetch is attempted. Keep the focus on the writeBundle path that
validates forged.kind first, so a future reorder that fetches early will break
this test.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/lib/bundle.ts`:
- Line 866: The bundle failure details currently include the raw presigned
artifact URL in the `details` object, which can leak signed query parameters
when surfaced or persisted. Update the error handling in `bundle.ts` around the
`err.details` construction (including the other affected location) to avoid
storing the full `url`; instead keep only a redacted origin/path or remove the
URL field entirely while preserving the `artifact-url` context.

---

Nitpick comments:
In `@src/lib/bundle.test.ts`:
- Around line 856-859: The validation test in writeBundle should fail before any
network call when the evidence kind is malformed. Update the test around
writeBundle and throwIfFetched so it uses the fetch-guarding helper instead of
okFetch, and assert the rejection happens before any fetch is attempted. Keep
the focus on the writeBundle path that validates forged.kind first, so a future
reorder that fetches early will break this test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 63e2bc74-797b-49a7-a0ec-f3c138e6c738

📥 Commits

Reviewing files that changed from the base of the PR and between 9946809 and 1f3b126.

📒 Files selected for processing (2)
  • src/lib/bundle.test.ts
  • src/lib/bundle.ts

@merlinsantiago982-cmd merlinsantiago982-cmd force-pushed the fix/failure-bundle-download-safety branch from 1f3b126 to 113acfe Compare June 30, 2026 02:27
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