Is Vidyard - Screen Recorder & Screen Capture safe?

Medium risk

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.…

Vidyardv5.1.2Chrome Web Store
45Risk
Who publishes it

Buildscale, Inc - no other listings under this identity

What this publisher told the store about itself, and the other listings that told it the same thing.

Publisher
Vidyard
Declared legal entity
Buildscale, Inc
Registered address
301-1 Queen St N, Kitchener, ON N2H 2G7, CA
Registered contact
Buildscale, Inc

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-200
SourceAI SANDBOX

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.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You use Vidyard's recording panel or a recording-related workflow.

The extension did this

The extension measures performance and sends the metric name, value, and tags to Vidyard's metrics backend.

02EvidenceFIELD TABLE
Fields built for the metrics request
FieldValueWhy it matters
Metric name
recording_panel_time_to_loadShows which part of the recording workflow was measured.
Measured value
842.5Records the timing or count for that recording workflow measurement.
Network type
4gAdds your browser-reported connection type to the telemetry tags.
Extension version
4.3.9Tells the metrics backend which extension build produced the measurement.
03EvidenceNETWORK CAPTURE
Captured request
POSThttps://extension-backend.vidyard.com/gv_metrics
No response was captured because sign-in prevented the dynamic session from entering the recording workflow.
04EvidenceCODE COMPARE
The code that does this

Recording metrics are measured and posted

What it actually does
Recording panel starts the load metricoverlayPopup.min.js
function 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 tagsoverlayPopup.min.js
async 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
    })
  }
}
05EvidenceTHIRD PARTY LIST
Telemetry destination
  • extension-backend.vidyard.com

    Vidyard endpoint receiving recording performance metrics; the error log string names Datadog as the metrics destination.

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-359
SourceAI SANDBOX

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.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You open Vidyard or use one of its recording-related controls.

The extension did this

The extension prepares a usage event that is tied to the current Vidyard user ID and sends it to Heap Analytics.

02EvidenceFIELD TABLE
Fields built for the Heap request
FieldValueWhy it matters
Analytics app
4242522408Identifies the Heap project that receives the event.
Your Vidyard user ID
12345678Ties the usage event back to a signed-in Vidyard account in the extension state.
Event name
Opened ExtensionShows what extension action was recorded.
Event time
2026-07-12T20:31:48.376ZRecords when the extension action happened.
Browser and extension
Chrome/126.0.0.0, Vidyard 4.3.9Adds your browser user agent and the Vidyard extension version to the event.
03EvidenceNETWORK CAPTURE
Captured request
POSThttps://heapanalytics.com/api/track
No response was captured because the login gate prevented the dynamic session from triggering this request.
04EvidenceCODE COMPARE
The code that does this

The source path that builds and sends Heap events

What it actually does
Popup open event calls the worker handlerpopup.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 propertiesservice-worker.min.js
const 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
      })
    }
  };
05EvidenceTHIRD PARTY LIST
Destination receiving the usage event
  • heapanalytics.com

    Heap Analytics endpoint receiving Vidyard extension usage events with app ID and user identity.

SeverityMEDIUM
ClassUNWANTED
TypeUnexpected
CWECWE-200
SourceAI SANDBOX

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.

01EvidenceCAUSE EFFECT
What actually happens
You did this

You enable or use Vidyard's hover recorder feature.

The extension did this

The extension registers and injects its hover recorder script across HTTPS pages while the feature is active.

02EvidenceFIELD TABLE
What the injected recorder can observe on a page
FieldValueWhy it matters
Matched page
https://app.example.com/dashboardThe recorder is not limited to a single named website; any HTTPS page can match while the feature is active.
Page structure
Dashboard heading, Save button, Search input labelThe injected script can read headings, buttons, labels, and other visible page elements needed by the overlay.
Recorder assets
hoverRecorder.min.js and hoverRecorder.min.cssShows which script and stylesheet are inserted into matching tabs.
03EvidenceCODE COMPARE
The code that does this

Hover recorder content script registration and injection

What it actually does
Feature-gated registration and tab injectionservice-worker.min.js
async 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 permissionsmanifest.json
"permissions": ["storage", "tabs", "webNavigation", "scripting", "notifications", "activeTab", "offscreen", "system.display", "alarms","tabGroups"],
"host_permissions": ["<all_urls>"]
Updated 30 September 2026jiihcciniecimeajcniapbngjjbonjan