Is Youtube Transcript safe?
YouTube Transcript is low risk. Before showing a transcript, the extension posts the YouTube video ID and a stored request counter to yt-to-text.com to check your usage allowance. This fires on every request; if signed out, the account-token field is sent empty.
AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.
Publishers can request a review.
Findings
Video ID and usage count sent to yt-to-text.com without signing in
Before showing a transcript, the extension posts the YouTube video ID and a stored request counter to yt-to-text.com to check your usage allowance.
This fires on every request; if signed out, the account-token field is sent empty.
- Severity
- Low unwanted
- Type
- Unexpected
- CWE
- CWE-200
- Source
- Dynamic sandbox
You click 'Get Subtitles' on a YouTube video, whether or not you're signed in.
The button sits inside the extension's transcription panel on youtube.com.
The extension posts the video's ID and a local usage counter to yt-to-text.com before showing you anything.
This happens on every subtitle request, including while signed out, the account-token field is just sent empty.
Observed during dynamic analysis on a signed-out session: yt-to-text.com replied 200 with {"code":"FREE_LIMIT_NOT_REACHED"}, which the extension uses to decide whether to display the transcript.
- x-source
- jgibaoklabopileepldnlkbbcibhbgmd
- Content-Type
- application/json
- x-app-version
- 2.3
{ "token": "", "usage_count": 0, "video_id": "48jlHaxZnig"}- YouTube video ID48jlHaxZnig
Tells the backend which specific video you're checking, even before you've signed in to anything.
- Local usage count0
Reports how many free subtitle checks the extension has already logged on this device.
- Account token"" (empty — sent even though no account is signed in)
Would identify your signed-in session if you had one; sent as an empty value when you don't.
Usage-check function that posts the video ID and counter
async function vp(e, t) { var n, o, r, a, i, s, l; const c = Jd(), u = sd(), d = await c.getUserUsage(); try { if (c.checkVideoUsage(e)) return { code: "ALLOW" }; if (c.checkSubscriptionCache()) return c.userUsage.subtitlesCounter++, c.setVideoUsage(e), c.shouldShowReview("subtitles") && (t.value = !0), { code: "ALLOW" }; const o = d.value.subtitlesCounter, r = await u.getRefreshedToken(), a = await async function(e, t, n) { return await Pu.post(Ku + "/v3/Usage", { token: e, usage_count: t, video_id: n }, { headers: { "Content-Type": "application/json", "x-app-version": Yu, "x-source": Ju } }) }(r || "", o, e); return (null == (n = null == a ? void 0 : a.data) ? void 0 : n.code) && "FREE_LIMIT_NOT_REACHED" === a.data.code ? (c.userUsage.subtitlesCounter++, c.setVideoUsage(e), c.shouldShowReview("subtitles") && (t.value = !0), { code: "ALLOW" }) : (c.setAllowUsageBySubscription(), { code: "ALLOW" }) } catch (Bp) { if (null == (r = null == (o = null == Bp ? void 0 : Bp.response) ? void 0 : o.data) ? void 0 : r.code) switch (null == (i = null == (a = Bp.response) ? void 0 : a.data) ? void 0 : i.code) { case "FREE_LIMIT_REACHED": return u.accessToken ? { code: "SHOW_PAYWALL", plans: null == (l = null == (s = Bp.response) ? void 0 : s.data) ? void 0 : l.plans } : { code: "SHOW_LOGIN" }; case "INVALID_TOKEN": await u.logout("content-script"); break; default: console.error(Bp) } return { code: "ALLOW" } }}- yt-to-text.com
Receives the YouTube video ID and local usage counter on every subtitle check, and returns the free-limit status that gates whether the transcript is shown.