Back to skill

Security audit

Intake META Ads Analyst

Security checks for vulnerabilities and agentic risk

Overview

The skill is purpose-aligned for Meta ads reporting, but it normalizes pasting a live Meta access token into chat and command lines without adequate secret-handling safeguards.

Install only if you are comfortable giving the agent read access to the Intake Meta ad account. Use a short-lived ads_read token, avoid pasting real tokens into normal chat when a secret-entry mechanism is available, revoke tokens after use, and store exported CSV/JSON reports in an approved secure location.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/meta_campaign_insights.py:288
Finding

Meta Access Token Exposed Through Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:49-58; scripts/meta_campaign_insights.py:288-293; scripts/meta_campaign_insights.py:503
Vulnerability Type: Credential exposure through process arguments and shell history
Risk Level: High

Vulnerable Code

SKILL.md:49-58:

bash
When Max provides a token, use `scripts/meta_campaign_insights.py` to pull data. Standard pull sequence:

# Install dependency (once per session)
pip install -q requests

# 1. Campaign overview — last 30 days
python scripts/meta_campaign_insights.py \
  -t TOKEN \
  -a act_2335535636459862 \

scripts/meta_campaign_insights.py:288-293:

python
parser.add_argument(
    "-t",
    "--access-token",
    required=True,
    help="Meta Marketing API access token (with ads_read permission)",
)

scripts/meta_campaign_insights.py:503:

python
data = fetch_insights(args.access_token, args.account_id, params)

Technical Analysis

The documented and implemented workflow requires a Meta bearer token to be supplied directly as a command-line argument. Command-line arguments may be recorded in interactive shell history, terminal transcripts, automation logs, process-monitoring telemetry, and job metadata. Depending on operating-system process isolation, they may also be visible to other local users while the process is running.

The token is subsequently sent over HTTPS to Meta's official Graph API. That network transmission is necessary for the declared reporting functionality, and the requested ads_read permission is consistent with least privilege. The security defect is the local token-delivery mechanism, not the use of Meta's API.

Attack Path

  1. An authorized operator runs the documented command with a real token in place of TOKEN.
  2. The shell, terminal recorder, process monitor, CI system, or execution environment retains the complete command line.
  3. An attacker with ac ...[truncated 895 chars]
Remediation
View remediation

Remediation Suggestions

  • Remove the token-bearing command examples from SKILL.md and the script documentation.
  • Accept the token through a protected environment variable, such as META_ACCESS_TOKEN, or an interactive hidden prompt implemented with getpass.getpass().
  • Prefer a secrets manager when the script runs through automation.
  • If environment variables are used, ensure job configuration and diagnostic tooling do not print the environment.
  • Reject tokens supplied through command-line arguments, or retain the option only as an explicitly deprecated compatibility mechanism with a security warning.
  • Preserve the least-privilege requirement by continuing to request only ads_read.
  • Avoid printing tokens, request URLs containing tokens, request headers, or complete request objects in logs.
  • Revoke and regenerate any token that may already have appeared in shell history or execution logs.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:49
Finding

Unpinned Third-Party Dependency Installed at Runtime

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:49-53; references/campaign-insights-api.md:24-27; scripts/meta_campaign_insights.py:7-9
Vulnerability Type: Mutable and unverified dependency installation
Risk Level: Medium

Vulnerable Code

SKILL.md:49-53:

bash
When Max provides a token, use `scripts/meta_campaign_insights.py` to pull data. Standard pull sequence:

# Install dependency (once per session)
pip install -q requests

scripts/meta_campaign_insights.py:7-9:

python
Requirements:
    pip install requests

Technical Analysis

The Skill instructs the agent to install requests from the configured Python package index at execution time without a version constraint, integrity hash, lockfile, or isolated environment. Consequently, the installed code can change independently of the reviewed Skill package.

The package name is legitimate and no typosquatting or intentionally malicious source was identified. Nevertheless, mutable dependency resolution creates a supply-chain boundary that is not represented by the audited source. A compromised upstream release, package index, package-index configuration, or network trust path could cause attacker-controlled installation or import behavior.

Running pip install in the active interpreter can also modify a shared environment and produce dependency conflicts affecting unrelated tools.

Attack Path

  1. The operator or agent follows the Skill instructions and executes pip install -q requests.
  2. pip resolves the package and transitive dependencies using the environment's configured package index.
  3. A compromised index, malicious mirror configuration, or compromised future package release supplies altered package content.
  4. Package installation hooks or subsequently imported module code execute in the context running the Skill.
  5. The malicious dependency gains the same filesystem, network, environment, and proce ...[truncated 671 chars]
Remediation
View remediation

Remediation Suggestions

  • Add a reviewed dependency manifest with exact versions for requests and its transitive dependencies.
  • Generate and verify cryptographic hashes, then install with pip install --require-hashes -r requirements.txt.
  • Use a lockfile generated through a dependency-management tool and review updates before adoption.
  • Install dependencies in a dedicated virtual environment rather than modifying the agent's shared interpreter.
  • Use a trusted, explicitly configured package index or an internally controlled artifact repository.
  • Remove routine runtime installation from the Skill workflow where possible; provision reviewed dependencies before handling credentials.
  • Run dependency vulnerability and provenance checks during release preparation.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents a broad Intake Breathing META ads analyst skill with specialized analysis and preloaded business context. The supplied code only fetches Meta Insights data from the Marketing API, handles pagination/errors, exports results, and prints a basic spend/impressions/clicks summary. While this partially matches the 'data pulls via Marketing API' portion of the description, the majority of the declared analyst capabilities are not implemented. Additionally, the code is not tied to Intake Breathing specifically; it accepts any account ID and token and contains no embedded account context or brand-specific logic. Therefore the description materially overstates and mischaracterizes the actual behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill explicitly instructs the user to paste a live Graph API access token into the conversation, with no warning about credential sensitivity, storage, redaction, or safer alternatives. Access tokens are bearer secrets; if mishandled in chat logs, prompts, or downstream tooling, they can enable unauthorized reads of ad account data until expiration and normalize unsafe secret-sharing practices.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

