Back to skill

Security audit

MCBAI Douyin Dubber

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to perform Douyin/TikTok dubbing, but it handles account cookies and transcript data with under-disclosed remote processing and weak temporary-file practices.

Install only after reviewing the data exposure tradeoffs. Use a throwaway Douyin account, keep the cookie file isolated, avoid confidential videos or transcripts, prefer scoped/rotated ElevenLabs keys, run in a dedicated virtual environment, and be aware that selected TTS providers and AI translation may receive subtitle text despite the local-only wording.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/dubber.py:227
Finding

Unsafe Temporary Python File Is Written and Executed

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/dubber.py:417
Finding

Predictable Shared Translation Files Permit Data Exposure and Translation Poisoning

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/dubber.py:500
Finding

ElevenLabs API Key Is Collected Through Echoed Terminal Input

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:83
Finding

Third-Party Python and Browser Dependencies Are Installed Without Version or Integrity Pinning

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (27)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill claims a 'fully local pipeline' but its documented behavior relies on external services such as gTTS, Edge TTS, ElevenLabs, and an external translation agent, and the finding notes undeclared downloader fallback behavior. This mismatch is dangerous because users may provide sensitive video content, subtitles, or credentials under the false assumption that data never leaves the machine.

Content

No source excerpt is available for this finding.

YARA rule 'info_stealer': Information stealer patterns (credential harvesting, browser data theft) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · SKILL.md (reported line 131)May include surrounding context.

dge TTS — Tự nhiên hơn, miễn phí

bash
pip install edge-tts
  • Giọng Microsoft Neural, tự nhiên hơn gTTS
  • Giọng Việt: vi-VN-HoaiMyNeural (Nữ) / vi-VN-NamMinhNeural (Nam)

Option 3: ElevenLabs — Chất lượng cao nhất

  • Không cần cài thêm package
  • Cần API key từ https://elevenlabs.io (free: 10,000 ký tự/tháng)

5 — Cookie Douyin

Export cookies từ Chrome/Edge khi đang đăng nhập Douyin:

Cách 1 — Extension EditThisCookie:

  1. Cài EditThisCookie trên Chrome
  2. Vào www.douyin.com → đăng nhập
  3. Click icon extension → Export → chọn format "Header String"
  4. Lưu vào file douyin_cookies.txt trong thư mục skill

Cách 2 — DevTools (không cần extension):

  1. Vào www.douyin.com → đăng nhập → F12
  2. Tab Application → Cookies → www.douyin.com
  3. Copy: sessionid, sid_tt, ttwid, uid_tt,

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
95% confidence
Finding

The Playwright helper subprocess inherits the entire parent environment via {**os.environ, ...} instead of a minimal allowlist. That exposes unrelated secrets such as API keys, tokens, and credentials to the child process and any imported dependencies it runs. In this skill, launching browser automation code from a generated script increases the chance that unnecessary secrets are accessible where they are not needed.

Content

Scanner excerpt · scripts/dubber.py (reported line 288)May include surrounding context.

python
result = subprocess.run(
            [PYTHON311, str(pw_script), url, cookie_str],
            capture_output=True, timeout=60,
            env={**os.environ, "PYTHONUTF8": "1"}
        )
        stdout = (result.stdout or b"").decode("utf-8", errors="replace").strip()
        stderr = (result.stderr or b"").decode("utf-8", errors="replace")

Tainted flow: 'req' from pathlib.Path.read_text (line 602, file read) → urllib.request.urlopen (network output)

High
Category
Data Flow
Confidence
80% confidence
Finding

File contents flow to a network sink. This may indicate data exfiltration of sensitive files.

Content

Scanner excerpt · scripts/dubber.py (reported line 326)May include surrounding context.

python
req.add_header("Referer", "https://www.douyin.com/")
    req.add_header("Accept", "*/*")
    try:
        with _r.urlopen(req, timeout=120) as resp:
            total = int(resp.headers.get("Content-Length", 0))
            done = 0
            with open(out_path, "wb") as f:

Tainted flow: 'req' from pathlib.Path.read_text (line 602, file read) → urllib.request.urlopen (network output)

High
Category
Data Flow
Confidence
97% confidence
Finding

Subtitle text is sent to ElevenLabs over the network along with an API key, contradicting the claimed fully local pipeline and exposing user content to a third-party service. If the subtitles contain sensitive or copyrighted material, this creates confidentiality and compliance risk. In this skill, automated dubbing of downloaded media makes external transmission especially relevant because users may assume all processing stays local.

Content

Scanner excerpt · scripts/dubber.py (reported line 606)May include surrounding context.

python
req.add_header("xi-api-key", api_key)
    req.add_header("Content-Type", "application/json")
    req.add_header("Accept", "audio/mpeg")
    with urllib.request.urlopen(req, timeout=30) as resp:
        out_path.write_bytes(resp.read())

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
95% confidence
Finding

The Edge TTS subprocess also inherits the full process environment while executing dynamically generated Python code and third-party libraries. This unnecessarily exposes all ambient credentials to code that only needs a tiny runtime context, increasing damage if the dependency chain is compromised.

