Is VEO Automation - Auto VEO & Nano Banana on Google Flow safe?

High risk

VEO Automation is high risk. The extension requests a Google Flow config from configs.kylenguyen.me. The worker caches JSON only with a selectors object; content-script code clicks Flow controls and reads names. Server selectors let a response retarget the automation.

Truong Nguyenv3.4.8.0Chrome Web Store
72Risk
Who publishes it

Truong Nguyen - 4 other listings from the same operator, 1 of them carrying a finding

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

Publisher
Truong Nguyen
Registered address
Tu Hoàng, Nam Từ Liêm, Hà Nội 119000, VN
Registered contact
Truong Nguyen

Same store account

4 other listings published from this account, 186k+ users between them. 1 of them carries a finding.

Shared hosts - 1 hostname

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.

watermark.kylenguyen.me
Also called by 1 other listing: VEO Automation - Auto VEO & Nano Banana on Google Flow

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

Publishers can request a review.

Findings

Remote config controls Google Flow selectors

The extension requests a Google Flow config from configs.kylenguyen.me.

The worker caches JSON only with a selectors object; content-script code clicks Flow controls and reads names.

Server selectors let a response retarget the automation.

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

You start the extension's Google Flow automation or character scan.

The extension did this

The extension asks its service worker for server-provided selector settings before interacting with the page.

Those settings determine which Google Flow controls the automation clicks or reads.

Captured request
GEThttps://configs.kylenguyen.me/config/flow-automation

Observed during dynamic analysis: the response was JSON containing a selectors object, including a selector consumed as selectors.charactersTabButton.

Headers
client credential header
<redacted>
Selector fields that drive page automation
  • Character tab target
    selectors.charactersTabButton

    Controls which Google Flow tab the extension opens before reading available characters.

  • Character name target
    selectors.charactersNameSelector

    Controls which page elements are read to build the list of character names shown to you.

  • Agent-mode controls
    selectors.enableAgentModeButton / selectors.disableAgentModeButton

    Controls which page elements are clicked to enable or disable Flow's agent mode during automation.

  • Media cleanup control
    selectors.removeSelectedImagesButton

    Controls which page element is clicked to remove selected images and videos before generating output.

The code that does this

The fetch, cache, and selector-use path

Readable version

Remote config helper fetches and caches selector JSON

assets/remoteConfig-CbIdrXch.js
function t(t, n) {  return t.version.split(",").map(t => t.trim()).filter(Boolean).includes(n.trim())}let n = null;async function e(t) {  const n = await fetch(`${t}/config/flow-automation`, {    method: "GET",    headers: {      "client credential header": "<redacted>"    }  });  if (!n.ok) throw new Error(`HTTP ${n.status}`);  const e = await n.json();  if (!e?.selectors) throw new Error("Invalid config shape");  return e}async function r() {  if (n) return n;  try {    return n = await e("https://configs.kylenguyen.me"), n  } catch (t) {}  try {    return n = await e("https://extension-config.onegreen.workers.dev"), n  } catch (t) {    return null  }}export {  r as g, t as i};

Service worker returns that config to callers

assets/index.ts-DoSGWp_j.js
case "GET_REMOTE_CONFIG":  return e().then(e => m(e)).catch(() => m(null)), !0;

Prompt queue loads remote config before processing automation work

assets/index.ts-CjccIiMW.js
async function oe(e) {  const t = await new Promise(e => {    chrome.runtime.sendMessage({      type: "GET_REMOTE_CONFIG"    }, t => e(t ?? null))  });  if (!t) return e.status = "error", re(e), Z.shift(), e.sendResponse({    success: !1,    error: "Cannot connect to server. Extension may be unauthorized.",    results: []  }), te = null, void ne(1);  for (;;) {    if (e.isCancelling) {      e.status = "cancelled";      const t = e.results;      return Z.shift(), re(e), e.sendResponse({        success: !1,        cancelled: !0,        results: t      }), te = null, void ne(1)    }    if (e.pendingIndexes.length > 0) {      const n = [];      for (let r = 0; r < 1; r++) n.push(X(e, t, ee, re).catch(e => {}));      await Promise.all(n)    }    for (; ee.some(t => t.id === e.id);) await K(200);    if (0 === e.pendingIndexes.length) {      e.status = "completed";      const t = e.results.every(e => e.success),        n = e.results;      return Z.shift(), re(e), e.sendResponse({        success: t,        results: n      }), te = null, void ne(1)    }  }}

Character scan consumes selector fields from the returned config

assets/index.ts-CjccIiMW.js
case "SCAN_CHARACTERS":  return async function() {    const e = await new Promise(e => {      chrome.runtime.sendMessage({        type: "GET_REMOTE_CONFIG"      }, t => e(t ?? null))    });    if (!e) return [];    if (i(e.selectors.charactersTabButton).length > 0) {      await w(e.selectors.charactersTabButton, "Click characters tab"), await v(e.selectors.charactersNameSelector);      return i(e.selectors.charactersNameSelector).map((e, t) => i(t).attr("alt") || i(t).text() || "").get()    }    return []  }().then(e => n({    characters: e  })), !0;
Remote hosts involved in selector delivery
    • configs.kylenguyen.me

    Primary flow-automation config host in shipped code; dynamic analysis observed the extension requesting selector JSON from this host.

    • extension-config.onegreen.workers.dev

    Fallback flow-automation config host in shipped code if the primary config request fails.

Updated 30 September 2026fnmijgmnjpealnnadjpjilaanhhambeb