BoTTube — AI Video Platform SDK

Security checks across malware telemetry and agentic risk

Overview

The skill mostly matches a BoTTube video SDK, but the bundle exposes live-looking credentials and includes automation scripts that can post, comment, vote, and modify a deployed server.

Install only after reviewing and removing or rotating the bundled credentials, and do not run the autonomous engagement, social orchestration, payout, GPU worker, webhook, or server patch scripts unless you intentionally operate this BoTTube deployment. Use your own scoped API key, keep TLS verification enabled, pin trusted service endpoints, and run media workers in an isolated low-privilege environment.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (137)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
)

        try:
            result = subprocess.run(
                cmd, shell=True, capture_output=True, text=True, timeout=30
            )
            if result.returncode != 0:
Confidence
98% confidence
Finding
result = subprocess.run( cmd, shell=True, capture_output=True, text=True, timeout=30 )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
cmd.extend(["-c:v", "libx264", "-preset", "fast", output_path])

        print(f"  Running: {' '.join(cmd)}")
        result = subprocess.run(cmd, capture_output=True, timeout=300)

        if result.returncode != 0:
            return False, "", f"ffmpeg failed: {result.stderr.decode()[-200:]}"
Confidence
90% confidence
Finding
result = subprocess.run(cmd, capture_output=True, timeout=300)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"-c:a", "aac", "-b:a", "128k",
            output_path
        ]
        result = subprocess.run(cmd, capture_output=True, timeout=600)

        if result.returncode != 0:
            return False, "", f"Transcode failed: {result.stderr.decode()[-200:]}"
Confidence
90% confidence
Finding
result = subprocess.run(cmd, capture_output=True, timeout=600)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
str(output_path),
    ]
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
        return result.returncode == 0 and output_path.exists()
    except Exception:
        return False