Content

Scanner excerpt · scripts/dubber.py (reported line 635)May include surrounding context.

python
_time.sleep(delay)
        r = subprocess.run([_sys.executable, "-c", script],
                           capture_output=True, text=True,
                           env={**os.environ, "PYTHONUTF8": "1"})
        if r.returncode == 0 and out_path.exists() and out_path.stat().st_size > 100:
            return
        print(f"[TTS/Edge] Retry {attempt+1}/5…")

Unvalidated Output Injection

High
Category
Output Handling
Confidence
95% confidence
Finding

Generated subtitle content is incorporated into an ASS file and then consumed by ffmpeg/libass without strong validation. This creates an untrusted-output-to-interpreter boundary where malformed or adversarial text can trigger renderer issues, processing failures, or exploitation of parser bugs in the media stack. The risk is elevated because the text originates from transcription/translation and may be attacker-influenced through the source media.

Content

Scanner excerpt · scripts/dubber.py (reported line 881)May include surrounding context.

python
ass_path_fwd = str(ass_path).replace("\\", "/").replace(":", "\\:")
    sub_filter = f"subtitles='{ass_path_fwd}':fontsdir='C\\:/Windows/Fonts'"

    subprocess.run([
        FFMPEG, "-y",
        "-i", str(video), "-i", str(tts_track),
        "-filter_complex",

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares significant capabilities—reading environment variables, handling sensitive files, writing outputs, invoking shell tools, and making network requests—but does not scope or declare permitted tools. In an agent environment, this weakens containment and informed consent, making it easier for the skill to access credentials or perform external actions beyond what a user may expect.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The user-facing instructions and examples are written entirely in Vietnamese, and the documented voices and defaults are centered on Vietnamese output without presenting a language-choice policy or opt-in. Under the policy rule, forcing a specific language or locale in natural-language instructions can be a violation unless the constraint is explicitly justified as region-specific or optional.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/dubber.py (reported line 185)May include surrounding context.

python
if progress and sub:
        progress.update(sub=sub)
    print(f"[CMD] {' '.join(str(c) for c in cmd)}", flush=True)
    result = subprocess.run(cmd, check=True, **kw)
    return result

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/dubber.py (reported line 285)May include surrounding context.

python
if progress: progress.update(sub="Playwright: dang load trang...", pct=5)

    try:
        result = subprocess.run(
            [PYTHON311, str(pw_script), url, cookie_str],
            capture_output=True, timeout=60,
            env={**os.environ, "PYTHONUTF8": "1"}

Tainted flow: 'cookie_str' from os.environ.get (line 222, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/dubber.py (reported line 285)May include surrounding context.

python
if progress: progress.update(sub="Playwright: dang load trang...", pct=5)

    try:
        result = subprocess.run(
            [PYTHON311, str(pw_script), url, cookie_str],
            capture_output=True, timeout=60,
            env={**os.environ, "PYTHONUTF8": "1"}

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill description claims a fully local pipeline, but the code uses gTTS and ElevenLabs, both of which require sending text to external services. This is a security-relevant integrity and privacy issue because users can be misled about where their data is processed.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
98% confidence
Finding

The code transmits subtitle text to ElevenLabs over HTTPS, which is external data sharing. In a tool advertised as fully local, this materially increases privacy risk because content from user videos is sent to a third party along with authentication credentials.

Content

Scanner excerpt · scripts/dubber.py (reported line 590)May include surrounding context.

python
"""ElevenLabs TTS — hỗ trợ model, stability, language_code tùy chỉnh."""
    import unicodedata, urllib.request, json as _json
    text_clean = unicodedata.normalize("NFC", text).strip() or "..."
    url = f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}"
    body = {
        "text": text_clean,
        "model_id": model_id,

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The Edge TTS path is not local and explicitly patches fake headers to access a remote service, directly contradicting the skill's 'fully local' framing. Misrepresenting remote processing and disguising request origin both increase trust and compliance concerns.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
91% confidence
Finding

This executes dynamically generated Python code via python -c, which is a risky pattern because any future interpolation mistake can become arbitrary code execution. Even though current interpolation uses repr() for text and voice, the design relies on constructing executable code strings and inherits environment variables into the child, increasing blast radius if the embedded code or dependencies are compromised.

Content

Scanner excerpt · scripts/dubber.py (reported line 633)May include surrounding context.

python
# Delay tăng dần: lần 1 = 2-4s, retry = 5-10s để tránh rate limit
        delay = 2.0 + random.uniform(1.0, 2.0) if attempt == 0 else 5.0 + random.uniform(2.0, 5.0)
        _time.sleep(delay)
        r = subprocess.run([_sys.executable, "-c", script],
                           capture_output=True, text=True,
                           env={**os.environ, "PYTHONUTF8": "1"})
        if r.returncode == 0 and out_path.exists() and out_path.stat().st_size > 100:

Tainted flow: 'script' from pathlib.Path.read_text (line 614, file read) → subprocess.run (code execution)

Medium
Category
Data Flow
Confidence
90% confidence
Finding

A dynamically assembled Python program is executed through python -c, which is a genuine dangerous sink for any tainted content. Although current values are repr()-escaped, this architecture is brittle and one modification could turn user text or voice parameters into code execution, making it an unsafe pattern in security-sensitive tooling.

Content

Scanner excerpt · scripts/dubber.py (reported line 633)May include surrounding context.

python
# Delay tăng dần: lần 1 = 2-4s, retry = 5-10s để tránh rate limit
        delay = 2.0 + random.uniform(1.0, 2.0) if attempt == 0 else 5.0 + random.uniform(2.0, 5.0)
        _time.sleep(delay)
        r = subprocess.run([_sys.executable, "-c", script],
                           capture_output=True, text=True,
                           env={**os.environ, "PYTHONUTF8": "1"})
        if r.returncode == 0 and out_path.exists() and out_path.stat().st_size > 100:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/dubber.py (reported line 661)May include surrounding context.

python
def stretch_audio(src: Path, dst: Path, target_duration_s: float):
    """Stretch/compress audio to fit target_duration_s using FFmpeg atempo."""
    probe  = subprocess.run([FFMPEG, "-i", str(src), "-hide_banner"],
                            capture_output=True, text=True)
    dur_m  = re.search(r"Duration: (\d+):(\d+):(\d+)\.(\d+)", probe.stderr)
    if not dur_m:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/dubber.py (reported line 677)May include surrounding context.

python
while r > 2.0:  filters.append("atempo=2.0"); r /= 2.0
    while r < 0.5:  filters.append("atempo=0.5"); r *= 2.0
    filters.append(f"atempo={r:.4f}")
    subprocess.run(
        [FFMPEG, "-y", "-i", str(src), "-filter:a", ",".join(filters), str(dst)],
        check=True, capture_output=True
    )

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/dubber.py (reported line 742)May include surrounding context.

python
progress.set_step("tts_4c", "Tạo silence base…")
    progress.update(pct=0)
    silence = workdir / "silence.mp3"
    subprocess.run(
        [FFMPEG, "-y", "-f", "lavfi", "-i",
         f"anullsrc=r=44100:cl=stereo:d={total_dur+1}",
         "-acodec", "libmp3lame", "-q:a", "4", str(silence)],

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
81% confidence
Finding

This ffmpeg call builds a filter_complex string from subtitle timing data and generated segment count without any hard limit. Malicious or malformed subtitle input could create extremely large filter graphs or pathological delays, leading to denial of service via CPU, memory, or process failure. In this skill context, user-supplied videos and subtitles make resource-abuse more plausible.

Content

Scanner excerpt · scripts/dubber.py (reported line 770)May include surrounding context.

python
)

    tts_track = workdir / "tts_track.mp3"
    subprocess.run(
        [FFMPEG, "-y"] + inputs + [
            "-filter_complex", ";".join(filter_parts),
            "-map", "[aout]",

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/dubber.py (reported line 864)May include surrounding context.

python
progress.update(sub="Đang tạo ASS subtitle…", pct=5)

    # Detect video resolution
    probe = subprocess.run([FFMPEG, "-i", str(video), "-hide_banner"],
                           capture_output=True, text=True)
    w, h = 1080, 1920  # default dọc
    m = re.search(r"(\d{3,4})x(\d{3,4})", probe.stderr)

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
90% confidence
Finding

The final ffmpeg invocation embeds a dynamically constructed subtitles filter referencing a generated ASS file derived from translated text. Although shell injection is avoided, untrusted subtitle content is passed into ffmpeg/libass processing, creating output-injection and parser-abuse risk, and malformed ASS/text can break processing or trigger vulnerabilities in underlying media libraries if present. This is more dangerous here because subtitle text comes from external transcription/translation flows and is then burned into media automatically.

Content

Scanner excerpt · scripts/dubber.py (reported line 881)May include surrounding context.

python
ass_path_fwd = str(ass_path).replace("\\", "/").replace(":", "\\:")
    sub_filter = f"subtitles='{ass_path_fwd}':fontsdir='C\\:/Windows/Fonts'"

    subprocess.run([
        FFMPEG, "-y",
        "-i", str(video), "-i", str(tts_track),
        "-filter_complex",

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/dubber.py (reported line 964)May include surrounding context.

python
prog.update(sub=f"Tải xong: {video_path.name}", pct=100)

        # Lấy thời lượng video
        probe   = subprocess.run([FFMPEG, "-i", str(video_path), "-hide_banner"],
                                 capture_output=True, text=True)
        dur_m   = re.search(r"Duration: (\d+):(\d+):(\d+)\.(\d+)", probe.stderr)
        total_dur = 60.0

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The embedded Playwright script hard-codes locale='zh-CN', which imposes a specific language/locale behavior regardless of user preference. This matches the policy category for language or locale constraints without an explicit opt-in or documented justification in the file.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.