Back to skill

Security audit

Ascii Video

Security checks for vulnerabilities and agentic risk

Overview

The bundled converter mostly matches its stated ASCII-video purpose, but its documentation tells users to download and run mutable remote Python code that was not the reviewed artifact.

Review before installing. Prefer running the bundled artifact/ascii_video.py, not the documented curl command, unless the download is pinned to a trusted commit and verified. Expect local file reads/writes, ffmpeg execution, and Pillow/ffmpeg dependencies; avoid running the CI verifier on untrusted folders outside a sandbox.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (2)

T03 · Remote Payload Retrieval and Execution

Warning
Location
SKILL.md:34
Finding

Mutable Remote Python Payload Download in Skill Installation Instructions

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:34
Vulnerability Type: Remote payload retrieval from an unpinned source
Risk Level: Medium

Vulnerable Code

bash
curl -O https://raw.githubusercontent.com/itsPremkumar/ascii-video/main/ascii_video.py

The subsequent quick-start instructions execute the downloaded file:

bash
python ascii_video.py self-test
python ascii_video.py convert --help
python ascii_video.py frame --help
python ascii_video.py image --help

Technical Analysis

The installation instructions retrieve executable Python code from the mutable main branch of a repository controlled by a personal GitHub account. The URL is not pinned to an immutable commit or release artifact, and the instructions do not verify a checksum or cryptographic signature.

As a result, the effective code executed by users can differ from the code reviewed in this Skill package. This remote retrieval is also unnecessary for the declared functionality because ascii_video.py is already included in the package.

The download itself does not automatically execute the payload, but the documented quick-start commands instruct users to run the downloaded file. This creates a direct remote-payload execution path if the upstream repository, maintainer account, DNS/TLS trust chain, or release process is compromised.

Attack Path

  1. An attacker compromises the upstream repository or the maintainer's GitHub account, or otherwise gains permission to modify the main branch.
  2. The attacker replaces ascii_video.py with a malicious Python payload.
  3. A user follows the installation command in SKILL.md.
  4. curl downloads the current attacker-controlled version without integrity verification.
  5. The user follows the quick-start instructions and runs python ascii_video.py ....
  6. The payload executes with the same operating-system privileges and environment access as the invoking user.

