T09 · Insecure Skill Coding Practices
- Location
SKILL.md:242- Finding
OAuth Refresh Token Persisted in Agent Long-Term Memory
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This grocery skill is mostly purpose-aligned, but it handles long-lived account tokens in ways that need careful review before installation.
Review before installing. Use this only if you are comfortable with a hosted proxy handling Kroger OAuth tokens and with the agent potentially retaining a Kroger refresh token across sessions. Prefer not saving refresh tokens in agent memory; use a secure keychain or self-host with fixed OAuth scopes, atomic token claiming, rate limits on token polling, present Firestore deny-all rules, and a clear logout/revocation path.
SKILL.md:242OAuth Refresh Token Persisted in Agent Long-Term Memory
internal/secrets/store.go:24File-Keyring Fallback Encrypts OAuth Tokens with a Hardcoded Password
firebase/functions/src/authorize.ts:43Public OAuth Authorization Endpoint Allows Caller-Controlled Scopes
firebase/functions/src/tokenUser.ts:13OAuth Tokens Can Be Stolen Through an Unbound Session Identifier
firebase/firebase.json:2Firestore Security Rules Referenced by Deployment and Documentation Are Missing
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- Kong CLI with subcommands: auth, products, locations, cart, identity
- Two auth modes: client_credentials (search) and authorization_code (cart/identity)
- Tokens stored in OS keyring via 99designs/keyring
- Credentials in `~/.config/krocli/credentials.json`
- Output: `-j` JSON, `-p` plain/TSV, default human-friendly to stderr
## OpenClaw Skill
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- Kong CLI with subcommands: auth, products, locations, cart, identity
- Two auth modes: client_credentials (search) and authorization_code (cart/identity)
- Tokens stored in OS keyring via 99designs/keyring
- Credentials in `~/.config/krocli/credentials.json`
- Output: `-j` JSON, `-p` plain/TSV, default human-friendly to stderr
## OpenClaw Skill
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- Kong CLI with subcommands: auth, products, locations, cart, identity
- Two auth modes: client_credentials (search) and authorization_code (cart/identity)
- Tokens stored in OS keyring via 99designs/keyring
- Credentials in `~/.config/krocli/credentials.json`
- Output: `-j` JSON, `-p` plain/TSV, default human-friendly to stderr
## OpenClaw Skill
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- Kong CLI with subcommands: auth, products, locations, cart, identity
- Two auth modes: client_credentials (search) and authorization_code (cart/identity)
- Tokens stored in OS keyring via 99designs/keyring
- Credentials in `~/.config/krocli/credentials.json`
- Output: `-j` JSON, `-p` plain/TSV, default human-friendly to stderr
## OpenClaw Skill
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- Kong CLI with subcommands: auth, products, locations, cart, identity
- Two auth modes: client_credentials (search) and authorization_code (cart/identity)
- Tokens stored in OS keyring via 99designs/keyring
- Credentials in `~/.config/krocli/credentials.json`
- Output: `-j` JSON, `-p` plain/TSV, default human-friendly to stderr
## OpenClaw Skill
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
- Kong CLI with subcommands: auth, products, locations, cart, identity
- Two auth modes: client_credentials (search) and authorization_code (cart/identity)
- Tokens stored in OS keyring via 99designs/keyring
- Credentials in `~/.config/krocli/credentials.json`
- Output: `-j` JSON, `-p` plain/TSV, default human-friendly to stderr
## OpenClaw Skill
The declared description promises end-user grocery shopping capabilities across Kroger-family stores. However, the supplied code chunk does not implement or expose any product search, store lookup, cart, or profile logic. Instead, it initializes Firebase and exports endpoints whose names strongly indicate OAuth or token management. While auth can be a supporting detail, this code chunk's actual visible purpose is authentication infrastructure, which is materially different from the declared user-facing grocery functionality. Therefore, the description does not accurately represent this code chunk.
The declared description focuses on grocery shopping features such as product search, store lookup, cart management, and profile access. The supplied code does none of those things. Instead, it provides backend abuse-prevention logic for throttling requests based on IP and action within a time window. While rate limiting could be a supporting implementation detail somewhere in a larger grocery app, this specific code chunk’s behavior is not represented by the declared purpose and has a materially different primary function. Therefore, this is a clear description-behavior mismatch.
This code chunk does not implement the user-facing grocery capabilities described. Its primary function is to obtain and return an OAuth token from Kroger's API using stored client secrets. While this may support product search indirectly, the actual behavior is an authentication/token service, not searching products, finding stores, adding to cart, or viewing profiles across Kroger-family stores. The declared description materially overstates and misrepresents what this specific code does.
This code does not implement grocery shopping features such as product search, location lookup, cart actions, or profile access. Its primary purpose is token retrieval: given a session_id, it checks a Firestore sessions collection for a completed session, returns access and refresh tokens, and deletes the session record afterward. That is a materially different function from the declared grocery assistant behavior. While token handling could theoretically support account login, the declared description does not disclose that this endpoint directly returns authentication credentials or performs backend session/token exchange logic. Therefore the description does not accurately represent the supplied code chunk.
The declared description focuses on end-user grocery shopping actions such as product search, store lookup, cart management, and profile access across Kroger brands. The provided code does not implement those shopping capabilities. Instead, it provides authentication and configuration plumbing for a CLI tool, including OAuth login flow support, token status reporting, credential import, local config storage, Telegram messaging, and browser launching. While auth could be a supporting component for a grocery skill, this chunk introduces undeclared capabilities and a materially different immediate purpose than the declared shopping functionality.
The code does not implement or test grocery search, store lookup, cart management, pricing, or profile viewing. Instead, it focuses on auth setup and outbound Telegram notification of a login URL. That is a materially different purpose from the declared grocery-shopping assistant. The Telegram/OpenClaw integration and credential storage are undeclared capabilities and are unrelated to the stated triggers like grocery search or add-to-cart.
The declared description presents a multi-function grocery shopping skill covering product search, store locations, cart management, and profile access across Kroger-family stores. The supplied code chunk is much narrower: it is exclusively about locations metadata and discovery. It searches stores near a zip code, fetches a store by ID, lists chains, and lists departments. There is no evidence here of product lookup, cart modification, or profile retrieval/login flows. While store-location functionality is consistent with part of the description, the overall declared purpose materially overstates what this code actually does, and the code also includes chain/department listing features that are not explicitly described. Therefore this chunk does not accurately match the full declared behavior.
This code does not implement the declared grocery-shopping functionality. Its primary purpose is configuration and secret management on the local filesystem plus optional Telegram/OpenClaw integration. The Telegram/OpenClaw behavior is an undeclared capability unrelated to the user-facing description, and the absence of any product, store, cart, or profile operations makes the actual behavior materially different from the declared purpose. Therefore this is a clear description-behavior mismatch.
The code does not implement or test grocery product search, store lookup, cart management, or profile access across Kroger-family stores. Instead, it focuses on config persistence for credentials and Telegram/OpenClaw integration, using local files and environment variables. That is a materially different purpose from the declared grocery-shopping functionality, so this is a clear description-behavior mismatch.
Yes, this is a clear mismatch. The declared description promises a user-facing grocery shopping integration with brand-specific commerce features, but the supplied code chunk contains only generic formatting utilities for printing JSON or tabular text. It does not interact with Kroger-family stores, perform searches, access user data, manage carts, or call any external services. This is not a supporting implementation detail for the declared behavior in any meaningful way by itself; its actual purpose is generic CLI/output formatting, which is materially different from the declared skill purpose.
The declared description describes a consumer grocery/shopping skill integrated with Kroger-family stores. However, the actual code chunk contains only unit tests for formatting output, specifically validating JSON output and tab-separated plain-text output written to stdout. There is no evidence of any grocery APIs, store-brand integrations, product search, cart operations, user profile access, or location services. This is a clear description-behavior mismatch because the code’s primary purpose is unrelated to the declared shopping functionality.
The declared description is about grocery shopping functionality for Kroger-family stores, including product search, store lookup, cart management, and profile access. The supplied code does none of those things. Its sole purpose is to post messages to Telegram using a bot token and chat ID. This is a materially different primary purpose and accesses an unrelated external service (Telegram) rather than Kroger-family store systems. Therefore, the description does not accurately represent the code's behavior.
This is a clear mismatch. The declared description says the skill supports grocery shopping tasks for Kroger-family stores, including product search, store locations, cart actions, and profile access. The supplied code chunk instead contains unit tests for a Telegram SendMessage function that posts messages to an API using a bot token and chat ID. There is no evidence of Kroger, grocery products, store locations, carts, profiles, or any supermarket-related behavior. The primary purpose and accessed service are materially different from the declared purpose.
The declared description promises a consumer-facing grocery shopping skill for Kroger-family stores. However, the supplied code chunk contains only terminal UI helper functions for colored stderr output using termenv. It does not interact with Kroger services, search products, find stores, manage carts, or access user profiles. This is a materially different primary purpose, so the description does not accurately represent the code shown.
Referenced artifact was not completely inspected
epository](https://github.com/BLANXLAIT/krocli). You can audit every function: `authorize.ts`, `callback.ts`, `tokenClient.ts`, `tokenUser.ts`, `tokenRefresh.ts
Referenced artifact was not completely inspected
epository](https://github.com/BLANXLAIT/krocli). You can audit every function: `authorize.ts`, `callback.ts`, `tokenClient.ts`, `tokenUser.ts`, `tokenRefresh.ts
The skill directs long-term persistence of a refresh token without a clear, explicit warning to the user that a reusable account credential will be retained across sessions. Users may reasonably expect a one-time login for convenience, not indefinite secret storage that can silently enable future account access.
Persisting a user's refresh token across sessions gives the skill durable delegated access to the user's Kroger account, enabling silent reauthentication later. This creates a substantial blast radius if the token is disclosed, misbound to another user/session, or retained after the user no longer expects access.
@grpc/grpc-js is a runtime transport dependency in the Firebase/Google Cloud stack, and the advisories describe malformed network messages causing crashes in server/client handling. In a cloud function or backend context, denial of service against RPC paths can materially affect availability even if the dependency is only transitive.
Detected: suspicious.exposed_secret_literal