Mọi tiện ích Chrome đều đi kèm một file manifest.json, và file này tiết lộ một phần rất đáng kể “trần năng lực” ở cấp trình duyệt của tiện ích đó: các API được yêu cầu, mẫu host, content script tĩnh, quyền tùy chọn và các kết nối bên ngoài được phép. Đây là tệp công khai nằm ngay trong gói cài đặt. Nhưng nó không chứng minh runtime có thực sự dùng những năng lực đã khai báo hay không, dữ liệu có rời khỏi máy hay không, hoặc việc truy cập tài khoản có diễn ra qua một luồng đăng nhập web riêng biệt hay không.
Tôi đã đọc mười tiện ích scraping và tự động hóa trình duyệt được chọn cho bài kiểm tra này, bao gồm cả Thunderbit của chúng tôi. Kết quả rất đa dạng. Có tiện ích không khai báo quyền truy cập site thường trực nào. Có tiện ích khai báo tới 13 quyền, bao gồm cả clipboardRead. Thunderbit là tiện ích duy nhất trong nhóm này khai báo debugger, một năng lực gắn CDP có phạm vi rủi ro khác hẳn so với truy cập trang, OAuth hay script do người dùng cung cấp.
Điều đó không phải là lời buộc tội. Một quyền rộng đôi khi là cách trung thực nhất để xây dựng một tính năng nào đó, còn một quyền hẹp có thể chỉ đơn giản là sản phẩm làm được ít hơn. Vấn đề là sự khác biệt này rất lớn, đã được công bố, nhưng lại không bao giờ xuất hiện trong các bảng so sánh.
Cách thực hiện
Mỗi tiện ích được tải xuống dưới dạng .crx từ endpoint cập nhật chính thức của Google — đúng URL mà Chrome tự dùng — sau đó được giải nén và phân tích. Không tiện ích nào được cài đặt và không có mã tiện ích nào được chạy. Đây chỉ là việc đọc một file JSON.
Việc tải được dàn đều, khoảng một request mỗi hai giây. Mỗi .crx, SHA-256 của nó, và manifest.json đã trích xuất đều được lưu lại làm bằng chứng. Thunderbit đi qua đúng cùng một script như chín tiện ích còn lại, không qua đường xử lý riêng, nên hàng của nó được suy ra chính xác như các hàng khác.
Phân tích dùng hai nhóm bằng chứng và giữ chúng tách biệt:
- Hành vi tĩnh được khai báo: mẫu host và các mục
content_scripts, gồmmatches,run_atvàall_frames. - Năng lực mà runtime có thể dùng: các API được đặt tên trong
permissionshoặcoptional_permissions. Những khai báo này cho thấy code có thể yêu cầu hay gọi gì, chứ không chứng minh là nó đã làm vậy.
Không gán điểm số kiểu “mạnh nhất”. debugger, userScripts, truy cập host rộng, scope OAuth, truy cập clipboard và nhắn tin ra ngoài đều phơi bày dữ liệu khác nhau và cần các điều kiện khác nhau. So sánh chúng đòi hỏi một mô hình đe doạ mà bài kiểm tra chỉ dựa trên manifest này không cung cấp.
Các kích thước bên dưới là tổng dung lượng đã giải nén, tính bằng MiB (2²⁰ bytes), cộng từ các entry ZIP.
Tính đến 2026-07-29. Tiện ích vẫn cập nhật; hãy kiểm tra lại trước khi trích dẫn.
Mười manifest khai báo gì

