Is SecondSub - Dual Subtitles for Netflix, Disney+, Coupang Play and TVING safe?

High risk

SecondSub is high risk. Source code shows the extension reads your saved translation API key from storage and sends it as `translateApiKey` in a POST to secondsub.quickka.site/api/v1/subtitles/translation. Testing did not reach this flow; no body was captured.

Quickkav1.7.4Chrome Web Store
72Risk
Who publishes it

Quickka - 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
Quickka

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

Publishers can request a review.

Findings

Translation API key sent to extension backend

Source code shows the extension reads your saved translation API key from storage and sends it as `translateApiKey` in a POST to secondsub.quickka.site/api/v1/subtitles/translation.

Testing did not reach this flow; no body was captured.

Severity
High unwanted
Type
Unexpected
CWE
CWE-522
Source
Dynamic sandbox
What actually happens
You did this

You save a translation API key and use AI subtitle translation on a supported streaming site.

The supported content scripts run on Netflix, Disney+, Coupang Play, and TVING pages.

The extension did this

The extension sends the saved key to its own translation relay along with subtitle data.

The shipped code posts the request to secondsub.quickka.site instead of keeping the credential only in your browser.

Fields assembled for the translation relay request
  • Translation API key
    sk-proj-4fb8b21c9a2d4c70 (illustrative)

    The credential you entered for your translation service account. Sending it to the relay lets that server make requests using your key.

  • Translation service
    openai

    This tells the relay which translation provider your key is meant to authorize.

  • Language choices
    sourceLangCode: en, targetLangCode: ko

    This describes which subtitle language is being translated and which target language you selected.

  • Subtitle text
    subtitles: [{ start: 12.4, end: 15.1, text: "Welcome back." }] (illustrative)

    This is the subtitle content being translated for the video you are watching.

Captured request
POSThttps://secondsub.quickka.site/api/v1/subtitles/translation
Headers
Content-Type
application/json
The code that does this

The popup stores the key, then the subtitle utility posts it to the relay

Readable version

Settings popup reads the API key field

assets/popup.html-C6azPtVl.js
function Y() {  const e = document.getElementById("tr-service"),    n = document.getElementById("tr-api-key"),    t = document.getElementById("tr-target-lang");  return {    service: e.value,    apiKey: n.value,    targetLang: t.value  }}

Settings popup stores trSetting and selects the translation source

assets/popup.html-C6azPtVl.js
document.getElementById("tr-set-button").addEventListener("click", () => {  chrome.storage.local.set({    trSetting: Y()  }), L() && chrome.runtime.sendMessage({    type: "TR_SELECT",    data: L()  })})

AI subtitle path reads trSetting.apiKey before translation

assets/util.js-NwVxSbc2.js
$UTIL.applyAISubtitleShowHideSettings = function(t, e) {  t.code !== "none" ? chrome.storage.local.get([e], o => {    chrome.storage.local.get(["trSetting"], i => {      i.trSetting && i.trSetting.service !== "none" && i.trSetting.apiKey !== "" && p($SECONDSUB.ottTypeFromKey(e), o[e], t).then(s => {        I(e, s, t, i.trSetting).then(r => {          n.subtitleAIContents = r, w()        })      })    })  }) : v()}

Relay request serializes the key as translateApiKey

assets/util.js-NwVxSbc2.js
I = async function(t, e, o, i) {  const s = {    streamingService: $SECONDSUB.ottTypeFromKey(t),    movieId: $SECONDSUB.movieIdFromKey(t),    sourceLangCode: o.code,    targetLangCode: i.targetLang,    closedCaption: o.cc,    translateService: i.service,    translateApiKey: i.apiKey,    subtitles: e  };  try {    const r = await fetch(O + "/api/v1/subtitles/translation", {      method: "POST",      body: JSON.stringify(s),      headers: {        "Content-Type": "application/json"      }    });    if (!r.ok) throw new Error("Network response was not ok");    const l = r.body.getReader(),      c = new TextDecoder("utf-8");    let a = "";    for (;;) {      const {        done: P,        value: Y      } = await l.read();      if (P) break;      a += c.decode(Y, {        stream: !0      })    }    const S = JSON.parse(a);    S.code === "CMN-001" ? n.subtitleAIContents = S.data : n.subtitleAIContents = null  } catch (r) {    n.subtitleAIContents = null, console.error("Failed to ai subtitle download:", r)  }  return n.subtitleAIContents}
External destination used for the translation relay
    • secondsub.quickka.site

    Receives the AI subtitle translation POST that includes the saved translation API key, selected service, language choices, and subtitle content.

Updated 30 September 2026bkkdbnjccbhdicmhkmpdjinpgpcnkcnn