Back to skill

Security audit

Timemap

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a legitimate Timemap search skill, but its unpinned installer and shared temporary cache handling make it worth reviewing before installation.

Install from a reviewed commit or manual copy rather than the unpinned npx command when possible. Use this skill only if you are comfortable with it fetching public Timemap data and writing a local cache; on shared multi-user systems, avoid running it until the cache is moved to a private per-user directory.

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 (2)

T08 · Insecure Dependencies

Warning
Location
README.md:15
Finding
Unpinned npm Package Execution in Installation Instructions## Vulnerability Details **File Location**: `README.md:15-18` **Vulnerability Type**: Unpinned third-party package execution **Risk Level**: Medium ### Vulnerable Code ```bash npx skills add alexpolonsky/agent-skill-timemap ``` ### Technical Analysis The documented installation procedure invokes the `skills` npm package through `npx` without specifying a reviewed version, integrity hash, or lockfile. When the package is not already available locally, `npx` can retrieve and execute the version currently resolved by the npm registry. The effective installer can therefore change independently of the audited project. Compromise of the package, its publishing account, its transitive dependencies, or the registry resolution process could cause installation-time execution of code that was not included in this audit. This finding concerns the documented installation chain. No malicious npm package or malicious behavior in the audited project itself was established. ### Attack Path 1. An attacker compromises the npm package resolved as `skills`, its maintainer account, or a dependency used during execution. 2. The attacker publishes a malicious version or modifies the package's dependency chain. 3. A user follows the documented unpinned `npx skills add ...` command. 4. `npx` downloads the currently resolved package version. 5. The malicious package executes with the privileges of the user performing the installation. ### Impact Assessment Successful exploitation could provide arbitrary code execution under the installing user's account. The resulting scope could include reading and modifying files accessible to that user, stealing user-level credentials or tokens available to the process, modifying installed agent skills, and performing network operations. The command does not inherently grant administrator privileges. System-wide impact would require the user to run it under an elevated account or for the attacker to ex ...[truncated 50 chars]
Remediation
## Remediation Suggestions - Pin the installer package to a specifically reviewed version instead of allowing registry resolution to select the latest release. - Use a lockfile and verify npm integrity metadata for the installer and its transitive dependencies. - Document the expected package publisher, registry, version, and checksum so users can validate the downloaded artifact. - Prefer installation from a signed release archive or immutable repository commit whose contents can be reviewed before execution. - Avoid advising users to run the installer with `sudo` or another elevated account. - Add dependency monitoring and periodically reassess the pinned installer version for known vulnerabilities.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/timemap.py:19
Finding
Predictable Shared Temporary Cache Allows Cache Poisoning and Symlink File Clobbering## Vulnerability Details **File Location**: `scripts/timemap.py:19, 79-93, 99-103` **Vulnerability Type**: Unsafe predictable temporary file handling **Risk Level**: Medium ### Vulnerable Code ```python CACHE_FILE = os.path.join(tempfile.gettempdir(), "timemap-venues-cache.json") ``` ```python def _read_cache(): """Return cached venues array or None if stale/missing.""" if _force_fresh: return None try: if not os.path.exists(CACHE_FILE): return None age = time.time() - os.path.getmtime(CACHE_FILE) if age > CACHE_TTL: return None with open(CACHE_FILE, "r", encoding="utf-8") as f: data = json.load(f) # Handle both list (old cache) and dict (new cache with {"result": [...]}) if isinstance(data, dict): return data.get("result", []) return data except (json.JSONDecodeError, OSError): return None ``` ```python def _write_cache(venues): """Write venues to cache file.""" try: with open(CACHE_FILE, "w", encoding="utf-8") as f: json.dump(venues, f, ensure_ascii=False) except OSError: pass # best effort ``` ### Technical Analysis The cache uses a fixed, globally predictable filename in the operating system's shared temporary directory. The implementation does not verify that the cache is a regular file owned by the current user, does not reject symbolic links, and does not use exclusive or atomic creation. On a multi-user system, another local user may create the cache pathname before the victim's first execution. A valid and sufficiently recent attacker-created JSON document will be trusted by `_read_cache()` as venue data. This permits local cache poisoning. The write operation uses `open(CACHE_FILE, "w")`, which follows symbolic links and truncates the destination. If an attacker pre-creates th ...[truncated 2063 chars]
Remediation
## Remediation Suggestions - Store cache data in a per-user cache directory, such as the platform-specific user cache location, rather than the shared temporary directory. - Create the cache directory with permissions restricted to the current user, such as mode `0700` on POSIX systems. - Create cache files with mode `0600` and verify that existing files are regular files owned by the current user. - Reject symbolic links using no-follow file-opening semantics where available. - Write data to a securely created temporary file in the same private directory, flush and close it, and atomically replace the cache using `os.replace()`. - Do not perform separate existence and metadata checks followed by an ordinary open, because that leaves time-of-check/time-of-use race windows. - Consider validating the expected top-level schema and field types before trusting cached API records. - If a secure cache cannot be created, disable caching and use the HTTPS API response directly rather than falling back to an unsafe shared file.
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • 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 (4)

Rp1

Medium
Category
MCP Rug Pull
Confidence
85% confidence
Finding
The README instructs users to run `npx skills add alexpolonsky/agent-skill-timemap` without pinning a specific package version. This can cause users to execute whatever version is current at install time, increasing supply-chain risk if the package is later compromised or a breaking/malicious release is published. The skill context slightly increases exposure because installation is the primary user entrypoint and users are likely to copy-paste this command verbatim.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill advertises executable code usage and likely performs network access, local caching, and environment interaction, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates a least-privilege failure: an agent runtime may grant broader capabilities than users or reviewers expect, increasing the chance of unintended file writes, environment access, or network use.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
The markdown states "Search for a venue (Hebrew or English)", and similar wording appears elsewhere, presenting a language limitation as the expected mode of use. While likely practical for this dataset, the file does not explicitly offer user language choice or frame the locale limitation as an opt-in or justified policy constraint.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
The docstring states searches are by name or address in "Hebrew or English," and similar help text repeats this language constraint. This implies a fixed language scope without explicit user opt-in or a broader language-choice mechanism, which fits the locale/language policy check.

Static analysis

No suspicious patterns detected.