Back to skill

Security audit

gcal-oauth-bridge

Security checks for vulnerabilities and agentic risk

Overview

This skill is for a real calendar-bridge workflow, but it asks users to run unpinned external code persistently with Google Calendar credentials and leaves local calendar access under-scoped.

Review before installing. Only use this if you trust and pin the external repository revision, understand the npm dependency risk, require a strong CALENDAR_BRIDGE_API_KEY, keep the service bound to localhost, and know how to disable the systemd user service and revoke Google OAuth access.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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
Findings (3)

T06 · System Persistence

Error
Location
SKILL.md:125
Finding
Persistent Calendar Bridge User Service<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 125-130 **Vulnerability Type**: Cross-session user service persistence **Risk Level**: High ### Vulnerable Code ```bash ### 5. Keep it running (systemd) ```bash systemctl --user enable calendar-bridge.service systemctl --user start calendar-bridge.service ``` ``` ### Technical Analysis The Skill explicitly directs the user to enable an externally obtained application as a systemd user service. The `enable` operation configures the service to start automatically in future user sessions, extending execution beyond the current Skill invocation. The installed service handles persistent Google OAuth tokens and private calendar information. Because the service implementation is retrieved separately and is not included in the audited artifact, its behavior cannot be independently verified from this package. Persistent execution amplifies the consequences of an upstream repository, dependency, or local installation compromise. ### Attack Path 1. A user follows the Skill instructions and downloads the external Calendar Bridge repository. 2. The user installs its dependencies and grants it Google Calendar OAuth access. 3. Refresh tokens are stored locally for long-term access. 4. The user enables `calendar-bridge.service` through systemd. 5. The downloaded application starts automatically in later user sessions. 6. If the application, its dependencies, or its service file is malicious or subsequently modified, attacker-controlled code executes persistently with the user's privileges and can access available calendar credentials and data. ### Impact Assessment Successful exploitation provides recurring code execution under the affected operating-system user account. The executable service may access files and environment variables available to that user, including Calendar Bridge configuration, Google client credentials, OAuth refresh tokens, and returned calendar data. This does not demons ...[truncated 216 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove the automatic `systemctl --user enable` instruction. - Run the bridge only on demand and stop it after the requested calendar operation. - If persistence is genuinely required, obtain explicit informed user approval before enabling it. - Pin the service implementation to a reviewed commit and provide a reviewed service-unit file. - Configure systemd sandboxing controls such as `NoNewPrivileges=true`, `PrivateTmp=true`, `ProtectSystem=strict`, and narrowly scoped `ReadWritePaths`. - Run the service under a dedicated, minimally privileged account where practical. - Document procedures to disable and remove the service, revoke OAuth access, and delete locally retained tokens. ]]>

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:84
Finding
Execution of Mutable External Source and Unverified npm Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 84-95 **Vulnerability Type**: Remote payload retrieval and insecure software supply chain **Risk Level**: High ### Vulnerable Code ```bash ### 1. Clone and install ```bash git clone https://github.com/DanielKillenberger/gcal-oauth-bridge.git cd gcal-oauth-bridge npm install cp .env.example .env # Edit .env with GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET ``` ``` The downloaded application is subsequently executed as follows: ```bash node app.js # or: npm start ``` ### Technical Analysis The instructions clone the mutable default branch of an external Git repository, install its npm dependency graph, and execute the resulting application. No reviewed commit, release tag, checksum, signature, lockfile enforcement, or source-verification procedure is specified. This creates two related risks: 1. The effective application payload may change after the Skill itself has been reviewed because `git clone` retrieves current upstream content. 2. `npm install` may execute package lifecycle scripts and install transitive dependencies whose integrity and behavior are not established by this artifact. The application is then configured with Google OAuth client credentials and receives access to locally retained OAuth tokens. Consequently, a compromised upstream repository or npm dependency could execute code in a security-sensitive context. The source code and dependency manifests of the referenced application are absent from the audited package, so claims that tokens remain local cannot be verified through this audit. ### Attack Path 1. An attacker compromises the referenced repository, maintainer account, release process, or an npm dependency. 2. The attacker adds malicious application logic or an installation lifecycle script. 3. A user follows the Skill and clones the repository without pinning a known-good commit. 4. `npm install` executes the compromised dependency installation path or lif ...[truncated 1133 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin the repository to a specific, reviewed commit hash rather than cloning a mutable default branch. - Publish and verify a cryptographic checksum or signature for the approved source revision. - Include a committed dependency lockfile and use `npm ci` rather than an unconstrained `npm install`. - Review package lifecycle scripts and use `npm ci --ignore-scripts` where application requirements permit. - Audit direct and transitive dependencies for known vulnerabilities and suspicious package ownership changes. - Vendor the reviewed implementation into the audited artifact when feasible. - Execute the service in a restricted account or sandbox with minimal filesystem and network access. - Do not provide OAuth credentials until source and dependency integrity checks have completed successfully. - Establish a controlled upgrade process in which new revisions are reviewed and re-pinned before deployment. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:68
Finding
Calendar Data API Permits Unauthenticated Local Access by Default<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 68-80 **Vulnerability Type**: Missing mandatory authentication for a sensitive local API **Risk Level**: Medium ### Vulnerable Code ```bash # Quick event check (7 days, primary calendar) curl http://localhost:3000/events # All calendars, next 14 days curl http://localhost:3000/events?days=14&calendar=all # With API key (if CALENDAR_BRIDGE_API_KEY is configured) curl -H "Authorization: Bearer $API_KEY" http://localhost:3000/events?calendar=all ``` ```text To call from OpenClaw/skill context (no API key needed when running on same host): GET http://localhost:3000/events?calendar=all&days=7 ``` ### Technical Analysis The documentation treats `CALENDAR_BRIDGE_API_KEY` as optional and explicitly recommends unauthenticated access when the caller is on the same host. The `/events` endpoint returns sensitive calendar information, including event summaries, descriptions, locations, links, and calendar identifiers. Binding a service to loopback reduces direct remote exposure but is not an authentication boundary. Other processes operating under the same host, other local users where socket access is unrestricted, compromised applications, browser-mediated requests, containers sharing host networking, or an accidentally configured reverse proxy may be able to reach the service. The documented API also includes calendar-listing and OAuth-related endpoints. Although the available artifact does not contain the server implementation needed to verify each endpoint's authorization behavior, the documented unauthenticated `/events` access is sufficient to expose private calendar data to unauthorized local callers. ### Attack Path 1. The Calendar Bridge runs on port 3000 without `CALENDAR_BRIDGE_API_KEY`. 2. The service has already received Google Calendar authorization and has valid tokens. 3. An untrusted local process, user, container, browser-originated request, or accidentally exposed proxy r ...[truncated 959 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Require a strong, randomly generated API key for every endpoint that exposes calendar or OAuth state. - Reject startup when no authentication secret is configured, except in an explicit development mode. - Bind strictly to the loopback interface and verify that container or proxy configuration does not expose the port externally. - Store the API key in a protected secret store or environment file readable only by the service account. - Apply constant-time token comparison and return uniform authentication failures. - Implement endpoint-level authorization, request logging, rate limiting, and secret rotation. - Consider Unix-domain sockets with restrictive filesystem permissions instead of an unauthenticated TCP listener. - Protect browser-accessible endpoints against cross-origin abuse and DNS-rebinding-style access. - Update all examples to include authentication and remove the assertion that same-host callers do not need an API key. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • 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
Findings (5)

