Is Website Downloader safe?
Website Downloader is medium risk. Opening Website Downloader or finishing a download posts a telemetry event to Tinybird. A side-panel event carried a persistent UUID, language, timezone, version, platform, browser, user-agent; download events also add the page URL.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Download events send page URLs to Tinybird
Opening Website Downloader or finishing a download posts a telemetry event to Tinybird.
A side-panel event carried a persistent UUID, language, timezone, version, platform, browser, user-agent; download events also add the page URL.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
You open the extension panel or complete a page download.
The extension sends a telemetry event to Tinybird with your browser context and, for download events, the downloaded page URL.
- Content-Type
- application/json
- Authorization
- Bearer <redacted>
- Event namepanel.opened
Shows which extension action happened, such as opening the panel or finishing a download.
- Persistent user ID7d45c0de-9d3e-4b69-9a40-3adf3b3476f6 (illustrative)
Lets the analytics service tie separate extension events back to the same browser profile.
- Downloaded page URLhttps://docs.example.com/private/project-plan.html (illustrative)
Shows which page you downloaded and can reveal the site, path, and query string for that page.
- Language and timezoneen-US, UTC
Adds regional context to your event and can narrow down where and how the browser is used.
- Browser and platformChromium on Linux, extension version 3.0.24
Describes your browser environment and can help distinguish one device profile from another.
- User agentMozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/126.0.0.0 Safari/537.36 (illustrative)
Provides detailed browser and operating-system information as part of the telemetry event.
The shared telemetry sender builds the JSON event and posts it to Tinybird
Readable side-panel sender and metadata collector
chunks/sidepanel-B-KAhS5d.jsconst TINYBIRD_LOCAL_ENDPOINT = "http://localhost:7181/v0/events?name=analytics_events", TINYBIRD_CLOUD_ENDPOINT = "https://api.europe-west2.gcp.tinybird.co/v0/events?name=analytics_events", TINYBIRD_LOCAL_TOKEN = "<redacted>", TINYBIRD_CLOUD_TOKEN = "<redacted>";async function getOrCreateUserId() { const M = await chrome.storage.sync.get("user_id"); if (M.user_id) return M.user_id; const F = crypto.randomUUID(); return await chrome.storage.sync.set({ user_id: F }), F}async function collectMetadata() { const M = await detectBrowser(), F = navigator.userAgentData; return { timestamp: new Date().toISOString(), timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, language: navigator.language, extensionId: chrome.runtime.id, version: chrome.runtime.getManifest().version, platform: F?.platform || navigator.platform, browser: M, userAgent: navigator.userAgent, isProduction: !0 }}async function tbEvent(M, F = {}) { try { const U = await getOrCreateUserId(), Z = await collectMetadata(), rt = { event_name: M, userId: U, timestamp: Z.timestamp, timezone: Z.timezone, language: Z.language, extensionId: Z.extensionId, version: Z.version, platform: Z.platform, browser: Z.browser, userAgent: Z.userAgent, isProduction: Z.isProduction ? 1 : 0, ...F }, pt = isDevelopmentMode(); await fetch(pt ? TINYBIRD_LOCAL_ENDPOINT : TINYBIRD_CLOUD_ENDPOINT, { method: "POST", headers: { Authorization: `Bearer ${pt?TINYBIRD_LOCAL_TOKEN:TINYBIRD_CLOUD_TOKEN}`, "Content-Type": "application/json" }, body: JSON.stringify(rt) }) } catch (U) { console.error("Failed to send event to Tinybird:", U) }}Download completion adds the page URL before sending telemetry
Readable download completion path
chunks/sidepanel-B-KAhS5d.jsasync function downloadPreparedData(M) { const F = M.downloadableInfo?.options, U = M.url; F !== void 0 ? (await initiateDownload({ info: F }), tbEvent("download.success", { isMultiPage: M.downloadableInfo?.isMultiPage, maxDepth: M.downloadableInfo?.maxDepth, url: U })) : tbEvent("download.object_missing", { isMultiPage: M.downloadableInfo?.isMultiPage, maxDepth: M.downloadableInfo?.maxDepth, url: U }), M.downloadableInfo && (M.downloadableInfo.isMultiPage ? tbEvent("download.multi_page", { maxDepth: M.downloadableInfo.maxDepth, url: U }) : tbEvent("download.single_page")), M.downloadableInfo?.quotaExceeded ? infoMessage.setMessage("This website is too large to save completely.<br>Download incomplete - some pages could not be saved.", !1, !1) : M.downloadableInfo?.someLinksNotDownloaded && infoMessage.setMessage("Some links were not downloaded because they redirected to other sites.", !1, !1), setButtonToDownload(), markDownloadChipSuccess(), infoMessage.shouldClearOnDownloadComplete() && clearInfoMessage(), clearMultiPagePopupTimer(), setTimeout(async () => { if (await shouldShowRatingPopup()) maybeShowRatingModal(); else { let rt = document.getElementById("ratingContainer"); rt.style.visibility = "visible", tbEvent("rating.shown", { source: "post_download" }) } }, 2e3)}- api.europe-west2.gcp.tinybird.co
Receives Website Downloader telemetry events through Tinybird's hosted analytics events API.