Tài liệu tham khảo chính thức: Chrome's permission declaration guide.
| Extension | Version | Unpacked | Files | Permissions | Site access | Reaches file:// |
|---|---|---|---|---|---|---|
| Axiom.ai | 5.1.0 | 37.1 MiB | 232 | 8 | http://*/* + https://*/* | ✅ |
| Table Capture | 11.0.41 | 21.1 MiB | 115 | 4 (+3 optional) | <all_urls> | ✅ |
| Magical | 3.119.1 | 16.8 MiB | 395 | 13 (+2 optional) | <all_urls> | ✅ |
| Thunderbit (ours) | 4.6.4 | 15.9 MiB | 78 | 8 recognized (+1 unrecognized array string: commands) | <all_urls> | ✅ |
| Clay for Chrome | 1.0.0 | 6.3 MiB | 51 | 6 | *://*/* (injects only on own domain) | — |
| Listly | 0.9.6 | 3.5 MiB | 84 | 7 | http://*/*, https://*/*, file:///*.html | ✅ |
| Hexomatic | 1.8.4 | 2.7 MiB | 37 | 2 | own domains only | — |
| Agenty | 2.9.7 | 2.2 MiB | 49 | 4 | none declared | — |
| Clip to Clay | 1.8.0 | 0.7 MiB | 16 | 4 | 2 named domains | — |
| TexAu v2 | 1.6.6 | 0.3 MiB | 12 | 6 | 14 named domains | — |
Hai tiện ích nữa có trong danh sách ứng viên nhưng không có mặt trong bảng, vì những lý do đáng để nói riêng.
Độ rộng khác nhau là do thiết kế, không phải do kích thước
Agenty không khai báo host permissions và cũng không ship content script nào cả. Bốn quyền của nó là activeTab, scripting, identity và identity.email. activeTab là quyền hẹp nhất: nó chỉ cấp truy cập vào tab hiện tại sau khi bạn bấm vào tiện ích, và chỉ cho tới khi bạn rời trang. Không có gì chạy trên trang của bạn trừ khi bạn chủ động gọi nó. Và nó chỉ nặng 2.2 MiB.
Axiom.ai khai báo http://*/* và https://*/*, chèn content script khớp với <all_urls>, và sau khi giải nén thì chiếm 37.1 MiB trên 232 file — lớn gấp 17 lần Agenty, với quyền truy cập thường trực vào mọi trang bạn ghé thăm.
Hexomatic đứng cùng kiểu với Agenty: hai quyền (storage, tabs), không có host permission, content script chỉ giới hạn trên hai domain của chính nó.
Clay for Chrome là một dạng khác cần tách riêng: nó khai báo *://*/* làm host permission nhưng chỉ chèn content script trên domain của chính nó. Năng lực thường trực thì rộng; hành vi tự động thì hẹp. Một bảng quyền đơn thuần sẽ nhập nhằng hai thứ này.
Năm trong mười tiện ích có thể chạm vào file trên máy bạn
file:/// không phải là website. Nó là filesystem cục bộ của bạn được hiển thị trong một tab trình duyệt — một file PDF bạn mở, một bản xuất HTML, hay một hóa đơn đã tải xuống.
Tài liệu tham khảo chính thức: Chrome match-pattern documentation.
Ba tiện ích nói điều đó một cách trực tiếp. Hai tiện ích khác đạt tới nó mà không cần nêu đích danh: <all_urls> bao gồm cả scheme file:.
| Extension | How it reaches file:// | Names file:// in its manifest? | Where |
|---|---|---|---|
| Magical | matches file:///* — every local file Chrome will render, not just HTML — in four of its six content-script entries | ✅ | content scripts, and web_accessible_resources |
| Listly | matches file:///*.html | ✅ | content scripts |
| Table Capture | <all_urls> content scripts, and it also names the scheme | ✅ | web_accessible_resources |
| Axiom.ai | purely by virtue of the <all_urls> wildcard | — | nowhere |
| Thunderbit (ours) | purely by virtue of the <all_urls> wildcard | — | nowhere |
http://*/* và https://*/* không bao phủ file://; <all_urls> và *://*/* cũng khác nhau ở điểm này. Năm tiện ích ở đây là những tiện ích mà khai báo của chúng vươn tới scheme đó bằng cách này hay cách khác — không phải vì chúng chọn dạng wildcard nào.
Chrome đặt toàn bộ cơ chế này sau một công tắc riêng cho từng tiện ích là “Allow access to file URLs”, và công tắc này tắt theo mặc định, nên khai báo chỉ là một yêu cầu chứ không phải một đặc quyền được cấp. Năm trong mười là con số trung thực, và hai trong số năm tiện ích đó không hề viết file:// ở bất kỳ đâu trong manifest: Axiom.ai và của chúng tôi.
Con số này có tính cả web_accessible_resources, không chỉ content scripts và host permissions. Table Capture có nêu file://*/* ở đó; nếu bỏ block này đi thì sẽ vô tình xếp nó vào nhóm tiện ích có manifest chạm tới file mà không gọi tên scheme.
Những quyền bạn không thấy cho tới khi chúng được yêu cầu

