Is DAMI - Công cụ kết nối & quản lý KOL TikTok toàn diện safe?
DAMI fetches unsigned JavaScript from its own CDN and injects it into the seller's authenticated TikTok Shop tab.
When its workbench UI dispatches an internal event, DAMI's background service worker pulls a fixed list of script files from cos-res.tikclubs.com over plain fetch(), with no integrity or signature check, and runs the combined text as an inline script in the main page world of the active TikTok Shop / Affiliate / Tokopedia seller tab. This gives that remote code the same access as the page itself, including the seller's TikTok session, cookies, and page content, and the extension ships local copies of the same-named files that are never actually used, so the code shown in the Chrome Web Store listing is not what runs.
Who publishes itNo other listings under this identity, 5 shared hostnames
No other listings under this identity, 5 shared hostnames
What this publisher told the store about itself, and the other listings that told it the same thing.
Shared hosts - 5 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
DAMI injects live CDN code into TikTok Shop tabs, unreviewed
Code analysis shows the extension fetches nine JS files live from cos-res.tikclubs.com on each DAMI task and runs the joined code in your TikTok Shop tab with full page privileges, bypassing the bundled, reviewed copies.
You start a DAMI automation task, such as Invite Creators, while a TikTok Shop or Affiliate tab is open.
The action fires inside the DAMI workbench UI (tabs.html or app.dami.vn).
The extension fetches nine JavaScript files fresh from cos-res.tikclubs.com and runs the joined code in your TikTok Shop tab with full page privileges.
The fetch has no hash or signature check, and the code runs in the page's MAIN world, not the extension's isolated content-script world.
background.js: fetching and running the CDN scripts
else if (r.type === "bg-execute-script") {
const { tab: w } = l;
et.tabs.sendMessage(s.id, { type: "tabs-get-common-info", timestamp: Date.now() }).then(v => {
let x = { ...v, ...r.data };
x.envMode = "production";
const V = "https://cos-res.tikclubs.com/dami/scripts/v2-2.0.0/prod";
x.scriptUrls = [
`${V}/CSharpCode.js`, `${V}/GlobalData.js`, `${V}/Rpa.js`, `${V}/RpaChat.js`,
`${V}/damiAdminApi.js`, `${V}/damiTikTokApi.js`, `${V}/content.js`,
`${V}/protobuf.js`, `${V}/dami_lang_en.js`
];
// ... j0(x, l.tab) is called a few lines below
async function j0(r, l) {
if (!r.scriptUrls) return;
r.envMode = "production";
// Append a cache-busting query to each of the 9 hardcoded CDN URLs
const o = r.scriptUrls.map(s => s + `?timest=${Date.now()}`);
// Fetch all 9 files with plain fetch() -- no hash / signature check
Promise.all(o.map(s => fetch(s).then(f => {
if (!f.ok) throw new Error(`Failed to load script: ${s} (Status: ${f.status})`);
return f.text();
}).catch(f => (console.error(f), "")))).then(async s => {
const f = s.join("\n"); // join all 9 fetched scripts into one string
let g = await U0(...); // resolve the active TikTok Shop / Affiliate tab
if (g) {
await tg(g); // focus that tab
// Run the joined, freshly-fetched code in the PAGE'S own MAIN world
const [{ result: m }] = await et.scripting.executeScript({
args: [f, r],
target: { tabId: g.id },
world: "MAIN",
func: Yx
});
}
});
}
// Yx runs INSIDE the page (chrome.scripting world:'MAIN'), so `document`
// here is the TikTok Shop tab's own document, not an extension page.
function Yx(r, l, o = []) {
l = JSON.stringify(l);
return new Promise((y, w) => {
const x = document.createElement("script");
x.classList.add("dm-custom-js");
// r is the joined text of all 9 files just fetched from the CDN --
// it is interpolated verbatim into the injected <script>'s source.
x.textContent = `(() => {
window.automaFetch = automaFetch
window.automaUpload = automaUpload
let scriptParams = ${l}
${r} // <-- the fetched CDN code, executed as page script
})()`;
document.head.appendChild(x); // runs with the page's own privileges
});
}
| Field | Value | Why it matters | |
|---|---|---|---|
CSharpCode.js | https://cos-res.tikclubs.com/dami/scripts/v2-2.0.0/prod/CSharpCode.js | RPA automation engine that drives Invite Creators / Sync Video Data tasks in the page. | |
GlobalData.js | https://cos-res.tikclubs.com/dami/scripts/v2-2.0.0/prod/GlobalData.js | Global config and API endpoint data used by the automation scripts. | |
Rpa.js / RpaChat.js | https://cos-res.tikclubs.com/dami/scripts/v2-2.0.0/prod/Rpa.js | TikTok Shop / Affiliate API client and chat automation used by the injected code. | |
damiAdminApi.js / damiTikTokApi.js | https://cos-res.tikclubs.com/dami/scripts/v2-2.0.0/prod/damiTikTokApi.js | Admin/session and TikTok Shop API calls made from the injected page code. | |
content.js / protobuf.js / lang_en | https://cos-res.tikclubs.com/dami/scripts/v2-2.0.0/prod/protobuf.js | Re-injected content logic, protobuf codec, and English UI strings for the overlay. |
- cos-res.tikclubs.com
tikclubs.com/DAMI-owned CDN. Serves the 9 unpinned JS files that run in the seller's TikTok Shop tab; not operated by TikTok.
Fetches the 9 JS files DAMI's background worker loads on every task and prints a SHA-256 hash of each, so you can tell if the live CDN payload changes from what was analyzed.
// dami-cdn-audit.js
// Fetches the 9 JS files that DAMI's background service worker loads on
// every automation task from cos-res.tikclubs.com, and prints a SHA-256
// hash of each so you can tell whether the live payload has changed
// since this claim was written.
const BASE = "https://cos-res.tikclubs.com/dami/scripts/v2-2.0.0/prod";
const FILES = [
"CSharpCode.js", "GlobalData.js", "Rpa.js", "RpaChat.js",
"damiAdminApi.js", "damiTikTokApi.js", "content.js",
"protobuf.js", "dami_lang_en.js",
];
async function sha256(text) {
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(text));
return Buffer.from(digest).toString("hex");
}
async function main() {
for (const name of FILES) {
const url = `${BASE}/${name}?timest=${Date.now()}`;
const res = await fetch(url);
const body = await res.text();
console.log(`${name}\t${body.length} bytes\tsha256:${await sha256(body)}`);
}
}
main();
- 1Install Node 18+.
- 2Run node dami-cdn-audit.js.
- 3Compare each SHA-256 against a later run or the CRX's bundled dami-scripts/ copy.
The scripts fetched at analysis time matched the vendor's bundled dami-scripts/ copies; no unexpected payload was observed live. The finding is the mechanism: an unpinned, unreviewable live-code load into an authenticated session.
Static analysis finding. This behaviour was identified by reading the shipped extension code and has not yet been reproduced in a live run. The trigger conditions and the exact data sent are read from the code, not from an observed capture.
Where it sends data
Destinations our analysis observed DAMI - Công cụ kết nối & quản lý KOL TikTok toàn diện contacting. Sending data somewhere is not a finding on its own - an extension that syncs your settings has to talk to its own server - but it is where your data can go, and who else it goes to.
- cos-res.tikclubs.com
DAMI - Công cụ kết nối & quản lý KOL TikTok toàn diện sends data to cos-res.tikclubs.com. No other extension we have analysed sends data here.