Back to skill

Security audit

Tripit Calendar

Security checks for vulnerabilities and agentic risk

Overview

This TripIt skill has a coherent travel-calendar purpose, but it fetches an unvalidated private feed URL and may expose sensitive itinerary or feed-token data in ways users should review before installing.

Install only if you are comfortable giving the skill access to a private TripIt iCal URL and itinerary data. Prefer setting TRIPIT_ICAL_URL in a controlled environment, avoid running it from directories with unrelated .env files, use an HTTPS TripIt feed URL only, and consider pinning dependencies and redacting feed URLs from errors before routine use.

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

T09 · Insecure Skill Coding Practices

Warning
Location
final_tripit_ical.py:87
Finding
Unrestricted Feed URL Enables Server-Side Request Forgery and Insecure Transport## Vulnerability Details **File Location**: `final_tripit_ical.py`, lines 87–104 **Vulnerability Type**: Unrestricted outbound request destination **Risk Level**: Medium **Vulnerable Code**: ```python def get_feed_url(cli_url: Optional[str]) -> str: if cli_url and cli_url.strip(): return cli_url.strip() env_url = get_env_value("TRIPIT_ICAL_URL") if env_url: return env_url raise ValueError( "Missing TripIt iCal URL. Pass it as an argument or set TRIPIT_ICAL_URL in the environment or ~/.openclaw/.env." ) def fetch_ics(url: str) -> str: response = requests.get( url, headers={"User-Agent": "TripIt-iCal-Skill/1.1"}, timeout=30, ) response.raise_for_status() return response.text ``` ### Technical Analysis The script accepts a URL from either its first command-line argument or an environment configuration without validating its scheme, hostname, resolved IP address, port, or path. Although the Skill is declared to retrieve a private TripIt iCalendar feed, the implementation can issue an HTTP request to any destination accepted by `requests`. This creates a server-side request forgery condition when an attacker can influence the argument or `TRIPIT_ICAL_URL`. Potential destinations include loopback interfaces, private network services, link-local addresses, and cloud instance metadata endpoints. In addition, `requests` follows redirects by default, so an initially acceptable destination could redirect to a restricted address unless every redirect target is revalidated. Plain HTTP URLs are also accepted. A private TripIt feed URL acts as a bearer credential and the feed contains sensitive itinerary information; using cleartext transport can expose both to interception or modification. ### Attack Path 1. An attacker influences the command-line feed argument, environment variable, or an accepted `.env` file. 2. The atta ...[truncated 1186 chars]
Remediation
## Remediation Suggestions - Require the `https` scheme and reject URLs containing unsupported schemes, embedded user information, or unexpected ports. - Allowlist the official TripIt feed hostnames and expected path structure if this Skill is intended exclusively for TripIt. - Resolve the hostname and reject loopback, private, link-local, multicast, reserved, and unspecified addresses for both IPv4 and IPv6. - Disable redirects with `allow_redirects=False`, or manually follow redirects while applying the same scheme, hostname, and resolved-address validation to every destination. - Consider binding the configured URL through trusted OpenClaw configuration rather than accepting an arbitrary positional argument. - Apply an appropriate response-size limit before parsing the calendar.

T09 · Insecure Skill Coding Practices

Warning
Location
final_tripit_ical.py:367
Finding
HTTP Error Output May Disclose the Private TripIt Feed URL## Vulnerability Details **File Location**: `final_tripit_ical.py`, lines 367–368 **Vulnerability Type**: Credential-bearing URL disclosure through error handling **Risk Level**: Medium **Vulnerable Code**: ```python except requests.HTTPError as e: return fail(f"HTTP error while fetching TripIt iCal feed: {e}", 2, pretty) ``` ### Technical Analysis A private TripIt iCalendar URL functions as a bearer secret: possession of the complete URL may be sufficient to retrieve the user's itinerary. The string representation of a `requests.HTTPError` commonly contains the request method, status, and requested URL. The exception is interpolated directly into an error message and printed either as JSON or terminal output. If the URL is present in the exception, its credential-bearing path or query data may therefore enter Agent output, execution logs, observability systems, terminal history, or conversation context. ### Attack Path 1. The Skill requests the configured private TripIt URL. 2. The remote server, proxy, or redirect destination returns an HTTP error status. 3. `response.raise_for_status()` raises `requests.HTTPError`. 4. The handler converts the complete exception to text without redaction. 5. The resulting error is printed and may be retained in logs or exposed to users and systems that can view Agent output. 6. A party that obtains the complete URL may use it to retrieve the private calendar feed while the URL remains valid. ### Impact Assessment Disclosure of the private feed URL may grant unauthorized read access to travel dates, flight or train details, hotels, locations, booking notes, and other itinerary content available in the feed. The scope is limited to data authorized by that feed URL, but exposure may continue until the private URL is revoked or regenerated.
Remediation
## Remediation Suggestions - Do not include the raw `HTTPError` string in user-facing or logged output. - Report only a generic error and the numeric HTTP status, for example: `TripIt feed returned HTTP 403`. - Never log the request URL for a private calendar feed. - If diagnostic URLs are operationally necessary, redact query strings, fragments, user information, and credential-bearing path segments. - Add automated tests confirming that configured secrets cannot appear in any HTTP, redirect, timeout, or parsing error message. - Advise users to rotate the private TripIt URL if it has already appeared in logs.