This line directs the operator to collect an access token from the user, which is a credential collection pattern. In the context of an agent skill, asking for a bearer token directly is dangerous because anyone with the token can use the Meta API within its granted scope, and the token may be exposed through prompts, transcripts, logs, or debugging output.

Content

Scanner excerpt · references/campaign-insights-api.md (reported line 15)May include surrounding context.

md
Before running the script, ask the user for TWO things:

1. **Access Token** — with `ads_read` permission. Get at https://developers.facebook.com/tools/accesstoken/
2. **Ad Account ID** — format `act_123456789`. Found in Ads Manager → Account Overview, or Business Settings → Ad Accounts.

Prompt the user:

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

The sample prompt tells the user to provide their Meta access token in plaintext so the skill can pull data. That normalizes unsafe credential sharing and creates a direct path for credential leakage to the model interface, application logs, or anyone with access to the conversation history.

Content

Scanner excerpt · references/campaign-insights-api.md (reported line 20)May include surrounding context.

md
Prompt the user:
> "To export your campaign data, I need two things:
> 1. Your Meta access token (get one at https://developers.facebook.com/tools/accesstoken/ — ensure it has `ads_read` permission)
> 2. Your Ad Account ID (format: `act_123456789`, found in Ads Manager settings)
> Please provide both so I can pull your campaign insights."

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Documenting a CLI flag for --access-token is not inherently malicious, but in combination with the rest of the skill it reinforces a workflow centered on passing sensitive credentials as command-line arguments. Command-line secrets are commonly exposed via shell history, process listings, job logs, and screenshots, making accidental disclosure more likely.

Content

Scanner excerpt · references/campaign-insights-api.md (reported line 108)May include surrounding context.

md
| Argument | Description |
|---|---|
| `-t`, `--access-token` | **Required.** Meta API access token |
| `-a`, `--account-id` | **Required.** Ad account ID (act_XXXXX) |
| `--level` | `account`, `campaign`, `adset`, `ad` (default: campaign) |
| `--fields` | Comma-separated fields (default: smart per-level selection) |

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/meta_campaign_insights.py (reported line 154)May include surrounding context.

python
)
            if error_code == 190:
                print(
                    "Your access token is invalid or expired. Generate a new one at:",
                    file=sys.stderr,
                )
                print(

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/meta_campaign_insights.py (reported line 283)May include surrounding context.

python
)
            if error_code == 190:
                print(
                    "Your access token is invalid or expired. Generate a new one at:",
                    file=sys.stderr,
                )
                print(

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/meta_campaign_insights.py (reported line 291)May include surrounding context.

python
)
            if error_code == 190:
                print(
                    "Your access token is invalid or expired. Generate a new one at:",
                    file=sys.stderr,
                )
                print(

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill directs the agent to use network access and write files to /home/user/workspace/ but does not declare any explicit tool scope or permission boundaries. This creates an under-specified trust boundary where a broadly triggered skill can perform external API access and local data export without clear user-visible constraints or least-privilege limits.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrase is broad enough to activate this skill for nearly any META ads task in the client context, increasing the chance it runs when not strictly needed. Because the skill then requests credentials and initiates network/file operations, over-broad routing can lead to unnecessary token collection, data pulls, and exposure of sensitive advertising data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The document promotes exporting campaign insights to CSV/JSON files but provides no warning that the output can contain commercially sensitive marketing intelligence and potentially user-related performance data. This increases the chance that exports are written to insecure locations, shared broadly, or retained longer than appropriate.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill explicitly instructs the user to paste a live Meta access token into the interaction without any warning that the token is a sensitive credential or guidance to avoid exposing, logging, or storing it. A leaked token with ads_read access can grant unauthorized access to account performance data and may be retained in chat history, logs, or downstream tooling.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

The script exports Meta ad performance data directly to user-specified local files without any warning, classification, or safeguard around potentially sensitive business data. While this is expected functionality for an exporter, the absence of privacy guidance or controls increases the risk of accidental disclosure, insecure storage, or mishandling of account performance and attribution data.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This markdown file appears to be a skill reference/context document, but it does not specify when it should be used, what exact prompts should activate it, or any exclusion conditions. In a markdown skill artifact, the absence of trigger specificity can lead to over-broad or unintended use if the file is consumed as part of skill selection.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The diagnostic includes a command that writes results to /home/user/workspace/roas_check.csv, but the markdown does not warn that running it may overwrite an existing file at that location. Because this is a markdown file and file-writing behavior can affect user data, a brief disclosure would improve safety and clarity.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

These example commands write campaign exports to /home/user/workspace/sale_test_march.csv and /home/user/workspace/sale_test_ads_march.csv, but there is no accompanying warning about potential overwrites or local data handling. For markdown guidance that affects user files, the absence of any warning meets the missing-user-warning criterion.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.