optional_permissions được khai báo từ đầu nhưng chỉ được yêu cầu lúc runtime, nên chúng không xuất hiện trong prompt khi cài đặt. Có hai tiện ích dùng chúng, và một trong số đó là đáng kể.
| Extension | optional_permissions | The one that matters |
|---|---|---|
| Table Capture | userScripts, downloads, identity | userScripts can run user-supplied scripts in page contexts after Chrome's user gate is enabled |
| Magical | downloads, webRequest | webRequest observes network traffic |
userScripts không hiện ra cho tới khi được yêu cầu, và vô hình với bất kỳ ai chỉ nhìn vào số lượng quyền.
Nó còn có một “cổng” mà các quyền khác trong bài kiểm tra này không có, và nếu bỏ qua điều đó thì sẽ đánh giá quá cao nó. Chỉ khai báo userScripts thôi là chưa đủ để dùng: Chrome yêu cầu người dùng phải có một hành động rõ ràng trước. Trước Chrome 138, đó là Developer Mode, bật toàn cục ở chrome://extensions. Từ Chrome 138 trở đi, đó là công tắc Allow User Scripts theo từng tiện ích trên trang chi tiết của chính tiện ích đó, mặc định tắt. Vì vậy với một cài đặt thông thường, năng lực này chỉ được khai báo chứ chưa hoạt động. Kết luận chính xác là có điều kiện: Table Capture có thể làm cho API userScripts khả dụng sau khi người dùng bật cổng của Chrome. Bài kiểm tra này không đo việc người dùng có thường xuyên vào trang cài đặt đó hay bật công tắc hay không.
Cả hai đều không bị giấu; chúng đều nằm trong manifest. Một bảng bỏ qua block optional sẽ đánh giá thấp hai sản phẩm này.
Thời điểm chèn, không chỉ phạm vi
Cách một content script được chèn vào cũng rất quan trọng và làm thay đổi bức tranh. document_start là hook sớm nhất mà Chrome cung cấp; all_frames vươn vào cả các iframe nhúng từ bên thứ ba.
Mọi mục trong nhóm có chèn tĩnh vào tất cả frames, sắp theo thời điểm khai báo:
| Extension | run_at | all_frames | Content-script match pattern |
|---|---|---|---|
| Table Capture | document_start | ✅ | <all_urls> |
| Listly | document_start | ✅ | file:///*.html plus all of http and https |
| Axiom.ai | document_start | ✅ | own domains only |
| Clay for Chrome | document_start | ✅ | own domains only |
| Thunderbit (ours) | document_end | ✅ | <all_urls> |
| Magical | document_idle | ✅ | file:///* plus broad http and https |
| TexAu | document_idle (unset) | ✅ | fourteen named patterns |
Table Capture và Listly chạy ở hook sớm nhất trên các pattern khớp rộng. Axiom.ai và Clay for Chrome cũng dùng cùng thời điểm đó, nhưng chỉ trên domain của chính chúng — cùng mức “quyết liệt”, mục tiêu hẹp hơn.
Với khai báo tĩnh, <all_urls> cộng với all_frames là trần về độ rộng khớp, và cả Table Capture lẫn Thunderbit đều nằm ở đó. Nhưng thời điểm được khai báo khác nhau: Table Capture dùng document_start; content script tĩnh của Thunderbit dùng document_end. Các API runtime là một nhóm năng lực riêng và không thể suy ra từ bảng này.
Đếm số quyền là một chỉ số tổng hợp tệ. Table Capture chỉ khai báo bốn quyền — ít hơn đa số ở đây — nhưng lại chèn vào document_start trên tất cả frames, khớp <all_urls>, cộng thêm userScripts theo yêu cầu.
Ai được phép nhắn tin tới tiện ích
externally_connectable kiểm soát những trang web hoặc tiện ích khác nào có thể gửi tin nhắn trực tiếp tới background script của một tiện ích. Mặc định của nó khá ngược直 giác.
Không khai báo khóa này mới là thiết lập mở. Theo mặc định của Chrome khi externally_connectable không xuất hiện, bất kỳ tiện ích nào cũng có thể kết nối, còn không có trang web nào được phép. Khai báo nó là để giới hạn.
Nếu nhìn theo cách đó, bảng sẽ bị đảo chiều:
| Extension | externally_connectable declaration | Who can message it |
|---|---|---|
| Agenty | omitted | Permissive default — any extension may connect, no web page may |
| Clay for Chrome | omitted | Permissive default — any extension may connect, no web page may |
| Clip to Clay | omitted | Permissive default — any extension may connect, no web page may |
| Listly | omitted | Permissive default — any extension may connect, no web page may |
| Table Capture | omitted | Permissive default — any extension may connect, no web page may |
| TexAu | omitted | Permissive default — any extension may connect, no web page may |
| Thunderbit (ours) | omitted | Permissive default — any extension may connect, no web page may |
| Hexomatic | eight extension IDs and six web origins | Opens both channels from a closed baseline |
| Axiom.ai | seven web origins, no ids | Extension channel closed, seven web pages opened |
| Magical | {"ids": [], "matches": []} | The only extension here that closes both channels explicitly |
Quy tắc của Chrome có hai tầng. Từ tài liệu tham chiếu manifest:
| Situation | Who may connect |
|---|---|
| the whole key is absent | "all extensions can connect, but no web pages can connect" |
key present, ids unset or [] | "no extensions or apps can connect" |
key present, matches unset or [] | "no web pages can connect" |
Thiết lập mở mặc định gắn với việc toàn bộ khóa bị thiếu. Khi khóa đã xuất hiện, cả hai trường con đều bắt đầu ở trạng thái đóng, và việc nêu giá trị cụ thể sẽ mở rộng từng kênh.
Axiom.ai khai báo khóa nhưng chỉ có matches. Vì vậy ids không được đặt, nghĩa là không có tiện ích nào có thể nhắn tin tới nó — kênh extension đã đóng, chứ không hề để mở. Thứ nó mở ra là bảy web origin, trong đó chỉ có một origin thuộc Axiom: hai origin là bên thứ ba không thể quy cho Axiom (*://*.tgwc.space/*, *://*.bitmachine.co.uk/*), còn lại là localhost, 0.0.0.0, một host của Google APIs, và một nền tảng mạng xã hội lớn mà nó không vận hành.
Hexomatic mở kênh extension cho tám ID được đặt tên. Khi khóa đã có mặt, baseline là 0 extension; nêu tám ID sẽ mở thành tám. Sáu matches của nó mở rộng kênh còn lại từ không có gì, và trong số đó có hai mục là http://localhost:8000/* và http://localhost:3000/* qua HTTP thường — bất kỳ thứ gì đang trả lời trên các cổng đó trên máy người dùng đều nằm trong allowlist.
Bảy trong mười tiện ích bỏ qua khóa hoàn toàn, bao gồm cả của chúng tôi, và đó là những tiện ích đang ở trạng thái mặc định mở cho nhắn tin extension-to-extension. Hai tiện ích đóng kênh đó: Magical đóng tường minh với ids: [], còn Axiom.ai thì khai báo khóa nhưng không bao giờ nhắc tới ids. Magical là tiện ích duy nhất đóng cả hai.
Câu cuối cùng đó là lý do phải đọc manifest thay vì chỉ đếm quyền. Cùng một tiện ích có thể rộng ở một trục nhưng lại nghiêm ngặt nhất nhóm ở trục khác.
Trục mà không ai đếm: OAuth scopes
Manifest có thể chứa block oauth2, và các scope bên trong là quyền truy cập vào tài khoản của bạn ở các công ty khác — một kiểu phạm vi khác hẳn những gì nói ở trên, và không một phép đếm quyền nào phản ánh được.
Tài liệu tham khảo chính thức: Google OAuth 2.0 scope list.
| Extension | oauth2 scopes requested |
|---|---|
| Axiom.ai | openid, email, profile, auth/drive, auth/spreadsheets |
| Table Capture | auth/spreadsheets, auth/userinfo.email |
| Agenty | openid, email, profile |
| The other seven, including ours | none declared |
https://www.googleapis.com/auth/drive là scope rộng. Google có cung cấp scope hẹp hơn là drive.file, chỉ cấp quyền cho những file mà ứng dụng tự tạo ra hoặc người dùng chọn rõ ràng; còn auth/drive thì cho phép xem, sửa, tạo và xóa trên toàn bộ Google Drive của người dùng. auth/spreadsheets có cùng hình thái đối với mọi bảng tính mà tài khoản đó có thể truy cập. Cả Axiom.ai lẫn Table Capture đều ghép scope tài khoản Google với quyền truy cập trang <all_urls>.
Có hai giới hạn đối với điều mà bảng này chứng minh. Scope chỉ là được yêu cầu, không phải được cấp — Google sẽ hiện màn hình đồng ý và người dùng có thể từ chối, và tiện ích có thể chẳng bao giờ gọi API. Và manifest chỉ nhìn thấy OAuth đi qua luồng identity của Chrome; một tiện ích đưa bạn sang trang đăng nhập web thay vì vậy thì ở đây sẽ không khai báo gì. Bảy số 0 có nghĩa là “không được yêu cầu trong file này”, chứ không phải “không có quyền truy cập vào tài khoản Google của bạn” — bao gồm cả của chúng tôi, đó là lý do trục này được báo cáo thay vì được giả định là hẹp.
Tiện ích của chúng tôi, trên cùng thang đo
Thunderbit 4.6.4 đã đi qua cùng một bộ phân tích manifest như chín tiện ích còn lại. Gói của nó nặng 15.9 MiB sau khi giải nén, trên 78 file.
Hành vi tĩnh được khai báo: <all_urls> xuất hiện trong host permissions và trong các match của content script. Script tĩnh chạy vào all_frames tại document_end. Vì <all_urls> bao gồm cả file:, manifest có thể chạm tới file cục bộ sau khi người dùng bật công tắc file-access của Chrome. Thunderbit cũng bỏ qua externally_connectable, nên mặc định của Chrome cho phép tin nhắn từ bất kỳ tiện ích nào nhưng không cho phép từ web page.
Trần năng lực runtime: mảng permissions chứa chín chuỗi: activeTab, commands, debugger, offscreen, scripting, sidePanel, storage, tabGroups và tabs. Chrome nhận ra tám trong số này là quyền; commands là một khóa manifest cấp cao và không có tác dụng khi xuất hiện như một entry trong mảng này. Thunderbit là tiện ích duy nhất trong nhóm khai báo debugger, và quyền này có thể gắn CDP vào một tab. Manifest cũng làm cho scripting sẵn sàng để đăng ký ở runtime. Những API này tạo ra năng lực vượt ra ngoài hàng document_end tĩnh, nhưng việc đọc manifest không thể kết luận Thunderbit có gọi một CDP method cụ thể hay đăng ký script ở một thời điểm sớm hơn nào không.
Phân biệt này chặn lại vài phép so sánh rất hấp dẫn nhưng không hợp lệ. Việc không có permission hẹp hơn như cookies không hề giới hạn những gì code có debugger có thể truy cập. Việc không có clipboardRead không phải là bằng chứng rằng không thể chạm tới clipboard. Ngược lại, sự xuất hiện của debugger cũng không phải bằng chứng rằng những đường đó đã được dùng. Muốn trả lời bất kỳ câu nào như vậy đều cần soi source code hoặc trace runtime, mà bài này không làm.
Trên thước đo này, Thunderbit rộng về truy cập site tĩnh, là tiện ích duy nhất trong nhóm khai báo debugger, và đang ở mặc định của Chrome cho nhắn tin giữa các tiện ích. Không có thứ hạng “mạnh nhất” duy nhất, vì audit này không cung cấp một mô hình đe doạ chung cho CDP, OAuth, userScripts, clipboard và host access.
Thiết kế tiết chế mà chẳng ai quảng bá
TexAu chỉ nặng 0.3 MiB — nhỏ nhất ở đây, chỉ bằng một nửa nhóm kế tiếp — và nó đặt tên cho 14 site cụ thể thay vì dùng wildcard: mạng xã hội, một nền tảng dành cho developer, các nền tảng xuất bản, một sản phẩm chat, nhà cung cấp dữ liệu doanh nghiệp, và domain của chính nó. Content script của nó khớp đúng 14 mục đó.
Bạn có thể đọc manifest này và biết chính xác tiện ích đang hoạt động ở đâu. Đây cũng là một dạng công bố sản phẩm — danh sách mục tiêu nói rõ công cụ dùng để làm gì hơn cả phần marketing.
Đổi lại là một sự đánh đổi thật sự: danh sách có tên không thể scrape một site không có trong đó, và mỗi mục tiêu mới đều cần một bản phát hành. Nhưng “14 domain được đặt tên” và “mọi URL tồn tại” là hai đề xuất rất khác nhau, và chỉ một trong số đó là dễ đọc.
Hai sản phẩm không đúng như danh sách nói
Tiện ích của Captain Data không được phân phối công khai. Endpoint cập nhật của Google trả về HTTP 204 với body rỗng cho extension ID của nó — phản hồi dành cho thứ mà store sẽ không phục vụ ẩn danh. Ngược lại, trang listing của nó được phục vụ ẩn danh — HTTP 200, 509,829 bytes. Những gì phần capture không thể tìm thấy ở đó là chuỗi version, ngày cập nhật gần nhất hay số lượt cài đặt; ghi chú của script nói rằng giá trị null ở đây là bằng chứng yếu, và không quan sát thấy tường đăng nhập nào. ID là thật và thuộc bên thứ nhất, nên cách đọc hợp lý nhất là phân phối qua link-only hoặc không public listing, nhưng tôi không thể phân biệt điều đó với việc bị gỡ khỏi store và sẽ không đoán mò.
Dataflow Kit không có tiện ích Chrome nào cả. Trang của họ mô tả một web app được host sẵn, với chọn lựa bằng point-and-click và một REST API. Dù vậy nó vẫn bị đưa vào danh sách shortlist tiện ích Chrome — thường thì các danh sách kiểu này được dựng lên như vậy.
Độ cũ và độ rộng, vì cả hai đều miễn phí để kiểm tra
Metadata của store bổ sung bối cảnh chọn sản phẩm ngoài phần quyền. Cùng các trường đó được thu thập cho mọi tiện ích vào 2026-07-30.
| Extension | Store version | Last updated | Install bucket |
|---|---|---|---|
| Thunderbit (ours) | 4.6.4 | July 28, 2026 | 200,000 |
| Listly | 0.9.6 | July 25, 2026 | 100,000 |
| Axiom.ai | 5.1.0 | July 20, 2026 | 100,000 |
| Table Capture | 11.0.41 | June 26, 2026 | 200,000 |
| Magical | 3.119.1 | April 4, 2026 | 200,000 |
| Agenty | 2.9.7 | February 8, 2026 | 10,000 |
| TexAu | 1.6.6 | August 20, 2025 | 7,000 |
| Clay for Chrome | 1.0.0 | April 9, 2025 | 10,000 |
| Clip to Clay | 1.8.0 | April 8, 2025 | 1,000 |
| Hexomatic | 1.8.4 | September 6, 2024 | 3,000 |
| Captain Data | — | — | not publicly served |
Ba sản phẩm đã hơn một năm chưa phát hành, còn Hexomatic thì gần hai năm. Với tiện ích, điều này quan trọng hơn với thư viện: Chrome phát hành bản ổn định khoảng bốn tuần một lần, và chính nền tảng extension cũng thay đổi liên tục bên dưới. userScripts đã chuyển cổng người dùng trong Chrome 138; một tiện ích lần cuối phát hành năm 2024 được xây dựng theo bộ quy tắc khác với trình duyệt hiện đang ép các quy tắc đó.
Hai điều mà bảng này không phải. Số lượt cài đặt là được Google chia theo bucket — 1,000 / 3,000 / 7,000 / 10,000 / 100,000 / 200,000 — nên chúng chỉ so sánh theo bậc độ lớn chứ không tinh hơn, và một số sản phẩm còn quảng cáo con số lớn hơn trong marketing của chính họ. Một ngày gần đây chỉ là факт về việc phát hành, không phải phán quyết về chất lượng bảo trì hay rủi ro quyền.
Một hệ quả hữu ích: version trên store khớp với version manifest ở mọi package trong mười package đã phân tích. Các file CRX mà bài kiểm tra này đọc chính là thứ store đang phục vụ hôm nay, chứ không phải bản sao cũ.
Tính mới ảnh hưởng tới mức độ cần theo dõi lại, chứ không làm đổi ngữ nghĩa của manifest. Một tiện ích theo domain đặt tên, dù cập nhật từ một năm trước, vẫn có thể phơi bày bề mặt trang ít hơn một tiện ích wildcard được phát hành hôm qua. Package mới hơn vẫn có thể là lựa chọn vận hành tốt hơn nếu nó theo kịp thay đổi của Chrome. Với shortlist, hãy dùng ngày trên store để quyết định cái gì cần test lại, rồi dùng manifest để quyết định cái gì cần xem xét năng lực kỹ hơn. Đừng biến hai cột này thành một điểm số.
Manifest không nói cho bạn điều gì
Quyền được khai báo là trần năng lực, không phải hành vi. <all_urls> nghĩa là tiện ích có thể đọc mọi trang. Nó không có nghĩa là nó đang làm vậy, hay có gì đó rời khỏi máy bạn. Muốn biết thực sự xảy ra gì thì phải quan sát traffic mạng ở runtime — đó là một công việc khác, không được làm ở đây, và không điều nào ở trên nên bị hiểu là bằng chứng của hành vi lạm dụng.
Bài review liên quan: Chrome extension testability experiment.
Ba ranh giới nữa:
- Chrome chặn khá nhiều thứ trong số này. File access tắt mặc định;
activeTabcố tình rất hẹp; quyền tùy chọn cần prompt lúc runtime; người dùng sẽ thấy danh sách quyền khi cài. - Quyền rộng thường là cần thiết. Một công cụ có nhiệm vụ “trích một bảng từ bất kỳ trang nào bạn đang xem” không thể chạy chỉ với danh sách domain được đặt tên. Phạm vi hẹp đôi khi là kỷ luật, đôi khi chỉ là sản phẩm nhỏ hơn.
- Một version, một ngày. Mọi con số đều lấy từ package được phục vụ vào 2026-07-29.
Các chỉnh sửa quan trọng trong phân tích
Các con số đã công bố dùng ba quy tắc dễ bị viết sai khi làm manifest parser nhanh. Thứ nhất, <all_urls> bao gồm scheme file:, nhưng Chrome vẫn giữ truy cập file thật sự sau một toggle do người dùng điều khiển. Thứ hai, phải kiểm tra web_accessible_resources.matches cùng với content scripts và host permissions; đó là chỗ Table Capture gọi đích danh file://*/*. Thứ ba, externally_connectable có default khác nhau tuỳ việc toàn bộ khóa bị thiếu hay khóa tồn tại nhưng một trường con rỗng. Các bảng trên áp dụng các quy tắc này một cách nhất quán.
Tổng permission của Thunderbit cũng phân biệt chuỗi thô với các Chrome permission được nhận diện. Mảng của nó có chín mục, nhưng commands thuộc khóa cấp cao của manifest, nên số hiệu dụng dùng ở đây là tám permission được nhận diện cộng một chuỗi không được nhận diện. Cuối cùng, khai báo content_scripts tĩnh không phải bằng chứng rằng code gọi scripting.registerContentScripts hay một CDP method. Những khả năng đó chỉ xuất hiện dưới dạng năng lực runtime, không bao giờ là hành vi đã quan sát. Các manifest thô, SHA CRX và output parser là dấu vết kiểm toán cho các bước chuẩn hoá này, nên người đọc không cần phải tin prose một cách mù quáng.
Khi quyết định cài thực tế, hãy so sánh ít nhất bốn chiều riêng biệt: trang nào nằm trong phạm vi mặc định, hành động cụ thể nào của người dùng mở rộng thêm phạm vi, những API trình duyệt hay tài khoản nào sẽ khả dụng, và bên gọi nào từ bên ngoài có thể nhắn tin tới tiện ích. Mô hình activeTab của Agenty, userScripts có cổng của Table Capture, scope Drive của Axiom.ai, và khai báo debugger của Thunderbit không nằm trên cùng một thước đo tuyến tính. Chúng là các câu trả lời khác nhau cho những câu hỏi đe doạ khác nhau.
Đây là so sánh đó, áp dụng lên bốn thiết kế cố tình khác nhau:
| Extension | Page scope visible in the manifest | Additional gate | Non-page capability in this audit | External caller posture |
|---|---|---|---|---|
| Agenty | no host permission or static content script | user invokes activeTab on the current tab | Chrome identity permissions | key omitted: any extension may connect, no web page may |
| Table Capture | static scripts on <all_urls> in all frames at document_start | file access is off by default; userScripts needs Chrome's separate user gate | optional userScripts, downloads, and identity | key omitted: any extension may connect, no web page may |
| Axiom.ai | HTTP and HTTPS wildcard access; static scripts at document_start on its own domains | OAuth consent for requested Google scopes | Drive and Sheets OAuth scopes declared | extension callers closed; seven web origins opened |
| Thunderbit | <all_urls> host access and static scripts in all frames at document_end | file access is off by default; attaching debugger has Chrome-controlled user-visible behavior | debugger, scripting, tabs, and related browser APIs declared | key omitted: any extension may connect, no web page may |
Bảng này vẫn không cho ra một “người thắng”. Việc Agenty chỉ có quyền site thường trực rất hẹp không nói gì về backend của nó xử lý dữ liệu gửi lên ra sao. Scope tài khoản của Axiom.ai không thể so với việc đọc trang hiện tại của một tiện ích. Khai báo userScripts của Table Capture là inert cho tới khi người dùng bật cổng riêng của nó. Quyền debugger của Thunderbit phơi ra một bề mặt điều khiển trình duyệt rất rộng, nhưng manifest không cho thấy code của nó gọi những CDP domain hay method nào. Mỗi hàng cho bạn biết cần kiểm tra tiếp cái gì: traffic mạng runtime, source code, luồng consent hay trace API của trình duyệt.

Sự tách biệt này cũng quan trọng khi đọc prompt cài đặt của Chrome. Một phép đếm quyền thô không thể cho thấy timing, độ phủ qua frame, OAuth scope, web_accessible_resources, hay việc bỏ trống khóa externally_connectable. Ngược lại, một khai báo rộng không phải là bằng chứng của việc thu thập hay rò rỉ. Kết quả hữu ích của một manifest audit là một kế hoạch kiểm thử runtime có thứ tự ưu tiên: xác định bề mặt dữ liệu, ghi nhận cổng do người dùng bật, rồi quan sát xem đường được khai báo có thực sự được dùng hay không.
Cách đọc của bạn
Bài review liên quan: browser automation guide.
chrome://extensions→ Details cho thấy những site access nào đã được cấp, và cho phép bạn chuyển sang on click với mọi thứ không cần quyền thường trực. Điều đó thu hẹp nửa phần site-access của những gì nói ở trên. Nó không chạm vào inbound messaging (externally_connectablevẫn đi tới service worker bất kể thế nào), hay các quyền ở cấp trình duyệt. Thunderbit khai báodebuggerlà điểm rất đáng chú ý ở đây. Tài liệu bảo mật extension chính thức của Chromium nói rằng debugger API “trong một số trường hợp cũng có thể đi vòng qua các hạn chế thông thường khác, chẳng hạn host permissions hoặc file access”, nên đặt site access sang “on click” không giới hạn được những gì nó có thể chạm tới. Và điều khiển đó cũng không chạm vàotabs,webNavigation,clipboardRead,downloads, hay bất cứ thứ gì trongoptional_permissions.- Với file thô, package nằm dưới thư mục
Extensions/<id>/<version>/của Chrome. Hãy đọc sáu trường:permissions,optional_permissions,host_permissions,content_scripts(tứcmatches,run_atvàall_framesbên trong),externally_connectable— nhớ rằng một khóa vắng mặt là mở cho extension caller — vàweb_accessible_resources, nơimatchescó thể gọi tên những scheme mà content scripts không hề nêu. Trường cuối của Thunderbit có hai entry<all_urls>phơi raindex.htmlvà hai script bundled cho mọi origin, vớiuse_dynamic_url: false, cho phép một trang kiểm tra xem các URL extension ổn định này có resolve hay không. - Kiểm tra ngày cập nhật trên store so với version Chrome hiện tại.
Công bố và tài nguyên: bài viết này được xuất bản bởi Thunderbit, và tiện ích của chúng tôi cũng nằm trong cùng bảng và cùng parser. open-source scraper pillar của chúng tôi bao quát các công cụ không phải tiện ích extension.
Thử Thunderbit để trích xuất dữ liệu web
Bản rút gọn
Mười tiện ích scraping và tự động hóa, bao gồm cả của chúng tôi, đều được đọc từ manifest của chính chúng.
Agenty không khai báo site access và cũng không có content script, chỉ hoạt động trên tab bạn đang xem khi bấm vào nó, với dung lượng 2.2 MiB. Axiom.ai khai báo mọi URL HTTP và HTTPS trên 37.1 MiB. Magical khai báo 13 quyền, bao gồm clipboardRead — và cũng là tiện ích duy nhất ở đây đóng hoàn toàn inbound messaging. Table Capture chỉ khai báo bốn quyền, nhưng lại chèn ở document_start vào tất cả frames trên <all_urls> — cùng mức ceiling match mà của chúng tôi đạt tới, nhưng sớm hơn — cộng thêm userScripts theo yêu cầu. TexAu nhỏ nhất, và nó đặt tên cho nhiều target nhất — 14 pattern trên 13 thuộc tính khác nhau. Nó không phải là duy nhất gọi tên chúng: Clip to Clay khai báo hai mục (clay.com và một site bên thứ ba), còn Hexomatic và Clay for Chrome đặt tên domain của chính họ. TexAu là tiện ích duy nhất mà danh sách được đặt tên chủ yếu là site của người khác. Năm trong mười tiện ích có thể chạm vào file trên máy bạn, trong đó hai tiện ích — Axiom.ai và của chúng tôi — làm được điều đó mà không hề viết file://.
Thunderbit, của chúng tôi, nằm ở phía rộng hơn: <all_urls> cho cả host access và static injection, cộng thêm debugger, thứ mà không tiện ích nào khác trong nhóm này khai báo. Nó cũng nằm ở mặc định của Chrome cho phép tin nhắn từ bất kỳ tiện ích nào, và nó chạm tới file:// sau khi người dùng bật cổng file-access của Chrome.
Một khai báo là trần, không phải hành vi, và không điều nào trong số này cho thấy lạm dụng. Nhưng chúng đã được công bố, miễn phí để kiểm tra, và độ chênh lệch giữa hai đầu lớn hơn bất kỳ thứ gì trên các trang sản phẩm.
Thử Thunderbit để trích xuất dữ liệu web Get Started Free
Câu hỏi thường gặp
Quyền rộng có nghĩa là tiện ích đang làm gì đó sai không — và tại sao đếm quyền lại không đủ?
Không, và vì đếm quyền bỏ sót hai thứ. <all_urls> có nghĩa là tiện ích có thể đọc mọi trang bạn ghé thăm; nó không nói gì về việc nó làm gì hay có gì đó rời khỏi máy bạn hay không, và một công cụ được xây để trích dữ liệu từ bất kỳ trang nào thì thật sự không thể hoạt động chỉ dựa trên danh sách domain được đặt tên. Phát hiện ở đây là độ rộng của phạm vi, không phải hành vi sai — muốn biết hành vi thực tế phải phân tích traffic runtime, mà bài này không làm. Còn về đếm số lượng: cài đặt injection không phải là quyền, nên Table Capture chỉ khai báo bốn quyền nhưng lại chèn ở document_start, vào all_frames, khớp <all_urls>. Và optional_permissions không hề xuất hiện trong prompt cài đặt — Table Capture có thể yêu cầu userScripts lúc runtime, cho phép chạy script do người dùng cung cấp trong context của trang, còn Magical có thể yêu cầu webRequest.
Tiện ích nào xin ít nhất?
Agenty: bốn quyền, không host permissions, không content script. Nó dựa vào activeTab, quyền chỉ cấp truy cập vào tab hiện tại sau khi bạn bấm tiện ích và chỉ kéo dài cho tới khi bạn rời trang. Hexomatic đứng kế tiếp, với hai quyền và content script chỉ giới hạn trên domain của chính nó.
Làm sao một tiện ích có thể chạm vào file cục bộ của tôi mà không khai báo file://?
Vì <all_urls> bao gồm cả scheme file:. Listly, Magical và Table Capture đều gọi đích danh pattern file:// — Magical trong content scripts và Table Capture trong web_accessible_resources. Axiom.ai và Thunderbit chạm tới nó qua wildcard mà không nhắc tới ở đâu cả. http://*/* và https://*/* không bao phủ file://. Chrome giữ file access tắt theo mặc định, sau một toggle riêng cho từng tiện ích, nên khai báo chỉ là một yêu cầu chứ không phải sự cho phép.
externally_connectable là gì, và tại sao không khai báo nó lại là lựa chọn mở?
Nó chỉ ra các web origin hoặc extension ID được phép nhắn tin tới background script của một tiện ích. Mặc định của Chrome khi khóa này không có mặt là bất kỳ tiện ích nào cũng có thể kết nối và không có trang web nào được phép. Bảy trong mười tiện ích này bỏ qua nó, bao gồm cả Thunderbit. Khi khóa hiện diện, Hexomatic mở kênh extension cho tám ID được đặt tên; Axiom.ai mở bảy web origin nhưng đóng kênh extension; Magical khai báo danh sách rỗng cho cả hai, đóng cả hai kênh.
Manifest của Thunderbit khai báo gì?
<all_urls> cho host access và static content-script injection, trong all_frames tại document_end; 15.9 MiB trên 78 file; và chín chuỗi trong mảng permission. Tám mục là quyền được Chrome nhận diện: activeTab, debugger, offscreen, scripting, sidePanel, storage, tabGroups và tabs. commands là khóa manifest cấp cao và không có tác dụng trong mảng này. Không có tiện ích nào khác trong nhóm này khai báo debugger. Thunderbit cũng chạm tới file:// thông qua <all_urls> sau khi cổng file-access của Chrome được bật, và nó bỏ qua externally_connectable. Hành vi runtime không được chạy, nên bài kiểm tra không khẳng định tiện ích thực sự gọi CDP hay method scripting nào.