T09 · Insecure Skill Coding Practices

Note
Location
final_tripit_ical.py:13
Finding
Undocumented Working-Directory Environment File Access Exceeds Required Scope## Vulnerability Details **File Location**: `final_tripit_ical.py`, lines 13–16 and 68–79 **Vulnerability Type**: Excessive configuration-file access and configuration precedence weakness **Risk Level**: Low **Vulnerable Code**: ```python ENV_CANDIDATES = [ Path.cwd() / ".env", Path.home() / ".openclaw" / ".env", ] ``` ```python def get_env_value(key: str) -> str: value = os.getenv(key, "").strip() if value: return value for env_path in ENV_CANDIDATES: file_values = read_env_file(env_path) value = file_values.get(key, "").strip() if value: return value return "" ``` ### Technical Analysis The documentation states that the script falls back to `~/.openclaw/.env`, but the implementation first reads `.env` from the current working directory. This extra file access is not required by the declared functionality and broadens the Skill's credential-related access beyond its documented scope. `read_env_file()` parses every assignment in the selected file into a dictionary, even though only `TRIPIT_ICAL_URL` is needed. The implementation does not transmit unrelated entries, so there is no evidence that it intentionally steals other credentials. Nevertheless, reading a generic project `.env` unnecessarily exposes unrelated secrets to the process and increases the consequences of future logging, debugging, or code changes. The current-directory file also has precedence over `~/.openclaw/.env`. If execution occurs in an attacker-controlled or unexpected directory, a local `.env` can silently replace the intended TripIt destination. ### Attack Path 1. `TRIPIT_ICAL_URL` is absent from the process environment. 2. The Skill is invoked from a directory containing an attacker-created or unintended `.env` file. 3. The file defines `TRIPIT_ICAL_URL` with an attacker-selected URL. 4. `get_env_value()` reads the working-directory file before the ...[truncated 658 chars]
Remediation
## Remediation Suggestions - Remove `Path.cwd() / ".env"` from `ENV_CANDIDATES`. - Prefer the process environment supplied by OpenClaw and, if a fallback remains necessary, access only the documented `~/.openclaw/.env` path. - Parse only the `TRIPIT_ICAL_URL` entry rather than storing every entry from a generic credential file. - Validate ownership and restrictive permissions before reading the fallback file. - Document all configuration paths and their precedence. - Combine this change with strict feed URL validation so a modified configuration file cannot select an arbitrary network destination.

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding
Third-Party Dependencies Are Unpinned and Installation Is Not Reproducible## Vulnerability Details **File Location**: `requirements.txt`, lines 1–2 **Vulnerability Type**: Unpinned third-party dependencies **Risk Level**: Low **Vulnerable Code**: ```text requests icalendar ``` ### Technical Analysis The dependency declarations do not specify reviewed versions or cryptographic hashes. Each installation can therefore resolve to different package releases depending on installation time and package index state. The package names match the modules imported by the script, and the audit found no evidence of typographical package names, dependency confusion, or an intentionally malicious package source. The risk is nevertheless that a future vulnerable, incompatible, or compromised release could be selected automatically without a corresponding change to the audited project. ### Attack Path 1. An operator installs the project dependencies using the unpinned requirements file. 2. The package resolver selects the releases available from the configured package index at that time. 3. A newly vulnerable or compromised release is installed without requiring any repository modification. 4. The dependency executes in the Skill's Python process when imported or when processing attacker-influenced calendar or network data. ### Impact Assessment A compromised dependency would execute with the same operating-system permissions, file access, environment access, and network access as the Skill process. This could expose the private TripIt URL and itinerary data. There is no evidence that the currently named packages are malicious; this finding concerns preventable supply-chain and reproducibility exposure.
Remediation
## Remediation Suggestions - Pin both dependencies to reviewed, compatible versions. - Generate a lock file containing the complete transitive dependency graph. - Use cryptographic hashes with hash-required installation mode where practical. - Install only from trusted package indexes over authenticated HTTPS. - Add automated dependency vulnerability and update monitoring. - Review and deliberately update pinned versions on a controlled schedule rather than resolving unrestricted latest releases during deployment.
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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (11)

