Back to skill

Security audit

petTracer pet tracking

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to perform PetTracer tracking as advertised, but it handles sensitive credentials and live location data with overly broad endpoint controls.

Review before installing. Use this only in a trusted agent environment, do not set custom PetTracer API or WebSocket base URLs unless you control and trust them, prefer environment-injected short-lived tokens over passwords, avoid passing passwords on the command line, and treat all stdout, generated PNGs, map links, and history/live output as sensitive location data.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/pettracer_cli.py:41
Finding

Configurable REST API Origin Can Exfiltrate PetTracer Credentials and Bearer Tokens

Content
View full analysis
str: """Return bearer token from env or by logging in.""" token = _env_first("PETTRACER_TOKEN") if token: return token username = username or _env_first("PETTRACER_USERNAME", "PETTRACER_EMAIL") password = password or _env_first("PETTRACER_PASSWORD") if not username or not password: raise PetTracerAuthError( "Missing credentials. Set PETTRACER_TOKEN or (PETTRACER_USERNAME/PETTRACER_EMAIL + PETTRACER_PASSWORD)." ) payload = {"login": username, "password": password} resp = _request("POST", LOGIN_ENDPOINT, json_body=payload, timeout_s=timeout_s, retries=retries) if not isinstance(resp, dict): raise PetTracerAuthError("Login response was not a JSON object.") token = resp.get("access_token") or resp.get("token") or resp.get("id_token") if not token: raise PetTracerAuthError("Login response did not contain an access token.") return str(token) def fetch_devices(*, token: str, timeout_s: int, retries: int) -> List[Dict[str, Any]]: ...[truncated 2573 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/pettracer_watch.py:43
Finding

Arbitrary WebSocket Origin Receives the PetTracer Bearer Token in the URL

Content
View full analysis
None: self.ws_base = ws_base.rstrip("/") self.token = token self.device_ids = [int(x) for x in device_ids] self.verbose = verbose self._running = True # Lazily imported dependency try: import aiohttp # noqa: F401 except Exception as e: raise RuntimeError("aiohttp is required. Install with: pip install aiohttp") from e async def run_forever(self) -> None: import aiohttp backoff_s = 10 backoff_max_s = 60 while self._running: session_id = _rand_session_id() server_id = _rand_server_id() url = f"{self.ws_base}/{server_id}/{session_id}/websocket?access_token={self.token}" if self.verbose: print(f"[pettracer_watch] connecting: {_redact_access_token(url)}", file=sys.stderr) try: async with aiohttp.ClientSession() as session: async with session.ws_connect(url, heartbeat=30) as ws: ``` ```python p.add_argument("--ws-base", default=DEFAULT_WS_BASE, help="SockJS WS base (default: PetTracer).") ``` ### Technical Analysis The live-tracking client accepts a WebSocket base through either `PETTRACER_WS_BASE` or the command-line `--ws-base` option. It does not verify that the scheme is `wss`, that the destination hostname is `pt.pettracer.com`, or that the destination otherwise belongs to PetTracer. The client appends the bearer token as the `access_token` quer ...[truncated 1629 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/pettracer_watch.py:234
Finding

Unredacted WebSocket Exceptions May Leak Bearer Tokens to Logs

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/requirements.txt:1
Finding

Unbounded and Unhashed aiohttp Dependency Creates Supply-Chain Risk

Content
View full analysis
=3.8 ``` The Skill directs users or agents to install this dependency: ```bash # Install dependency pip install -r scripts/requirements.txt # Stream updates python scripts/pettracer_watch.py --pet "Fluffy" ``` ### Technical Analysis The requirement specifies only a lower version bound. Every future `aiohttp` release satisfying `>=3.8` is therefore eligible for installation. No lock file, upper bound, exact version, package hash, or trusted-index constraint is provided. This makes installation non-reproducible and causes the effective code executed by the Skill to depend on the package index state at installation time. A compromised upstream release, compromised package index, unsafe future release, or maliciously configured package mirror could introduce arbitrary code into the agent environment. This is a supply-chain weakness rather than evidence that the current `aiohttp` package is malicious. ### Attack Path 1. The agent follows the documented command and runs `pip install -r scripts/requirements.txt`. 2. Pip queries its configured package index or mirror. 3. The resolver selects any available release satisfying `aiohttp>=3.8`. 4. A compromised index, mirror, account, or future release supplies malicious package content. 5. Package installation or subsequent import executes attacker-controlled code in the agent's Python environment. 6. The malicious dependency inherits the process's access to PetTracer credentials, map API keys, location data, files, and network connectivity. ### Impact Assessment Compromised dependency code runs with the same operating-system privileges as the user or agent executing the Skill. It could potentially: - Read `PETTRACER_PASSWORD`, `PETTRACER_TOKEN`, and `GO ...[truncated 416 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/pettracer_cli.py:763
Finding

Command-Line Password Options Expose PetTracer Credentials Through Process Metadata

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • 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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (17)

Tainted flow: 'req' from os.getenv (line 84, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The script allows API and WebSocket base URLs to be fully overridden via environment variables and then sends bearer tokens and/or user credentials to those endpoints. In an agent or multi-tenant environment, a malicious or poisoned environment configuration could redirect requests to an attacker-controlled host, causing credential and token exfiltration.

Content

Scanner excerpt · scripts/pettracer_watch.py (reported line 86)May include surrounding context.

python
req = Request(url, data=data, headers=headers, method=method.upper())
    try:
        with urlopen(req, timeout=timeout_s) as resp:
            raw = resp.read().decode("utf-8")
            return json.loads(raw)
    except HTTPError as e:

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This skill introduces an additional external dependency on Google Maps Static API beyond the core PetTracer tracking function, but that dependency is not clearly reflected in an enforceable permission/resource declaration. Hidden or underdeclared third-party data flows are risky because precise pet GPS coordinates may be transmitted to another vendor without clear disclosure or policy control.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

This skill introduces an additional external dependency on Google Maps Static API beyond the core PetTracer tracking function, but that dependency is not clearly reflected in an enforceable permission/resource declaration. Hidden or underdeclared third-party data flows are risky because precise pet GPS coordinates may be transmitted to another vendor without clear disclosure or policy control.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

This skill introduces an additional external dependency on Google Maps Static API beyond the core PetTracer tracking function, but that dependency is not clearly reflected in an enforceable permission/resource declaration. Hidden or underdeclared third-party data flows are risky because precise pet GPS coordinates may be transmitted to another vendor without clear disclosure or policy control.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 147)May include surrounding context.

md
pip install -r scripts/requirements.txt

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/maps.md (reported line 49)May include surrounding context.

md
If Google Maps Static API isn’t viable, alternatives include:

- **Mapbox Static Images API** (needs Mapbox access token)
- **OSM-derived static map services** (often free/cheap, but you must respect provider terms; OSM Foundation tile servers are best-effort and can block heavy usage)

If you need one of these alternatives, extend `pettracer_mapshot.py` with a `--provider` switch.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/pettracer_cli.py (reported line 361)May include surrounding context.

python
raise RuntimeError("Login response was not a JSON object.")
    token = resp.get("access_token") or resp.get("token") or resp.get("id_token")
    if not token:
        raise RuntimeError("Login response did not contain an access token.")
    return str(token)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/pettracer_watch.py (reported line 117)May include surrounding context.

python
raise RuntimeError("Login response was not a JSON object.")
    token = resp.get("access_token") or resp.get("token") or resp.get("id_token")
    if not token:
        raise RuntimeError("Login response did not contain an access token.")
    return str(token)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill requires access to environment secrets and outbound network communication but does not declare any explicit tool scope or allowed-tools boundaries. In an agent environment, this increases the risk of overbroad execution, secret access, and unintended external requests because the runtime cannot enforce least privilege from the manifest alone.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The activation guidance uses broad natural-language triggers such as asking where a pet is or requesting a map image, which can cause over-triggering in loosely related conversations. In a location-tracking skill, accidental activation is more dangerous than usual because it may access sensitive geolocation data and account inventory without sufficiently explicit user intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation instructs users how to authenticate and retrieve precise pet location and history data, but it provides no guidance on protecting credentials, bearer tokens, or sensitive GPS information. In the context of a tracking skill, this increases the chance that implementers will log tokens, expose screenshots or history to unintended recipients, or mishandle highly sensitive location data tied to a household.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script sends precise pet GPS coordinates to the Google Maps Static API to render a map image, but it provides no user-facing disclosure, consent check, or privacy control before transferring that location data to a third-party service. Because this skill handles sensitive real-world location information, that silent external sharing creates a meaningful privacy and data-handling risk, especially in an agent context where users may not realize a map screenshot requires disclosure of coordinates to Google.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The script prints live pet telemetry, including device identifiers and precise location data, directly to stdout as NDJSON. In agent workflows, stdout is commonly logged, persisted, or forwarded, so this can unintentionally disclose sensitive real-time location information without explicit user confirmation or data-handling safeguards.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The request headers hard-code Accept-Language to en-GB,en-US;q=0.9,en;q=0.8, which imposes a specific language/locale preference in outbound API calls. This is a natural-language policy concern because the skill does not offer any user choice or documented opt-in for locale selection.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The request headers hard-code "Accept-Language: en-GB,en-US;q=0.9,en;q=0.8", which imposes a specific language/locale preference. Under the policy, locale constraints should be optional, user-selectable, or clearly justified as region-specific; none of those conditions are present here.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The dependency is specified as aiohttp>=3.8, which allows installation of any future version and does not guarantee reproducible or reviewed builds. This creates supply-chain risk because vulnerable or breaking releases could be pulled in implicitly, and it is impossible to verify from the manifest whether a safe version is consistently used.

Content

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

text
aiohttp>=3.8

Unverifiable Dependency: aiohttp has 16 known advisory(ies) (CVE-2024-52303 (aiohttp has a memory leak when middleware is enabled when requesting a resource ); CVE-2026-54279 (aiohttp: Host-Only Cookies Become Domain Cookies After CookieJar Persistence); CVE-2026-34514 (AIOHTTP has CRLF injection through multipart part content type header constructi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The manifest references aiohttp without pinning to a specific version, while the package has multiple known advisories. In a network-facing skill that tracks pet location and likely performs authenticated API calls and image retrieval, using an unpinned version means a vulnerable release could be installed, potentially exposing request handling, cookies, or headers to known flaws.

Content

No source excerpt is available for this finding.