Skip to content

fix(tool): port upstream webfetch redirect rule checks (anomalyco/opencode#59748) - #1660

Open
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1793814180-webfetch-redirect-rules
Open

devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1793814180-webfetch-redirect-rules

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Issue for this PR

Closes #1658

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Ports the upstream webfetch permission fixes to the fork's packages/opencode/src/tool/webfetch.ts:

  • fix(core): apply webfetch URL rules to redirect targets anomalyco/opencode#59748: webfetch used fetch's default redirect: "follow", so only the URL the model passed was checked against the webfetch rules. An allowed page that redirects to a denied URL (for example http://169.254.169.254/... under {"*": "allow", "http://169.254.169.254/*": "deny"}) was fetched and returned to the model. Redirects are now followed by hand (redirect: "manual", max 10 hops). Each target is evaluated against the effective ruleset (ctx.permissions) before it is requested. A denied target throws PermissionDeniedError; as upstream does, the user is not asked again for redirect targets. Redirects to non-HTTP schemes fail.
  • fix(core): reject URL credentials and ignore fragments in web permissions anomalyco/opencode#61701: URLs with credentials are rejected, both the requested URL and redirect targets. Without this, a rule for https://docs.example.com* also matched https://[email protected]/. Fragments are dropped before rules are matched.
  • fix(core): match web permissions against the URL that is requested anomalyco/opencode#60505: the permission prompt matches the normalized URL.href, not the raw string the model typed.

Upstream made these changes in the v2 packages/core/src/tool/plugin/webfetch.ts. This PR adapts them to the fork's legacy tool and wraps the changes in altimate_change ... upstream_fix: markers. The failure cache, UA fallback and error messages are unchanged.

How did you verify your code works?

  • Added four tests to packages/opencode/test/tool/webfetch.test.ts: an allowed redirect is followed, a denied redirect target stops before it is requested, non-HTTP and endless redirects fail, and credentials are rejected. On main, the denied-redirect, scheme and credential tests fail. With this change, all 37 tests in webfetch.test.ts and webfetch-cache.test.ts pass.
  • bun run typecheck (tsgo) in packages/opencode passes, and so does the pre-push bun typecheck.
  • bun run script/upstream/analyze.ts --markers --base origin/main --strict: ok.

Cost side effects

None. A redirect issues the same number of HTTP requests as before. Rule checks are local.

Screenshots / recordings

Not a UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR
  • I checked for cost side effects (model calls, queries or cloud resources that grow with user data) and described them, or wrote "none"

Tracked in #1478.

Written by Devin


Summary by cubic

Fixes the webfetch tool's permission checks so allowed pages can no longer redirect to denied URLs, and incoming URLs are normalized before being matched against rules.

  • Follows redirects manually (max 10 hops) and checks each target against the effective ruleset before requesting it; denied targets throw without prompting the user again.
  • Rejects URLs with embedded credentials and drops URL fragments before matching rules, so a rule like https://docs.example.com* no longer matches https://[email protected]/.
  • Permission prompts now use the normalized URL.href instead of the raw input string.
  • Adds four tests covering allowed redirects, denied redirect targets, non-HTTP and endless redirects, and credential rejection.

Written for commit 0e4745a. Summary will update on new commits.

View guided diff Turn on auto-fix

…ncode#59748)

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Nov 4, 2026

Copy link
Copy Markdown

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2a864f37-f179-4638-829f-281ca27d2892

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@devin-ai-integration

Copy link
Copy Markdown
Author

CI note: the only red check is TypeScript, and it failed on one test unrelated to this change. test/altimate/learn/bootstrap-import-failure.test.ts timed out at 5000ms ("instance bootstrap survives a failed capture import"). The test passes locally on this branch (2 of 2 runs), and the same job passed on #1661. The Devin integration can't re-run jobs (HTTP 403), so a maintainer re-run of the job is needed.

Written by Devin

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.

webfetch follows redirects to URLs the permission rules deny

0 participants