Back to skill

Security audit

Fellow Aiden Precision Coffee Maker

Security checks for vulnerabilities and agentic risk

Overview

This skill asks for Fellow account credentials and sends them to a hard-coded, undisclosed AWS API endpoint while advertising device-control features the bundled code does not actually implement.

Install only after you are comfortable giving this skill your Fellow email and password and after verifying who operates the hard-coded API Gateway endpoint. Expect the shipped code to be mostly read-only despite the docs advertising create/delete/share/schedule features, and treat the unpinned unused dependency as something that should be removed or pinned before routine use.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (2)

other

Error
Location
fellow.py:12
Finding

Fellow Account Credentials Transmitted to an Undisclosed API Gateway

Content
View full analysis

Vulnerability Details

File Location: fellow.py:12, fellow.py:21-39, and fellow.py:85-97
Vulnerability Type: Credential exfiltration to an unverifiable destination
Risk Level: Critical

Vulnerable Code

python
BASE_URL = 'https://l8qtmnc692.execute-api.us-west-2.amazonaws.com/v1'
python
def _auth(self):
    """Authenticate and get token."""
    auth = {"email": self._email, "password": self._password}
    session = requests.Session()
    session.headers.update(HEADERS)
    login_url = BASE_URL + '/auth/login'
    response = session.post(login_url, json=auth, headers=HEADERS)
    parsed = json.loads(response.content)
    
    if 'accessToken' not in parsed:
        raise Exception("Email or password incorrect.")
    
    self._token = parsed['accessToken']
    self._session = session
    self._session.headers.update({'Authorization': 'Bearer ' + self._token})
python
def get_client():
    email = os.environ.get("FELLOW_EMAIL")
    password = os.environ.get("FELLOW_PASSWORD")

    if not email or not password:
        print(json.dumps({"error": "Missing credentials. Set FELLOW_EMAIL and FELLOW_PASSWORD environment variables."}))
        sys.exit(1)

    try:
        return FellowAidenDirect(email, password)
    except Exception as e:
        print(json.dumps({"error": f"Failed to connect: {str(e)}"}))
        sys.exit(1)

Technical Analysis

The implementation reads the user's Fellow email address and password from environment variables and sends both values in a JSON request to a hard-coded AWS API Gateway endpoint. The endpoint is not under an identifiable Fellow-owned domain, and neither README.md nor SKILL.md discloses this destination or provides evidence that it is an authorized Fellow authentication service.

