Back to skill

Security audit

Gsap

Security checks for vulnerabilities and agentic risk

Overview

This skill is mostly a GSAP/HyperFrames reference with a disclosed audio visualizer helper; the main caution is resource use if the helper is run with extreme settings.

Install only if you want GSAP/HyperFrames animation guidance and may use the audio visualizer helper. Run the helper manually on trusted media, keep fps and band counts reasonable, and review any CDN script usage for your project policy.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/extract-audio-data.py:91
Finding

Unbounded FPS and Frequency-Band Parameters Can Cause Resource Exhaustion

Content
View full analysis

Vulnerability Details

File Location: scripts/extract-audio-data.py, lines 91-112 and 157-160
Vulnerability Type: Uncontrolled resource consumption
Risk Level: Medium

Vulnerable Code

python
duration = len(samples) / SAMPLE_RATE
frame_step = SAMPLE_RATE // fps
total_frames = int(duration * fps)

# Precompute constants
hann = np.hanning(FFT_SIZE)
band_edges = compute_band_edges(n_bands)
freq_per_bin = SAMPLE_RATE / FFT_SIZE
n_bins = FFT_SIZE // 2 + 1
half_fft = FFT_SIZE // 2

# Pass 1: extract raw values
rms_values = np.zeros(total_frames)
band_values = np.zeros((total_frames, n_bands))

The command-line validation only enforces lower bounds:

python
if args.fps < 1:
    parser.error("--fps must be at least 1")
if args.bands < 1:
    parser.error("--bands must be at least 1")

Technical Analysis

The user-controlled --fps and --bands arguments have no upper bounds. These values directly determine the dimensions of NumPy arrays and the number of FFT-band processing operations:

  • total_frames grows according to the media duration multiplied by fps.
  • band_values allocates approximately total_frames × n_bands × 8 bytes with its default NumPy floating-point type.
  • The processing loop performs work for every frame and every frequency band.
  • If fps exceeds SAMPLE_RATE, integer division makes frame_step equal to zero. The program can then repeatedly process the same audio position while still allocating and iterating over an extremely large number of frames.

Although the input is passed to ffmpeg using an argument array and therefore does not create a shell-command injection issue, unrestricted numeric dimensions allow an invocation to consume excessive memory and CPU.

Attack Path

  1. An attacker or untrusted automation gains the ability to influence arguments supplied to extract-audio-data.py.

  2. The attacker provides a valid media file and an extreme parameter, for example:

    bash
    p
    

...[truncated 1357 chars]

Remediation
View remediation

Remediation Suggestions

  1. Enforce conservative upper bounds for both arguments. For example, permit only rendering-relevant frame rates and a reasonable number of bands:

    python
    MAX_FPS = 240
    MAX_BANDS = 128
    
    if not 1 <= args.fps <= MAX_FPS:
        parser.error(f"--fps must be between 1 and {MAX_FPS}")
    if not 1 <= args.bands <= MAX_BANDS:
        parser.error(f"--bands must be between 1 and {MAX_BANDS}")
    
  2. Explicitly reject frame rates above SAMPLE_RATE so frame_step cannot become zero:

    python
    if args.fps > SAMPLE_RATE:
        parser.error(f"--fps must not exceed the sample rate ({SAMPLE_RATE})")
    
  3. Calculate estimated memory usage before allocating arrays and reject jobs that exceed a configured budget:

    python
    estimated_bytes = total_frames * 8
    estimated_bytes += total_frames * n_bands * 8
    
    MAX_MEMORY_BYTES = 512 * 1024 * 1024
    if estimated_bytes > MAX_MEMORY_BYTES:
        raise ValueError("Requested analysis exceeds the configured memory limit")
    
  4. Impose limits on media duration and maximum output frame count, particularly when media files or command-line arguments originate from untrusted users.

  5. Avoid retaining all frame data in memory when large inputs must be supported. Process frames incrementally and stream JSON output, or write batches to a temporary output file with controlled size limits.

  6. Run extraction jobs with operating-system or container resource controls, including memory, CPU-time, file-size, and execution-time limits.

  7. Add automated tests covering extreme fps, bands, duration, and estimated-output-size combinations to verify that invalid jobs fail before expensive allocations or processing begin.

Vulnerability Patterns
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description says this skill is a GSAP animation reference/documentation aid for writing animations in HyperFrames compositions. The supplied code does not provide GSAP reference behavior, timeline utilities, animation helpers, or anything related to GSAP APIs. Instead, it is an audio analysis script that reads media files, processes audio into visualization metrics, and outputs structured JSON. This is a materially different primary purpose and includes undeclared capabilities involving media decoding, numerical signal analysis, and file generation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

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/extract-audio-data.py (reported line 52)May include surrounding context.

python
"-loglevel", "error",
        "pipe:1",
    ]
    result = subprocess.run(cmd, capture_output=True)
    if result.returncode != 0:
        print(f"ffmpeg error: {result.stderr.decode()}", file=sys.stderr)
        sys.exit(1)

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The manifest describes a GSAP animation reference for HyperFrames focused on animation APIs, timelines, and performance. This file additionally instructs users to load scripts from external CDNs and, later, to run external preprocessing and synchronous data loading for audio visualization, which extends beyond the narrowly described GSAP API/reference scope.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest claims coverage of gsap.to/from/fromTo, easing, stagger, defaults, timelines, and performance techniques. The Audio Visualizer section introduces a separate workflow involving ffmpeg, numpy, a Python extraction script, JSON data generation, and XHR-based loading, which is materially broader than the stated GSAP reference scope.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.