...[truncated 584 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the remote download command and instruct users to execute the bundled ascii_video.py file.
  2. If remote installation must remain supported, pin the URL to an immutable Git commit rather than main.
  3. Publish an expected SHA-256 digest through a separately trusted release channel and verify it before execution.
  4. Prefer signed release artifacts and document signature verification.
  5. Avoid commands that immediately execute newly downloaded code.
  6. Correct the installation documentation to disclose the Pillow and ffmpeg dependencies rather than describing the program as fully self-contained.

T03 · Remote Payload Retrieval and Execution

Warning
Location
README.md:36
Finding

Mutable Remote Python Payload Download in README Installation Instructions

Content
View full analysis

Vulnerability Details

File Location: README.md:36
Vulnerability Type: Remote payload retrieval from an unpinned source
Risk Level: Medium

Vulnerable Code

bash
curl -O https://raw.githubusercontent.com/itsPremkumar/ascii-video/main/ascii_video.py

The README subsequently directs users to execute the retrieved file:

bash
python ascii_video.py self-test
python ascii_video.py convert --help
python ascii_video.py frame --help
python ascii_video.py image --help

Technical Analysis

The README downloads executable Python code from a mutable branch without pinning an immutable revision or performing integrity verification. Consequently, a future or unauthorized upstream modification can change the code users receive after this package has been audited.

Although GitHub is a conventional hosting provider, trust is delegated to the current state of a personal repository's main branch. The package already contains the relevant script, so this additional external retrieval exceeds the minimum network access necessary to use the Skill.

Attack Path

  1. An attacker obtains control over the referenced repository or its main branch.
  2. The attacker publishes a modified ascii_video.py.
  3. A user copies the documented curl command.
  4. The unverified malicious script is written to the user's working directory.
  5. The user runs one of the documented Python commands.
  6. The malicious code executes in the user's security context.

Impact Assessment

Exploitation enables arbitrary code execution with the permissions of the user or automation runner following the README. Accessible files, environment variables, development credentials, network resources, and user-level configuration may be exposed or modified.

No evidence was found that the bundled implementation itself attempts privilege escalation, persistence, credential theft, or data exfiltration. The risk arises from a ...[truncated 63 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the curl instruction with directions to use the copy of ascii_video.py distributed in the audited package.
  2. If downloads are necessary, use an immutable commit or versioned release URL.
  3. Provide and verify a cryptographic checksum or signature before execution.
  4. Ensure release documentation and packaged code reference the same reviewed version.
  5. Document the actual Pillow and ffmpeg prerequisites so users do not rely on the inaccurate “No pip install needed” and “self-contained” claims.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (20)

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

If the underlying skill code actually performs filesystem inspection, subprocess execution, CI/deployment verification, and secret scanning while claiming to be a harmless ASCII-video utility, that is a serious description-behavior mismatch. In an agent ecosystem, disguising privileged reconnaissance and code execution behind an unrelated media-conversion description can trick users or orchestrators into granting dangerous access.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

If the underlying skill code actually performs filesystem inspection, subprocess execution, CI/deployment verification, and secret scanning while claiming to be a harmless ASCII-video utility, that is a serious description-behavior mismatch. In an agent ecosystem, disguising privileged reconnaissance and code execution behind an unrelated media-conversion description can trick users or orchestrators into granting dangerous access.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

If the underlying skill code actually performs filesystem inspection, subprocess execution, CI/deployment verification, and secret scanning while claiming to be a harmless ASCII-video utility, that is a serious description-behavior mismatch. In an agent ecosystem, disguising privileged reconnaissance and code execution behind an unrelated media-conversion description can trick users or orchestrators into granting dangerous access.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The top-level parser defines subcommands and their arguments, but main() then calls cmd_convert/cmd_frame/cmd_image with 'rest', which will typically be empty because parse_known_args already consumed the subcommand arguments. This contradicts the documented commands in the module docstring and manifest by making the advertised conversion operations unusable from the main CLI entrypoint.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill advertises commands that download and run a Python script and references shell-based execution, but the manifest declares no explicit tool scope such as shell, file read, or file write permissions. In an agent setting, missing permission boundaries can let the skill obtain broader capabilities than a reviewer expects, increasing the chance of unsafe file access or command execution.

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 · ascii_video.py (reported line 243)May include surrounding context.

python
"-qscale:v", "2",
        "-y", pattern,
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        print(f"ffmpeg error: {result.stderr}", file=sys.stderr)
        return 0

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 · ascii_video.py (reported line 267)May include surrounding context.

python
"-qscale:v", "2",
        "-y", pattern,
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        print(f"ffmpeg error: {result.stderr}", file=sys.stderr)
        return 0

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 · ascii_video.py (reported line 441)May include surrounding context.

python
"-qscale:v", "2",
        "-y", pattern,
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        print(f"ffmpeg error: {result.stderr}", file=sys.stderr)
        return 0

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest says the skill supports 'multiple dithering modes', but the implementation only offers multiple ASCII character sets via --charset and hard-codes a single ffmpeg GIF dithering mode ('bayer') during palette use. There is no user-selectable dithering mode or broader dithering implementation matching that claim.

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 · ascii_video.py (reported line 286)May include surrounding context.

python
"-vf", "palettegen=stats_mode=diff",
        "-y", palette_path,
    ]
    subprocess.run(cmd1, capture_output=True, text=True)

    cmd2 = [
        "ffmpeg",

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 · ascii_video.py (reported line 296)May include surrounding context.

python
"-lavfi", "paletteuse=dither=bayer:bayer_scale=5",
        "-y", output_path,
    ]
    result = subprocess.run(cmd2, capture_output=True, text=True)

    # Clean up palette
    if os.path.exists(palette_path):

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
98% confidence
Finding

The script executes arbitrary Python files from the target skill directory as part of self-test discovery. Because the repository content is treated as untrusted input, this creates a direct arbitrary code execution path during CI or local verification, allowing a malicious skill author to run code on the verifier's machine.

Content

Scanner excerpt · ci/verify_product.py (reported line 37)May include surrounding context.

python
def has_self_test(fp):
    r = subprocess.run([sys.executable, fp, "self-test"], capture_output=True, text=True, timeout=30)
    return r.returncode == 0 and "PASS" in r.stdout

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Beyond the generic subprocess use, this is specifically dangerous because the harness silently executes a discovered product script as a self-test with no opt-in warning at the execution point. Users may believe they are performing passive verification, but are actually running untrusted code supplied by the skill author.

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 · ci/verify_product.py (reported line 67)May include surrounding context.

python
all_ok &= axis(False, "frontmatter (no SKILL.md)")
        all_ok &= axis(False, "docs (no SKILL.md)")
    # 3 compiles
    comp_ok = all(subprocess.run([sys.executable, "-m", "py_compile", fp],
                                capture_output=True).returncode == 0 for fp in files)
    all_ok &= axis(comp_ok, "compiles (py_compile all .py)")
    # 4 self-test (any of 3 valid forms)

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
98% confidence
Finding

The verifier automatically executes discovered test_*.py or *_test.py files from the target folder. In an adversarial skill context, a malicious author can place arbitrary payloads in a test file so they run during CI/local validation, resulting in arbitrary code execution, data exfiltration, or environment tampering.

Content

Scanner excerpt · ci/verify_product.py (reported line 79)May include surrounding context.

python
tests = [os.path.join(folder, f) for f in os.listdir(folder)
                 if (f.startswith("test_") or f.endswith("_test.py")) and f.endswith(".py")]
        if tests:
            st_ok = all(subprocess.run([sys.executable, t], capture_output=True, text=True,
                                      timeout=30).returncode == 0 for t in tests)
            st_note = f"{len(tests)} test_*.py"
        elif re.search(r"(?im)^test\s*:", skill_txt):

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script silently executes discovered test files from the analyzed folder, which is especially risky in a skill-verification context where content must be assumed adversarial. Lack of disclosure increases the chance that reviewers or CI operators unintentionally run attacker-controlled code under trusted credentials or network access.

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 · ci/verify_product.py (reported line 92)May include surrounding context.

python
# 7 deploy-ready
    ci = os.path.join(os.path.dirname(os.path.abspath(__file__)), "ci_check.py")
    if os.path.isfile(ci) and os.path.isfile(skill):
        r = subprocess.run([sys.executable, ci], cwd=folder, capture_output=True, text=True)
        all_ok &= axis(r.returncode == 0, "deploy-ready (ci/ci_check.py PASS)")
    else:
        all_ok &= axis(True, "deploy-ready (skipped)")

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The ffmpeg command uses '-y', which forces overwrite of existing output files without confirmation. In contexts where output paths may be influenced by other users or automation, this can cause unintended data loss or clobber existing files, especially because the tool accepts arbitrary output paths.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The image command writes directly to a user-specified path with normal file-open semantics, overwriting any existing file without warning. This can lead to accidental destruction of local files if the path is mistyped, reused, or supplied by an untrusted workflow wrapper.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

The verifier invokes ci_check.py in the context of the target folder, which is another subprocess action affecting the analyzed workspace. While consistent with the tool's purpose, there is no explicit user-facing notice at the call site that an additional script will be executed as part of verification.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.