Every implemented operation calls get_client(). Constructing FellowAidenDirect immediately invokes _auth(), so e ...[truncated 1917 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the hard-coded API Gateway with a documented, independently verifiable Fellow-owned authentication endpoint.
  2. Prefer an official, audited SDK or an OAuth/device-authorization flow using scoped, revocable tokens instead of collecting reusable account passwords.
  3. Clearly disclose the authentication destination, operator, privacy implications, and exact data transmitted before asking users to configure credentials.
  4. Validate the destination against an explicit allowlist and prevent redirects from forwarding authorization data to unrelated hosts.
  5. Store only short-lived access tokens where possible, and never log credentials, bearer tokens, or complete authentication responses.
  6. Add explicit request timeouts, HTTP status validation, and secure failure handling.
  7. Obtain and document authoritative proof that the endpoint is operated by or formally authorized by Fellow before distributing the Skill.

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Unpinned and Unused Third-Party Package Installed from PyPI

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1 and SKILL.md:14-17
Vulnerability Type: Unpinned third-party dependency and unnecessary supply-chain exposure
Risk Level: Medium

Vulnerable Code

requirements.txt:

text
fellow-aiden>=0.1.0

SKILL.md:

yaml
install:
  - id: pip-fellow-aiden
    kind: shell
    label: Install fellow-aiden Python library
    formula: pip3 install fellow-aiden --quiet

Technical Analysis

The dependency constraint accepts any version of fellow-aiden at or above version 0.1.0. Consequently, installation may resolve to a future release that was not reviewed with this Skill. No integrity hashes or lock file are supplied to ensure that users receive a known artifact.

Python package installation can execute package build or installation logic. A compromised maintainer account, malicious future release, or upstream package compromise could therefore introduce arbitrary code into the installation process.

The exposure is unnecessary for the implementation reviewed here: fellow.py performs direct HTTP requests and never imports fellow-aiden. The Skill documentation nevertheless directs the environment to install the package, increasing the trusted computing base without supporting the bundled script's implemented behavior.

Attack Path

  1. A user or automated Skill installer processes the installation formula or requirements.txt.
  2. pip queries the configured package index and selects the newest release satisfying fellow-aiden>=0.1.0.
  3. If that release or its distribution account has been compromised, the installer downloads an attacker-controlled artifact.
  4. Package build or installation logic executes with the privileges of the user installing the Skill.
  5. Malicious code could access files, environment variables, network resources, or credentials available to that process.

Impact Assessment

Successful exp ...[truncated 537 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the fellow-aiden dependency and installation step if the direct HTTP implementation remains in use.
  2. If the package is genuinely required, pin it to an audited exact version rather than using an open-ended lower bound.
  3. Supply cryptographic hashes using a hash-locked requirements file and install with pip --require-hashes.
  4. Review all transitive dependencies and regenerate the lock file through a controlled dependency-update process.
  5. Avoid --quiet during security-sensitive installations so users and operators can inspect package resolution and installation activity.
  6. Install dependencies in an isolated virtual environment under a non-privileged account.
  7. Use a trusted package mirror or registry policy that restricts packages to reviewed artifacts.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The description overstates the implemented functionality. While the code does access the Fellow Aiden brewer and can view brewer status, profiles, and schedules, it only performs GET-style reads from the API. There are no endpoints or commands for starting/stopping brews, changing settings, creating or tweaking recipes/profiles, adding shared brew links, or creating/updating/deleting schedules. The primary implemented behavior is a read-only inspection tool for brewer/device metadata, profiles, and schedules, not a full control-and-management skill as declared.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · README.md (reported line 14)May include surrounding context.

md
- **Brewer info** — check your brewer's display name and details
- **Profiles** — list, create, edit, delete, import, and share brew profiles
- **Brew Links** — import profiles from `brew.link` URLs or generate shareable links for your own
- **Schedules** — create and manage weekly automated brew schedules
- **Fuzzy matching** — find profiles by approximate title, no exact name needed

---

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README encourages broad natural-language control of a physical device without documenting guardrails, confirmation steps, or limits on ambiguous commands. In a voice/agent context, vague invocation increases the chance of unintended actions such as starting brews, changing schedules, or modifying profiles based on misinterpretation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README includes deletion of a profile as a normal example but provides no warning that this is destructive or that the skill should confirm the target before deleting. Combined with fuzzy matching and conversational control, this can lead to accidental deletion of the wrong profile or loss of user configuration.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill requires environment secrets and network access to authenticate to a third-party service, but it does not declare any explicit tool scope or permissions boundary. That makes the skill's effective capabilities less transparent to the platform and user, increasing the risk of overbroad execution and accidental secret exposure through an undeclared trust surface.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill encourages generating brew.link share URLs without warning that sharing may expose proprietary or personal brewing profiles to third parties or make them publicly accessible. Users may inadvertently disclose preferences, naming conventions, or linked profile data because the sharing action is presented as harmless and frictionless.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code sends the user's email and password to a remote API and then retrieves device information over HTTP requests. Although the functions have internal docstrings and there is an error message for missing credentials, there is no user-facing disclosure that credentials and account/device data will be transmitted to an external service.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The implemented commands and API methods are limited to authentication plus GET requests for device details, profiles, and schedules. There is no code here to create, update, delete, or otherwise manage profiles, recipes, shared brew links, or schedules as described in the manifest.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The README promotes creation of automated brew schedules without warning that this enables autonomous operation of a real appliance. Users may unintentionally configure recurring behavior that activates at unwanted times, with minor safety, waste, or nuisance consequences depending on the brewer state.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
91% confidence
Finding

The dependency is specified with a lower bound only, which allows installation of any newer version, including future releases that may introduce vulnerable, malicious, or breaking changes. Because this skill controls a smart coffee brewer and can manage schedules and shared brew links, a compromised or unexpectedly changed package could affect device operations or abuse connected-account functionality.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
fellow-aiden>=0.1.0

Static analysis

No suspicious patterns detected.