Back to skill

Security audit

google-autoreply

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its onboarding purpose, but it should be reviewed because it exposes long-lived account tokens through URLs and persistent storage while controlling business-account setup.

Review this skill before installing. It is not evidence of malware, but it asks an agent to handle a long-lived product session, connect or disconnect a Google Business Profile, configure automated public review replies, and create Stripe checkout sessions. Only use it if you trust the service and can avoid sharing token-bearing URLs or pasted callback values; confirm the exact business profile, auto-reply settings, and any paid plan before proceeding.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:28
Finding
Bearer session tokens are exposed through query strings, redirects, and user copy/paste<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 28, 59, 68–71, and 91 **Vulnerability Type**: Bearer credential exposure through URLs and prompts **Risk Level**: High ### Vulnerable Code Snippets `SKILL.md:28` ```text Connect Google Business = {API_BASE_URL}/oauth2/connectGoogleBusiness?token=<url-encoded-token>&redirectState=<url-encoded-return-url> ``` `SKILL.md:59` ```text 3. The callback carries `?token=<token>`; store `Bearer <token>` as the session token (in web: `localStorage`; in app: uni storage under key `token`). ``` `SKILL.md:68–71` ```text 2. Give the merchant this URL: `{API_BASE_URL}/oauth2/authorization/google-autoreply?handoffId=<handoffId>` and ask them to complete the sign-in. After login the browser is **redirected back to `returnUrl` with `token` & `tokenHead` appended** (e.g. `returnUrl?token=...&tokenHead=...`). 3. Poll `GET /oauth2/handoff/<handoffId>/token` (every ~2–3s) until `data.status === "READY"`. - `PENDING` → keep polling. - `EXPIRED` → the slot expired / was never opened; create a new handoff and retry, or fall back to asking the merchant to paste the `?token=` value. ``` `SKILL.md:91` ```text {API_BASE_URL}/oauth2/connectGoogleBusiness?token=<url-encoded-token>&redirectState=<url-encoded-return-url> ``` ### Technical Analysis The Skill transports a bearer session credential in OAuth callback URLs, redirect URLs, and the Google Business connection query string. URL encoding changes the representation of the token but does not provide confidentiality. Sensitive query parameters may be retained or disclosed through: - Browser history and synchronized browsing data - Web server, reverse-proxy, CDN, and monitoring logs - Analytics and error-reporting systems - Screenshots, screen sharing, and support records - Clipboard history when a user is asked to paste a token-bearing URL - Browser extensions or local malware with browsing-data access - `Referer` headers, depending on redirect flow an ...[truncated 1980 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace bearer tokens in URLs with short-lived, opaque, single-use authorization codes. 2. Redeem each code through a server-to-server back channel, binding it to: - The intended client and user session - A strict audience - The original redirect URI - A short expiration time - A cryptographically random state or PKCE verifier 3. Never append `token`, `tokenHead`, or an equivalent reusable credential to `returnUrl`. 4. Change the Google Business connection flow so it accepts a one-time connection grant rather than the merchant's login bearer token. 5. Remove the fallback that asks the merchant to paste a token or token-bearing URL. 6. Apply a strict `Referrer-Policy`, such as `no-referrer`, to authentication and callback pages as defense in depth. 7. Redact sensitive query parameters from proxy, CDN, application, analytics, and error-reporting logs. 8. Invalidate all credentials previously exposed by legacy URL-based flows and require affected sessions to authenticate again. 9. Add automated tests that reject authentication URLs containing bearer tokens or equivalent credentials. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:15
Finding
Approximately seven-year session token is persistently stored and broadly reused<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 15–18, 59, and 193 **Vulnerability Type**: Excessive credential lifetime and insecure client-side persistence **Risk Level**: High ### Vulnerable Code Snippets `SKILL.md:15–18` ```text - `AUTH_TOKEN` — the full `Authorization` header value for the login/session token (e.g. `Bearer <token>`). Set once after Step 1 and reused verbatim for **every** backend API call and the next session. Re-authorize only when the API returns `401`. - GMB OAuth client credentials (`client_id`/`client_secret`) are read by the backend from Spring config (`spring.security.oauth2...client-id/secret`), **not** by the agent — no env var needed. - Google Business `access_token`/`refresh_token` are **owned and persisted by the backend** in the shop's `googleBusinessToken` (DB) and auto-refreshed; the agent never stores or forwards these. A once-made GMB connection stays valid. - **Token lifetime (checked)**: login/session JWT is long-lived (`jwt.expiration` ≈ 7 years). GMB `access_token` is short-lived (`expires_in`, typically ~3600s / 1h), `refresh_token` is long-lived — the backend refreshes automatically. ``` `SKILL.md:59` ```text 3. The callback carries `?token=<token>`; store `Bearer <token>` as the session token (in web: `localStorage`; in app: uni storage under key `token`). ``` `SKILL.md:193` ```text - **Token presence**: All calls require `Authorization: Bearer <token>` — reuse the persisted `AUTH_TOKEN` env var for every request. If `401` is returned, the session token expired/absent — re-run Step 1. (Google Business `access_token` is ~1h but the backend auto-refreshes it with the long-lived `refresh_token`; no manual re-authorization is needed for the connection.) ``` ### Technical Analysis The Skill directs the agent to persist a bearer session token, reuse it for every backend request and future sessions, and wait for a `401` before reauthorization. It states that the JWT remains valid for approx ...[truncated 2525 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the approximately seven-year JWT with short-lived access tokens, preferably measured in minutes rather than years. 2. Use rotating refresh tokens with: - Server-side revocation - Reuse detection - Device or client binding where practical - Inactivity expiration - A reasonable absolute session lifetime 3. Store browser session credentials in `Secure`, `HttpOnly`, and appropriately configured `SameSite` cookies rather than `localStorage`. 4. For native applications, use platform-backed secure credential storage rather than generic application storage. 5. For agent environments, use a dedicated secret manager or credential broker instead of a broadly inherited environment variable. 6. Do not expose the full authorization value to child processes, diagnostics, logs, or prompts. 7. Issue scoped or audience-restricted credentials so that onboarding, configuration, and payment-related actions do not automatically share unnecessary privileges. 8. Reauthenticate or require step-up authorization for high-impact actions such as disconnecting or rebinding a Google Business Profile. 9. Implement explicit logout and session-revocation controls, and revoke sessions after suspected exposure. 10. Rotate all existing long-lived tokens after deploying the corrected authentication design. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (2)

Vague Triggers

Medium
Confidence
92% confidence
Finding
The invocation description is broad enough to trigger on generic account setup, membership, or Google Business connection requests, which can cause the agent to enter a high-risk workflow involving authentication, OAuth handoffs, and billing actions without sufficiently specific user intent. In this skill context, over-triggering is more dangerous because the skill can initiate login flows, poll for tokens, connect third-party business accounts, and guide payment-related steps.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill documents flows where tokens may appear in callback or return URLs and even includes a connect URL that places a login token in a query parameter. Without a strong user-facing warning and safer handling requirements, these tokens can leak through browser history, referrer headers, logs, screenshots, or third-party return URLs, leading to account/session compromise.

Static analysis

No suspicious patterns detected.