Is Vidyard - Screen Recorder & Screen Capture safe?
Vidyard is medium risk. Code shows Vidyard's recording panel posts metrics to extension-backend.vidyard.com/gv_metrics: a metric name, value, connection type, version, and caller tags. Sign-in requirement blocked live capture; no body included.…
Who publishes itBuildscale, Inc - no other listings under this identity, 2 shared hostnames
Buildscale, Inc - no other listings under this identity, 2 shared hostnames
What this publisher told the store about itself, and the other listings that told it the same thing.
Shared hosts - 2 hostnames
Hostnames hardcoded in this extension that few other listings call. That can mean one operator behind both, and it can equally mean a small shared vendor, so it is context rather than a conclusion. Hosts that many listings call are left out: they are services, not connections.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Vidyard posts recording metrics to its telemetry backend
Code shows Vidyard's recording panel posts metrics to extension-backend.vidyard.com/gv_metrics: a metric name, value, connection type, version, and caller tags.
Sign-in requirement blocked live capture; no body included.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-200
- Source
- Dynamic sandbox
You use Vidyard's recording panel or a recording-related workflow.
The extension measures performance and sends the metric name, value, and tags to Vidyard's metrics backend.
- Metric namerecording_panel_time_to_load
Shows which part of the recording workflow was measured.
- Measured value842.5
Records the timing or count for that recording workflow measurement.
- Network type4g
Adds your browser-reported connection type to the telemetry tags.
- Extension version4.3.9
Tells the metrics backend which extension build produced the measurement.
No response was captured because sign-in prevented the dynamic session from entering the recording workflow.
Recording metrics are measured and posted
Recording panel starts the load metric
overlayPopup.min.jsfunction jp() { (0, t.useEffect)((() => { (async () => { await Np.A.worker("startPerformanceMetrics", { measureName: Wi.A.Analytics.Metrics.RECORDING_PANEL_TIME_TO_LOAD }), await Zf.A.dispatch("resetUIVisibility") })() }), []); const { cameraDeviceName: e, micDeviceName: n, microphoneEnabled: r, source: i, isProcessing: a, isRecording: o } = qi(Zi.A, (e => ({ cameraDeviceName: e.cameraDeviceName, micDeviceName: e.micDeviceName, microphoneEnabled: e.microphoneEnabled, source: e.source, isProcessing: e.isProcessing, isRecording: e.isRecording })));}Metrics helper posts metric, value, and tags
overlayPopup.min.jsasync function s(e, t = 1, n = {}) { var i; n.connectionType = (null === (i = navigator) || void 0 === i || null === (i = i.connection) || void 0 === i ? void 0 : i.effectiveType) || "unknown", n.version = "4.3.9"; try { await r.A.sendRequest({ baseUrl: "https://extension-backend.vidyard.com/gv_metrics", method: "POST", params: { metric: e, value: t, tags: n } }) } catch (r) { if (o(e, r)) return; a.A.error("Could not log metric to Datadog", r, { ...null == r ? void 0 : r.data, metric: e, value: t, tags: n }) }}- extension-backend.vidyard.com
Vidyard endpoint receiving recording performance metrics; the error log string names Datadog as the metrics destination.
Vidyard sends identified usage events to Heap Analytics
Code shows Vidyard posts usage events to Heap Analytics with a Heap app ID, user ID, event name, timestamp, user agent, and version.
Sign-in blocked live capture; the body below reflects source code, not a capture.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-359
- Source
- Dynamic sandbox
You open Vidyard or use one of its recording-related controls.
The extension prepares a usage event that is tied to the current Vidyard user ID and sends it to Heap Analytics.
- Analytics app4242522408
Identifies the Heap project that receives the event.
- Your Vidyard user ID12345678
Ties the usage event back to a signed-in Vidyard account in the extension state.
- Event nameOpened Extension
Shows what extension action was recorded.
- Event time2026-07-12T20:31:48.376Z
Records when the extension action happened.
- Browser and extensionChrome/126.0.0.0, Vidyard 4.3.9
Adds your browser user agent and the Vidyard extension version to the event.
No response was captured because the login gate prevented the dynamic session from triggering this request.
The source path that builds and sends Heap events
Popup open event calls the worker handler
popup.min.js(0, t.useEffect)((() => { let e = null; const t = async t => { const { action: n } = t; n === Sm.A.Popup.CLOSE_POPUP && await (0, rk.dE)(e) && window.close() }; return (0, Em.d$)(t, Sm.A.Popup), (async () => { try { e = await (0, rk.Oo)(), await (0, Sy.A)(), await (0, Cy.vs)(), await Wr.A.commit("clearVideoPreviewer"), await lk.A.worker("handleOnExtensionOpened"), p(await (0, Oy.$I)({ namespace: "auth", storageArea: "local" })), await em.A.dispatch("checkVideoRecovery"), await s.A.dispatch("validateAccessTokenNotExpired"), Mu.A.state.isTestVideo || await hr.A.dispatch("updatePanelForAIAvatarsPromo") } catch (e) { Hh.A.error("PopupContainer init failed", e) } finally { d(!1) } })(), () => { (0, Em.E2)(t) }}), []);Heap helper adds identity and event properties
service-worker.min.jsconst u = { ADD_USER_PROPERTIES: "addUserProperties", TRACK: "track" }, l = async (e, ...t) => { if (!(0, a.SR)() && !(0, a.hp)()) return void await i.A.worker("sendHeap", { method: e, args: t }); if (await r.A.waitForLoaded(), !r.A.state.userId) return; let n, l; if (e === u.TRACK) { n = "track"; const e = t?.[1] || {}; e.manifestVersion = 3, e.extensionVersion = "4.3.9", e.browser = navigator.userAgent, l = { timestamp: (new Date).toISOString(), event: t[0], properties: e } } else e === u.ADD_USER_PROPERTIES && (n = "add_user_properties", l = { properties: t[0] }); o.A.debug({ src: "Heap", message: e, data: t }); try { await s.A.sendRequest({ baseUrl: `https://heapanalytics.com/api/${n}`, method: "POST", params: { app_id: "4242522408", identity: r.A.state.userId, ...l } }) } catch (e) { if (((e, t) => { if ("Failed to fetch" === e?.message) return o.A.error({ src: "Heap", message: e.message, data: t }), !0 })(e, t[0])) return; c.rollbar.error("Failed to send Heap request", e, { ...e?.data, requestParams: l }) } };- heapanalytics.com
Heap Analytics endpoint receiving Vidyard extension usage events with app ID and user identity.
Hover recorder injects into all HTTPS pages when enabled
When the hover recorder flag is present and state says it should show, Vidyard registers hoverRecorder.min.js/css for https://*/*, and queries tabs to inject the same script/CSS into matches, giving the overlay page-level access.
- Severity
- Medium unwanted
- Type
- Unexpected
- CWE
- CWE-200
- Source
- Dynamic sandbox
You enable or use Vidyard's hover recorder feature.
The extension registers and injects its hover recorder script across HTTPS pages while the feature is active.
- Matched pagehttps://app.example.com/dashboard
The recorder is not limited to a single named website; any HTTPS page can match while the feature is active.
- Page structureDashboard heading, Save button, Search input label
The injected script can read headings, buttons, labels, and other visible page elements needed by the overlay.
- Recorder assetshoverRecorder.min.js and hoverRecorder.min.css
Shows which script and stylesheet are inserted into matching tabs.
Hover recorder content script registration and injection
Feature-gated registration and tab injection
service-worker.min.jsasync function l() { if (o.Ay.syncDispatch("hasFeature", { name: o.Gv.HOVER_RECORDER_FEATURE }) && s.A.state.showHoverRecorder) { await chrome.scripting.registerContentScripts([{ id: "hover-script", js: ["hoverRecorder.min.js"], css: ["hoverRecorder.min.css"], matches: ["https://*/*"] }]); try { (await chrome.tabs.query({})).forEach((async e => { await (0, i.dE)(e.id) && (await chrome.scripting.insertCSS({ target: { tabId: e.id }, files: ["hoverRecorder.min.css"] }), await chrome.scripting.executeScript({ target: { tabId: e.id }, files: ["hoverRecorder.min.js"] })) })), (0, r.OB)("Viewed - Hover Recorder") } catch (e) { a.A.error("Mounting hover recorder failed", e) } }}Manifest grants scripting and broad host permissions
manifest.json"permissions": ["storage", "tabs", "webNavigation", "scripting", "notifications", "activeTab", "offscreen", "system.display", "alarms","tabGroups"],"host_permissions": ["<all_urls>"]What it can do
Permissions this extension asks for, as declared in version 5.1.5. 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
<all_urls>
Store data in your browser
storage
See the address and title of every tab you have open
tabs
See every page you navigate to, as you navigate to it
webNavigation
Run its own code inside the pages you visit
scripting
Show you desktop notifications
notifications
Act on the current tab, but only after you click the extension
activeTab
Run hidden pages in the background
offscreen
Read information about your displays
system.display
Schedule its own background tasks
alarms
Read and change your tab groups
tabGroups