Back to skill

Security audit

Gif Search

Security checks for vulnerabilities and agentic risk

Overview

The bundled GIF search code is not destructive, but the package tells users to download and run mutable remote Python code and its documentation does not match the actual tool behavior.

Review before installing. Prefer running the bundled gif_search.py rather than following the curl command, or require a pinned release and checksum. Use your own restricted TENOR_API_KEY, avoid sensitive search terms because queries go to Tenor, and do not run the included verifier on untrusted folders outside a sandbox.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:31
Finding

Mutable Remote Python Payload Downloaded Without Integrity Verification

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:31-39
Vulnerability Type: Remote payload retrieval and supply-chain risk
Risk Level: High

Vulnerable Code

bash
## Install

```bash
# Requires Python 3.8+. No pip install needed.
curl -O https://raw.githubusercontent.com/itsPremkumar/gif-search/main/gif_search.py
# Or copy the file anywhere — it's self-contained.

Quick start

bash
python gif_search.py --help        # list options
text

The same unsafe installation workflow also appears in `README.md:33-41`.

### Technical Analysis

The installation instructions download executable Python code from the mutable `main` branch of a personal GitHub repository. The command does not pin the content to an immutable commit or release and does not verify a cryptographic checksum or signature.

Although `curl` does not execute the response directly, the subsequent quick-start command instructs the user to execute the downloaded `gif_search.py` file. Consequently, the code eventually executed can differ from the code reviewed in this package.

This remote download is not necessary for the packaged Skill's declared functionality because `gif_search.py` is already included in the project. It therefore introduces avoidable external trust and exceeds the minimum access necessary to use the bundled implementation.

### Attack Path

1. An attacker compromises the upstream GitHub account or repository, gains permission to modify the repository, or causes malicious content to be merged into the `main` branch.
2. The attacker replaces `gif_search.py` with a malicious Python payload.
3. A user follows the documented installation command, downloading the current attacker-controlled version.
4. The user follows the quick-start instructions and runs `python gif_search.py --help` or another command.
5. The malicious Python code executes with the permissions of the invoking user.

This path is contin
...[truncated 716 chars]
Remediation
View remediation

Remediation Suggestions

  • Remove the remote download command and instruct users to run the gif_search.py file already included in the reviewed package.
  • If remote installation is required, publish versioned releases and pin the download to an immutable release asset or full Git commit hash.
  • Publish a SHA-256 digest through a separately protected release channel and verify it before execution.
  • Prefer signed release artifacts and document signature verification.
  • Use defensive download options such as curl --fail --show-error --location so HTTP errors do not silently produce an unexpected file.
  • Do not immediately execute downloaded content unless its origin and integrity have been verified.
  • Apply the same changes to both SKILL.md and README.md so the installation instructions remain consistent.

T09 · Insecure Skill Coding Practices

Warning
Location
gif_search.py:14
Finding

Hardcoded Shared Tenor API Key in Source Code

Content
View full analysis

Vulnerability Details

File Location: gif_search.py:14-22
Vulnerability Type: Hardcoded API credential and query-string disclosure
Risk Level: Medium

Vulnerable Code

python
TENOR_API_KEY = os.environ.get("TENOR_API_KEY", "AIzaSyCx-GlApCF5ULgMLUaFs_78RAQk1JMNhLk")  # demo key
BASE_URL = "https://tenor.googleapis.com/v2"
USER_AGENT = "GIFSearch/1.0"

def _get(endpoint, params):
    params["key"] = TENOR_API_KEY
    url = f"{BASE_URL}/{endpoint}?{urllib.parse.urlencode(params)}"
    req = urllib.request.Request(url, headers={"User-Agent": USER_AGENT})
    with urllib.request.urlopen(req, timeout=10) as r:
        return json.loads(r.read())

Technical Analysis

The source contains a usable-looking Google/Tenor API key as the default value when TENOR_API_KEY is not defined. Because the project is distributed publicly, this value cannot be treated as confidential.

The _get function appends the key to the URL query string. HTTPS protects the URL in transit from ordinary network observers, but full URLs may still be recorded by application diagnostics, proxies, monitoring systems, or other infrastructure components. Embedding a shared key also prevents reliable attribution and per-user revocation.

No evidence was found that the program reads or exfiltrates unrelated credentials. The exposure is limited to the embedded Tenor/Google API credential.

Attack Path

  1. An attacker reads the public gif_search.py source.
  2. The attacker extracts the hardcoded API key.
  3. The attacker submits requests directly to APIs permitted by the key.
  4. Those requests consume the associated project's quota and appear under the key owner's project.
  5. Abuse may cause quota exhaustion, key revocation, service degradation, or costs if billing and unrestricted paid APIs are associated with the credential.

The practical scope depends on the API restrictions, quotas, and billing controls configured ...[truncated 743 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove the hardcoded fallback and require users to provide TENOR_API_KEY through the environment or an appropriate secret manager.
  • Fail with a clear error if the environment variable is absent.
  • Revoke or rotate the exposed key because removal from the latest source revision does not remove it from repository history or mirrors.
  • Restrict the replacement key to only the required Tenor API, with conservative quotas and billing alerts.
  • Use separate credentials for development, CI, and production environments.
  • Avoid printing or logging constructed request URLs containing credentials.
  • Where supported by the API, prefer an authorization header over a query-string credential.
  • Add secret scanning to CI and expand it beyond simplistic regular-expression checks.
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 (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documented feature set promises download, caching, batch operations, and conversion, but the actual capabilities reportedly omit those functions and add undeclared ones such as trending, random retrieval, and GIF info lookup. Even if not overtly malicious, this is unsafe because users and policy engines cannot reliably predict the skill's behavior from its metadata.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documented feature set promises download, caching, batch operations, and conversion, but the actual capabilities reportedly omit those functions and add undeclared ones such as trending, random retrieval, and GIF info lookup. Even if not overtly malicious, this is unsafe because users and policy engines cannot reliably predict the skill's behavior from its metadata.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The documented feature set promises download, caching, batch operations, and conversion, but the actual capabilities reportedly omit those functions and add undeclared ones such as trending, random retrieval, and GIF info lookup. Even if not overtly malicious, this is unsafe because users and policy engines cannot reliably predict the skill's behavior from its metadata.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill advertises capabilities that inherently require network access, environment variable access, local file writes, and likely shell execution, but it declares no explicit tool scope or permissions. In an agent environment, this weakens security boundaries and makes it harder for users or orchestrators to constrain what the skill can do before execution.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
96% confidence
Finding

The harness executes an arbitrary Python file from the target product directory with a self-test argument. Because the file path is discovered from the untrusted folder contents and then run as code, a malicious skill can execute arbitrary code during verification, leading to code execution in CI or on a maintainer's workstation.

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
90% confidence
Finding

Beyond the core code-execution risk, the verifier provides no explicit warning or consent step before running a discovered Python file from an untrusted product. This increases the likelihood that maintainers or CI operators will execute attacker-controlled code without realizing the verification step is unsafe.

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
97% confidence
Finding

The verifier discovers test files in the target folder and executes them directly with Python. Since those test files are controlled by the untrusted skill author, verification can trigger arbitrary code execution, enabling secret theft, filesystem modification, or CI compromise.

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
92% confidence
Finding

The harness silently executes discovered test_*.py files without notifying the user that repository-controlled code will run. In the context of reviewing third-party skills, this lack of disclosure materially worsens the arbitrary-code-execution risk because test files are especially likely to be trusted automatically.

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)")

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The module docstring and implemented commands expose only search, trending, random, info, and a self-test flow; there is no code that downloads GIF content, caches results, performs bulk download, or converts formats. This creates a clear mismatch with the manifest description, which materially overstates the skill's actual behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code file sends user-provided queries to the Tenor API and includes the API key in outbound requests, but there is no confirmation prompt, logging/print disclosure, or comment/docstring warning that search terms are transmitted to a third-party service. For this file type, outbound network transmission of user or system data should have some visible disclosure unless clearly warned elsewhere in the skill description, which is not present in this file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This markdown file describes searching, downloading, and caching GIFs, which implies outbound requests to Tenor and writing files or cached data locally. While these behaviors are mentioned functionally, there is no explicit warning about privacy/system-impact implications such as transmitting queries to a third-party API or storing downloaded/cached content on disk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
74% confidence
Finding

The verifier launches another script as a subprocess in the target folder, which is an additional code-execution step with potential side effects. While this may be expected in CI, the file does not clearly warn users running it locally that verification includes executing ci/ci_check.py.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.