Credential Access

High
Category
Privilege Escalation
Content
git clone https://github.com/DanielKillenberger/gcal-oauth-bridge.git
cd gcal-oauth-bridge
npm install
cp .env.example .env
# Edit .env with GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET
```
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
git clone https://github.com/DanielKillenberger/gcal-oauth-bridge.git
cd gcal-oauth-bridge
npm install
cp .env.example .env
# Edit .env with GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET
```
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Session Persistence

Medium
Category
Rogue Agent
Content
### 5. Keep it running (systemd)
```bash
systemctl --user enable calendar-bridge.service
systemctl --user start calendar-bridge.service
```
Confidence
80% 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.

Vague Triggers

Low
Confidence
95% confidence
Finding
The standalone trigger "google calendar" is extremely broad and can appear in ordinary conversation, general product questions, or unrelated support requests. Because no contextual constraints are attached, it risks unintended invocation of this specific self-hosted bridge skill.

Vague Triggers

Low
Confidence
84% confidence
Finding
The triggers "set up calendar", "calendar auth", and "calendar access" are generic and could match many unrelated calendar configuration tasks, not specifically this local Calendar Bridge service. The file does not provide exclusion conditions or tighter scoping to distinguish when this skill should activate versus other calendar or setup workflows.

Static analysis

No suspicious patterns detected.