anthropics / anthropics/claude-code

claude-in-chrome: an UNGRANTED host makes executeScript-based tools hang their full timeout and blame the page, instead of denying

Đang mở
#93,348 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
area:browser-extension area:chrome bug has repro platform:macos
Ngôn ngữ chính
Python
Star
145k
Fork
23.1k
Chỉ số merge pull request
Chỉ số pull request đang chờ

Mô tả

## Summary

An `executeScript`-based browser tool called on a host the extension has **not been granted** does not return a permission error. It **hangs for its full timeout** and reports that the *page* is busy or still loading:

```
Failed to extract page text: Page still loading
(executeScript waited 45000ms for document_idle).
Error capturing screenshot: Script injection timed out after 5000ms —
the page is busy or mid-navigation ...
```

Every clause of that is false. The page is `readyState: "complete"`, the tab is `visibilityState: "visible"`, the connection is healthy, and `javascript_tool` answers instantly on the same tab in the same `browser_batch`.

The message misdirects to three things that are all fine — the page, the connection, and the browser selection — and never mentions permissions. Cost here: two separate multi-hour investigations across two days, both of which concluded "the Chrome connection is unstable."

## Reproduction

Grant the extension a host (e.g. `www.google.com`) and leave another ungranted (e.g. `example.com`). Then, in one tab:

| host | granted | `javascript_tool` | `get_page_text` | `computer` screenshot |
|---|---|---|---|---|
| `www.google.com` | yes | works | **works** | **works** |
| `example.com` | no | works | **45 000 ms timeout** | **5 000 ms timeout** |

Steps:

1. `tabs_context_mcp { createIfEmpty: true }`
2. `navigate` to the **ungranted** host.
3. `javascript_tool` → succeeds, returns the real `document.title`, `readyState: "complete"`, `visibilityState: "visible"`.
4. `get_page_text` on the same tab → hangs 45 s, then reports the page is still loading.
5. `navigate` the same tab to the **granted** host → `get_page_text` and screenshot both succeed immediately.
6. **Control:** navigate the same tab *back* to the ungranted host → fails again immediately.

Step 6 is what makes this a permission fault rather than a transient: the only variable is the host.

## What appears to be happening

There seem to be (at least) three injection paths that fail differently on an ungranted host:

| path | tools | on an ungranted host |
|---|---|---|
| immediate evaluation | `javascript_tool`, `navigate`, `chrome.tabs` reads | **succeeds** |
| `executeScript` at `document_idle` | `get_page_text`, `read_page`, `find`, `computer` screenshot | **hangs to timeout** |
| up-front permission check | `computer` click | **denies immediately, by name** |

A `computer` click on an ungranted domain returns `Permission denied for this action on this domain` — immediate and explicit. So the extension *can* produce a correct denial; the `executeScript` path just doesn't consult the grant before waiting.

A related contrast, same setup: `javascript_tool` is denied immediately and by name on some granted hosts (`Permission denied for JavaScript execution on this domain`). So `javascript_tool` and `executeScript` consult different policies, and only one of them reports failure honestly.

## Why this is worth fixing beyond the message

Chrome resets `runtime_granted_permissions` whenever its HMAC over `extensions.settings` fails to verify — a hard kill of Chrome can cause it. So grants can disappear with nobody having touched them, and the symptom is not "permission denied", it is every page-read and screenshot timing out while navigation keeps working. That reads exactly like a flaky connection.

Inside `browser_batch` it is worse: a 45 s hang blows the tool's response budget, so the batch returns `browser_batch did not respond in time` and the remaining actions are discarded — a third distinct message for the same root cause.

## Expected behaviour

`get_page_text`, `read_page`, `find` and `computer` screenshot should check the host grant **before** waiting for `document_idle`, and return the same immediate, named error that `computer` click already returns — ideally naming the host and pointing at the extension's site-access UI.

Failing that, the timeout message should not assert that the page is loading when the extension has not established that it can inject at all.

## Environment

- macOS 26.6.2 (Apple Silicon)
- Google Chrome 152.0.7977.83
- Claude extension 1.0.91
- Claude Code 2.1.267
- One Chrome install, one profile, extension present in that profile only

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Hướng nghiên cứu

Start by tracing the executeScript paths used by get_page_text, read_page, find, and computer screenshot, comparing them with computer click’s permission check. Reproduce on a granted and ungranted host, then verify these tools deny immediately with a named permission error rather than waiting for document_idle or blaming page loading; confirm browser_batch no longer loses remaining actions.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
javascript
Lĩnh vực
security, tooling
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Sôi nổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
55/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.