T08 · Insecure Dependencies
- Location
references/ad-delivery.md:14- Finding
Unpinned Global Installation of a Privileged Third-Party CLI
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is for running Meta ads and mostly discloses that, but it asks users to share powerful ad-account credentials and install an unpinned global CLI, so it needs Review before use.
Install only if you are comfortable giving an agent and the `lanbow-ads` CLI authority over Meta ad accounts. Use platform secret fields or environment variables, avoid pasting tokens or App Secrets into chat, use short-lived least-privilege tokens where possible, pin and verify the CLI before use, start with a test ad account and small budgets, and revoke or clean up credentials after the session.
references/ad-delivery.md:14Unpinned Global Installation of a Privileged Third-Party CLI
references/meta-account-setup.md:34Insecure Delivery and Command-Line Handling of Meta Credentials
references/meta-account-setup.md:213Non-Expiring Administrative System User Exceeds Least-Privilege Requirements
The skill explicitly instructs the agent to ask users to provide Meta credentials directly if environment variables are not set, including an access token and potentially an app secret. Even though it prefers secret fields first, normalizing direct credential collection in-conversation materially increases the risk of secret disclosure, logging, retention in transcripts, and use in untrusted hosted environments.
2. **Ask the user to provide credentials directly (most common):** If env vars are not set, tell the user exactly how to get each credential from Meta's web interface. **Recommend the user use their platform's secret fields or environment variables rather than pasting credentials directly into chat.** If direct input is the only option, only request the minimum credentials needed for the current task:
- **Access Token:** Open https://developers.facebook.com/tools/explorer/ → select your App → click "Generate Access Token" → select permissions `ads_management`, `ads_read`, `business_management` → click "Submit" → copy the token
- **App ID:** Go to https://developers.facebook.com/apps/ → select your App → App Settings → Basic
- **Ad Account ID:** Go to https://adsmanager.facebook.com/ → find `act_XXXXXXXXX` in the URL or account dropdown
- **App Secret (only if needed for token exchange):** App Settings → Basic → click "Show" next to App Secret
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
The agent is restricted to the following credential operations **only**:
- `lanbow-ads config set --app-id` / `--app-secret` / `--account` — configure CLI
- `lanbow-ads auth set-token` — set access token
- `lanbow-ads auth exchange` — exchange short-lived token for long-lived token
- `lanbow-ads auth status` — verify token validity
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
The agent is restricted to the following credential operations **only**:
- `lanbow-ads config set --app-id` / `--app-secret` / `--account` — configure CLI
- `lanbow-ads auth set-token` — set access token
- `lanbow-ads auth exchange` — exchange short-lived token for long-lived token
- `lanbow-ads auth status` — verify token validity
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
All sub-skill instructions and reference materials are self-contained in `references/`.
### Feature 1: Strategy Research
- **[strategy-research.md](references/strategy-research.md)** — Full strategy research system, research protocol, chapter-based output rules
- **[strategy-template.md](references/strategy-template.md)** — Report section structure (Executive Summary → Controls)
- **[strategy-meta-only-template.md](references/strategy-meta-only-template.md)** — Meta-only campaign strategy template
- **[strategy-document-standards.md](references/strategy-document-standards.md)** — Report formatting standards, table numbering, data source annotations
This section explicitly tells the agent to ask the user for an Access Token, App ID, and Ad Account ID directly, which is credential collection behavior. In context, this is more dangerous because the skill is operational and can immediately use the supplied token to manage live Meta ad accounts, creating risk of account compromise, unauthorized spend, and sensitive token exposure in conversation history or logs.
[ -n "$META_APP_SECRET" ] && lanbow-ads config set --app-secret "$META_APP_SECRET"
2. **User provides credentials directly:** Ask the user for their Access Token, App ID, and Ad Account ID (minimum needed). Only request App Secret if the user needs token exchange. Recommend the user provide credentials via env vars or platform secret fields rather than pasting into chat. The user gets tokens from Meta's web interface (Graph API Explorer or Business Settings).
3. **`lanbow-ads auth login` (rarely works):** This opens a local browser for OAuth. It only works when you and the user are on the **same machine**. Do NOT attempt this by default — if the user can't open the auth URL, it means you're on different machines. Fall back to method 2 immediately instead of sending auth URLs the user cannot use.
Documenting a global --access-token flag encourages passing secrets on the command line, where they may be exposed through shell history, process listings, job logs, or audit trails. Although this is a common CLI pattern, in a hosted agent setting it materially increases the risk of credential leakage compared with using preconfigured secure storage.
| `--format <format>` | Output format: `table` or `json` |
| `--verbose` | Enable verbose logging |
| `--account <id>` | Ad account ID or alias (overrides default) |
| `--access-token <token>` | Access token (overrides stored token) |
Default account is auto-injected when configured via `lanbow-ads config set --account act_XXXXX`.
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
Text-only (no product image):
curl -s "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent" \
-H "x-goog-api-key: ${GEMINI_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
Without product image:
curl -s "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-flash-image-preview:generateContent" \
-H "x-goog-api-key: ${GEMINI_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
| Path | Token Type | Validity | Best For |
|------|-----------|----------|----------|
| **Quick Start (recommended for new users)** | User Access Token via OAuth | ~1-2 hours (short-lived) or ~60 days (long-lived) | Get ads running fast, minimal setup |
| **Production Setup** | System User Token | Never expires | Long-running automation, team/agency use |
**Start with Quick Start.** You can upgrade to a System User Token later without recreating campaigns.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
| Path | Token Type | Validity | Best For |
|------|-----------|----------|----------|
| **Quick Start (recommended for new users)** | User Access Token via OAuth | ~1-2 hours (short-lived) or ~60 days (long-lived) | Get ads running fast, minimal setup |
| **Production Setup** | System User Token | Never expires | Long-running automation, team/agency use |
**Start with Quick Start.** You can upgrade to a System User Token later without recreating campaigns.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
| Path | Token Type | Validity | Best For |
|------|-----------|----------|----------|
| **Quick Start (recommended for new users)** | User Access Token via OAuth | ~1-2 hours (short-lived) or ~60 days (long-lived) | Get ads running fast, minimal setup |
| **Production Setup** | System User Token | Never expires | Long-running automation, team/agency use |
**Start with Quick Start.** You can upgrade to a System User Token later without recreating campaigns.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
| Path | Token Type | Validity | Best For |
|------|-----------|----------|----------|
| **Quick Start (recommended for new users)** | User Access Token via OAuth | ~1-2 hours (short-lived) or ~60 days (long-lived) | Get ads running fast, minimal setup |
| **Production Setup** | System User Token | Never expires | Long-running automation, team/agency use |
**Start with Quick Start.** You can upgrade to a System User Token later without recreating campaigns.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
| Path | Token Type | Validity | Best For |
|------|-----------|----------|----------|
| **Quick Start (recommended for new users)** | User Access Token via OAuth | ~1-2 hours (short-lived) or ~60 days (long-lived) | Get ads running fast, minimal setup |
| **Production Setup** | System User Token | Never expires | Long-running automation, team/agency use |
**Start with Quick Start.** You can upgrade to a System User Token later without recreating campaigns.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
| Path | Token Type | Validity | Best For |
|------|-----------|----------|----------|
| **Quick Start (recommended for new users)** | User Access Token via OAuth | ~1-2 hours (short-lived) or ~60 days (long-lived) | Get ads running fast, minimal setup |
| **Production Setup** | System User Token | Never expires | Long-running automation, team/agency use |
**Start with Quick Start.** You can upgrade to a System User Token later without recreating campaigns.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
| Path | Token Type | Validity | Best For |
|------|-----------|----------|----------|
| **Quick Start (recommended for new users)** | User Access Token via OAuth | ~1-2 hours (short-lived) or ~60 days (long-lived) | Get ads running fast, minimal setup |
| **Production Setup** | System User Token | Never expires | Long-running automation, team/agency use |
**Start with Quick Start.** You can upgrade to a System User Token later without recreating campaigns.
This line instructs the agent to ask the user to provide credentials directly, including an access token, creating a credential collection workflow through conversation. Even though the text mentions using env vars or secret fields when possible, it still endorses direct credential submission as a common path, which increases exposure in logs, transcripts, and intermediary systems.
**2. Ask the user to provide credentials directly (most common):**
If env vars are not set, ask the user for their Access Token, App ID, and Ad Account ID. **Only request the minimum credentials needed for the current task.** Tell the user exactly how to get each value — don't just ask, give them step-by-step instructions they can follow in their browser.
**Recommend the user use environment variables or their platform's secret fields rather than pasting credentials into chat.** If direct input is the only option, proceed with the instructions below.
This section begins a procedure for obtaining and transmitting an access token to the agent. Because access tokens are bearer secrets, collecting them through chat can allow anyone with transcript access to impersonate the user against Meta APIs.
**Recommend the user use environment variables or their platform's secret fields rather than pasting credentials into chat.** If direct input is the only option, proceed with the instructions below.
**To get an Access Token, tell the user:**
> You can get an Access Token yourself:
> 1. Open https://developers.facebook.com/tools/explorer/
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
**To get an Access Token, tell the user:**
> You can get an Access Token yourself:
> 1. Open https://developers.facebook.com/tools/explorer/
> 2. In the top-right **App** dropdown, select your App (use the App ID from Step 2)
> 3. Click **"Generate Access Token"** → select permissions: `ads_management`, `ads_read`, `business_management`
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
**To get an Access Token, tell the user:**
> You can get an Access Token yourself:
> 1. Open https://developers.facebook.com/tools/explorer/
> 2. In the top-right **App** dropdown, select your App (use the App ID from Step 2)
> 3. Click **"Generate Access Token"** → select permissions: `ads_management`, `ads_read`, `business_management`
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
**To get an Access Token, tell the user:**
> You can get an Access Token yourself:
> 1. Open https://developers.facebook.com/tools/explorer/
> 2. In the top-right **App** dropdown, select your App (use the App ID from Step 2)
> 3. Click **"Generate Access Token"** → select permissions: `ads_management`, `ads_read`, `business_management`
The explicit instruction to copy the generated access token and send it to the agent is a direct request for a sensitive bearer credential. In the context of an advertising automation skill, compromise of this token could enable campaign changes, billing-impacting actions, data access, and further token exchange operations depending on scopes.
> You can get an Access Token yourself:
> 1. Open https://developers.facebook.com/tools/explorer/
> 2. In the top-right **App** dropdown, select your App (use the App ID from Step 2)
> 3. Click **"Generate Access Token"** → select permissions: `ads_management`, `ads_read`, `business_management`
> 4. Click **"Submit"**
> 5. Copy the generated Access Token and send it to me
The guide tells the user how to reveal and share the Meta App Secret, which is a long-lived sensitive secret with broader abuse potential than a short-lived user token. Instructing users to transmit an app secret to the agent materially increases the chance of credential compromise, account takeover of API capabilities, and persistent unauthorized access.
This line operationalizes use of a user-supplied access token in the CLI after conversational collection, reinforcing an insecure credential handling pattern. While setting a token in the tool is expected, the surrounding workflow lacks a secure acquisition channel and thus turns this into a real exposure risk.
# User provides App ID → you run:
lanbow-ads config set --app-id <APP_ID>
# User provides Access Token → you run:
lanbow-ads auth set-token <ACCESS_TOKEN>
# User provides Ad Account ID → you run:
The guide states that the user needs to generate a token and paste it to the agent, directly endorsing insecure transmission of a bearer credential. Because this skill orchestrates ad lifecycle operations, the token likely carries permissions capable of changing campaigns and accessing business assets.
1. In the left menu, click **Add Product** (or scroll down on the app Dashboard)
2. Find **Marketing API** and click **Set Up**
## Step 3: Get an Access Token
The user needs to generate a token in their browser and paste it to you. There are two ways:
This instruction asks the user to provide both App Secret and Access Token so the agent can configure the CLI, combining multiple powerful credentials in one conversational workflow. In this context, exposure could permit long-lived unauthorized API access, token exchange, and broad manipulation of advertising assets and associated business data.
Once the user provides their App ID, App Secret, and Access Token, run:
lanbow-ads config set --app-id <APP_ID> --app-secret <APP_SECRET>
Detected: suspicious.generated_source_template_injection