Credential Access

High
Category
Privilege Escalation
Content
ENV_CANDIDATES = [
    Path.cwd() / ".env",
    Path.home() / ".openclaw" / ".env",
]
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
ENV_CANDIDATES = [
    Path.cwd() / ".env",
    Path.home() / ".openclaw" / ".env",
]
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill invokes Python code that uses environment variables, reads local files, and makes network requests, but the manifest does not declare any explicit tool scope or permissions boundaries. This weakens auditability and least-privilege enforcement, increasing the chance that the skill could access sensitive local configuration or exfiltrate data if the implementation changes or is abused.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
This code performs an HTTP request to fetch the user's TripIt iCal URL, which can expose travel itinerary data over the network, but there is no confirmation prompt, comment/docstring, or user-facing disclosure explaining that the skill will contact a remote service using a potentially sensitive personal feed URL. The surrounding code prints results and errors, but it does not warn about the privacy-sensitive network access itself.

Context-Inappropriate Capability

Low
Confidence
83% confidence
Finding
The documentation explicitly instructs the skill to fall back to reading ~/.openclaw/.env directly to obtain TRIPIT_ICAL_URL, which normalizes local secret-file access from within the skill. Even though the stated purpose is itinerary retrieval, reading env files broadens access to potentially unrelated secrets in the same file and creates unnecessary exposure of credential-like configuration.

Context-Inappropriate Capability

Low
Confidence
86% confidence
Finding
The manifest describes a skill for reading upcoming TripIt travel plans from an iCal feed, which justifies fetching and parsing the feed itself. However, this code also probes process environment variables and local configuration files, including ~/.openclaw/.env, to retrieve the URL, which is an additional local data access capability not mentioned in the stated purpose.

Missing User Warnings

Low
Confidence
83% confidence
Finding
The code reads TRIPIT_ICAL_URL from environment variables and local .env files, which may contain a private calendar feed URL tied to the user's account. There is no in-code warning, comment, or prompt informing the user that the skill will read credential-like configuration from environment or dotfiles.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests
icalendar
Confidence
97% confidence
Finding
The dependency `requests` is unpinned, which makes builds non-reproducible and can silently pull in a vulnerable or breaking version over time. In a skill that fetches remote TripIt iCal data, network-facing libraries are part of the trust boundary, so leaving the version unspecified increases supply-chain and reliability risk.

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +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
93% confidence
Finding
`requests` has known advisories, and because no version is pinned, there is no way to verify whether the deployed package is affected. This is more concerning in this skill because `requests` will likely retrieve remote calendar data, so flaws involving credential handling, TLS/session behavior, or URL parsing could affect confidentiality or integrity of travel data.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests
icalendar
Confidence
96% confidence
Finding
The dependency `icalendar` is also unpinned, so installations may resolve to different versions with different security properties. Because this skill parses untrusted calendar feed content, parser behavior matters, and failing to pin increases exposure to newly introduced or unresolved parser vulnerabilities.

Unverifiable Dependency: icalendar has 2 known advisory(ies) (CVE-2026-55099 (icalendar has Algorithmic Complexity in Equality); CVE-2026-55099 (icalendar has Algorithmic Complexity in Equality)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding
`icalendar` has known advisories, and without a pinned version the manifest cannot demonstrate that a safe release is used. Since this skill consumes external iCal content, parser-level issues such as algorithmic complexity bugs could allow denial of service through crafted calendar data.

Static analysis

No suspicious patterns detected.