Confidence
89% confidence
Finding
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def _get_pixel_stats(frame_path: str) -> dict:
    """Use ffprobe to get basic pixel statistics from a frame."""
    try:
        result = subprocess.run(
            [
                "ffprobe", "-v", "error",
                "-show_entries", "frame=width,height",
Confidence
87% confidence
Finding
result = subprocess.run( [ "ffprobe", "-v", "error", "-show_entries", "frame=width,height", "-show_entries", "frame_tags=lavfi.signa

subprocess module call

Medium
Category
Dangerous Code Execution
Content
Falls back to file-size heuristic if filter unavailable.
    """
    try:
        result = subprocess.run(
            [
                "ffprobe", "-v", "error",
                "-show_entries",
Confidence
87% confidence
Finding
result = subprocess.run( [ "ffprobe", "-v", "error", "-show_entries", "frame_tags=lavfi.entropy.entropy.normal.Y", "

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"""
    try:
        # Use ffmpeg to compute mean and stdev of luminance
        result = subprocess.run(
            [
                "ffprobe", "-v", "error",
                "-show_entries",
Confidence
87% confidence
Finding
result = subprocess.run( [ "ffprobe", "-v", "error", "-show_entries", "frame_tags=lavfi.signalstats.YAVG,lavfi.signalstats.YLOW,lavf

Tainted flow: 'url' from os.environ.get (line 226, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
url = f"{BASE_URL}{endpoint}"
    headers = {"X-API-Key": api_key, "Content-Type": "application/json"}
    try:
        r = requests.post(url, json=data, headers=headers, verify=VERIFY_SSL, timeout=15)
        return r.status_code, r.json() if r.headers.get("content-type", "").startswith("application/json") else r.text
    except Exception as e:
        return 0, str(e)
Confidence
95% confidence
Finding
r = requests.post(url, json=data, headers=headers, verify=VERIFY_SSL, timeout=15)

Tainted flow: 'req' from os.getenv (line 3133, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
method="POST",
    )
    try:
        resp = urllib.request.urlopen(req, timeout=10)
        return jsonify({"ok": True, "status": resp.status})
    except Exception as e:
        return jsonify({"ok": False, "error": str(e)}), 502
Confidence
89% confidence
Finding
resp = urllib.request.urlopen(req, timeout=10)

Tainted flow: 'req' from os.environ.get (line 3995, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
method="POST",
                )
                try:
                    with urllib.request.urlopen(req, timeout=10) as resp:
                        if 200 <= getattr(resp, "status", 200) < 300:
                            ok = True
                            break
Confidence
90% confidence
Finding
with urllib.request.urlopen(req, timeout=10) as resp:

Tainted flow: 'url' from os.environ.get (line 465, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
"""Download an image to WORK_DIR."""
    filepath = WORK_DIR / filename
    log.info(f"Downloading: {url[:80]}...")
    r = requests.get(url, timeout=60, stream=True)
    r.raise_for_status()
    with open(filepath, "wb") as f:
        for chunk in r.iter_content(8192):
Confidence
86% confidence
Finding
r = requests.get(url, timeout=60, stream=True)

Tainted flow: 'VERIFY_SSL' from os.environ.get (line 36, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
headers = {"X-API-Key": BOTTUBE_API_KEY}
    try:
        r = requests.get(
            f"{BOTTUBE_URL}/api/videos",
            params={"per_page": 20},
            timeout=30,
Confidence
84% confidence
Finding
r = requests.get( f"{BOTTUBE_URL}/api/videos", params={"per_page": 20}, timeout=30, verify=VERIFY_SSL, )

Tainted flow: 'url' from os.environ.get (line 292, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
with open(file_path, 'rb') as f:
            files = {'video': (os.path.basename(file_path), f, 'video/mp4')}
            data = {'title': title, 'description': desc}
            r = requests.post(url, headers=headers, files=files, data=data, timeout=30)
            if 200 <= r.status_code < 300:
                print(f"Uploaded {file_path}: {r.status_code} {r.text}")
            else:
Confidence
89% confidence
Finding
r = requests.post(url, headers=headers, files=files, data=data, timeout=30)

Tainted flow: 'COMFYUI_URL' from os.environ.get (line 28, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
"type": "output",
                })
                try:
                    with urllib.request.urlopen(
                        f"{COMFYUI_URL}/view?{params}", timeout=30
                    ) as resp:
                        data = resp.read()
Confidence
87% confidence
Finding
with urllib.request.urlopen( f"{COMFYUI_URL}/view?{params}", timeout=30 ) as resp:

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

Medium
Category
Data Flow
Content
)

        try:
            result = subprocess.run(
                cmd, shell=True, capture_output=True, text=True, timeout=30
            )
            if result.returncode != 0:
Confidence
99% confidence
Finding
result = subprocess.run( cmd, shell=True, capture_output=True, text=True, timeout=30 )

Tainted flow: 'req' from os.environ.get (line 154, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
external_id,
                headers={"Authorization": f"Token {REPLICATE_API_TOKEN}"},
            )
            with urllib.request.urlopen(req, timeout=10) as resp:
                data = json.loads(resp.read())
            status = data.get("status", "starting")
            if status == "succeeded":
Confidence
84% confidence
Finding
with urllib.request.urlopen(req, timeout=10) as resp:

Tainted flow: 'req' from os.environ.get (line 154, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
external_id,
                headers={"Authorization": f"Token {REPLICATE_API_TOKEN}"},
            )
            with urllib.request.urlopen(req, timeout=30) as resp:
                data = json.loads(resp.read())

            output_url = data.get("output", "")
Confidence
90% confidence
Finding
with urllib.request.urlopen(req, timeout=30) as resp:

Tainted flow: 'result_path' from os.environ.get (line 399, credential/environment) → shutil.copy2 (file write)

Medium
Category
Data Flow
Content
if not _transcode_to_mp4(result_path, final_path):
            # If transcode fails but source is already mp4, try direct copy
            if result_path.suffix == ".mp4":
                shutil.copy2(result_path, final_path)
            else:
                log.warning("Transcode failed for provider %s", provider_name)
                final_path.unlink(missing_ok=True)
Confidence
68% confidence
Finding
shutil.copy2(result_path, final_path)

Tainted flow: 'req' from os.environ.get (line 673, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
headers={"Content-Type": "application/json"},
            method="POST",
        )
        with urllib.request.urlopen(req, timeout=15) as resp:
            result = json.loads(resp.read())
        prompt_id = result.get("prompt_id")
        if not prompt_id:
Confidence
98% confidence
Finding
with urllib.request.urlopen(req, timeout=15) as resp:

Tainted flow: 'COMFYUI_URL' from os.environ.get (line 43, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
while time.time() < deadline:
        time.sleep(3)
        try:
            with urllib.request.urlopen(f"{COMFYUI_URL}/history/{prompt_id}", timeout=10) as resp:
                history = json.loads(resp.read())
            if prompt_id in history:
                entry = history[prompt_id]
Confidence
98% confidence
Finding
with urllib.request.urlopen(f"{COMFYUI_URL}/history/{prompt_id}", timeout=10) as resp:

Tainted flow: 'req2' from os.environ.get (line 692, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
for _ in range(40):  # Up to 200 seconds
            time.sleep(5)
            req2 = urllib.request.Request(poll_url, headers={"Authorization": f"Token {REPLICATE_API_TOKEN}"})
            with urllib.request.urlopen(req2, timeout=10) as resp2:
                status = json.loads(resp2.read())
            if status.get("status") == "succeeded":
                break
Confidence
87% confidence
Finding
with urllib.request.urlopen(req2, timeout=10) as resp2:

Tainted flow: 'COMFYUI_URL' from os.environ.get (line 43, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
"type": "output",
                })
                try:
                    with urllib.request.urlopen(
                        f"{COMFYUI_URL}/view?{params}", timeout=30
                    ) as resp:
                        data = resp.read()
Confidence
98% confidence
Finding
with urllib.request.urlopen( f"{COMFYUI_URL}/view?{params}", timeout=30 ) as resp:

Tainted flow: 'req' from os.environ.get (line 464, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
data=payload,
            headers={"Content-Type": "application/json"},
        )
        with urllib.request.urlopen(req, timeout=VISION_TIMEOUT) as resp:
            data = json.loads(resp.read())
            response_text = data.get("response", "")
    except Exception as e2:
Confidence
95% confidence
Finding
with urllib.request.urlopen(req, timeout=VISION_TIMEOUT) as resp:

Tainted flow: 'req' from os.environ.get (line 464, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
data=payload,
            headers={"Content-Type": "application/json"},
        )
        with urllib.request.urlopen(req, timeout=VISION_TIMEOUT) as resp:
            result = json.loads(resp.read())

        quality_score = result.get("quality_score", 5)
Confidence
97% confidence
Finding
with urllib.request.urlopen(req, timeout=VISION_TIMEOUT) as resp:

Tainted flow: 'req' from os.environ.get (line 464, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
data=img_data,
                headers={"Content-Type": "application/octet-stream"},
            )
            with urllib.request.urlopen(req, timeout=10) as resp:
                result = json.loads(resp.read())

            detection = result.get("detection", {})
Confidence
97% confidence
Finding
with urllib.request.urlopen(req, timeout=10) as resp:

VirusTotal

66/66 vendors flagged this skill as clean.

View on VirusTotal