Back to skill

Security audit

Random Coffee Outreach

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent and privacy-conscious, but its executable wrapper can load unreviewed local Python code from ancestor directories when run.

Review before installing. Use the skill only from a trusted repository layout, avoid running the wrapper from directories whose ancestors may contain untrusted src/random_coffee_matcher content, and prefer a pinned installed package or a wrapper that imports only from an explicit trusted project root.

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/random_coffee_matcher.py:10
Finding

Untrusted Ancestor-Path Python Module Loading

Content
View full analysis

Vulnerability Details

File Location: scripts/random_coffee_matcher.py, lines 10–15 and 23–27
Vulnerability Type: Python module search-path hijacking
Risk Level: Medium

Vulnerable Code

python
def add_repo_src() -> None:
    for parent in Path(__file__).resolve().parents:
        src = parent / "src"
        package = src / "random_coffee_matcher"
        if package.exists():
            sys.path.insert(0, str(src))
            return
    raise SystemExit(
        "Could not find src/random_coffee_matcher. Run this script from the "
        "random-coffee-best-fit-outreach repo clone or install the package first."
    )


def main() -> int:
    add_repo_src()
    from random_coffee_matcher.cli import main as cli_main

    return cli_main()

Technical Analysis

The wrapper traverses every ancestor of its own resolved path and accepts the first entry named src/random_coffee_matcher. It then places that ancestor-controlled src directory at the beginning of sys.path and imports random_coffee_matcher.cli.

The code does not establish a trusted repository root, verify that the selected package belongs to the intended project, or ensure that the selected package path is a directory. Because the selected path takes precedence over other Python module locations, a package placed in a writable ancestor can control the imported module.

Python executes package initialization and module-level statements during import. Consequently, merely invoking the documented wrapper can execute attacker-supplied Python before the expected CLI function is called.

The audited artifact does not contain src/random_coffee_matcher. In an environment without a matching ancestor package, the wrapper fails safely with SystemExit. Exploitation therefore requires an attacker to be able to create or influence the expected path in an ancestor directory of the installed skill.

Attack Path

  1. An attacker obtains write access to an ancestor directory ...[truncated 1596 chars]
Remediation
View remediation

Remediation Suggestions

  1. Bundle the required random_coffee_matcher package within the skill, or declare and install it through a pinned, integrity-verified dependency mechanism.
  2. Resolve modules from one explicit directory beneath a known project root rather than searching every ancestor.
  3. Validate the candidate with is_dir() and use Path.resolve() to ensure it remains inside the trusted root.
  4. Fail closed when the exact trusted package path is absent.
  5. Avoid prepending dynamically discovered directories to sys.path. Prefer a normal installed package or an explicit package-relative import.
  6. If repository-layout support is required, identify the repository root using a trusted manifest with validated contents rather than a generic directory name.
  7. Add tests that create decoy src/random_coffee_matcher packages in ancestor directories and confirm that the wrapper refuses to import them.

A hardened approach should use a single expected path, for example:

python
def add_repo_src() -> None:
    project_root = Path(__file__).resolve().parents[1]
    src = (project_root / "src").resolve()
    package = (src / "random_coffee_matcher").resolve()

    if src.parent != project_root or package.parent != src or not package.is_dir():
        raise SystemExit("Trusted bundled random_coffee_matcher package not found.")

    sys.path.insert(0, str(src))

This example assumes that parents[1] is the intentionally defined project root; deployment should enforce that layout and add stronger integrity controls where the surrounding directory is not trusted.

Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (1)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The activation description includes generic requests like "random coffee," "warm networking," and "founder/operator matching" without clear trigger constraints or exclusion conditions. In a markdown skill description, this is vague enough to overlap with ordinary conversation and may cause unintended invocation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.