Back to skill

Security audit

Meta Ad Spy

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent ad-research tooling, but it asks agents to install unsafe system packages, run an unsandboxed browser scraper, and use API tokens with weak scoping controls.

Install only in a disposable or isolated environment. Avoid --break-system-packages, keep Chromium sandboxing enabled, use least-privilege short-lived Meta tokens, do not run Phase 2 just because a token exists, and treat third-party API options as sharing your research targets and API keys externally.

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

T08 · Insecure Dependencies

Warning
Location
SKILL.md:42
Finding

Unpinned and Unnecessary Dependency Installation

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:91
Finding

Chromium Sandbox Disabled While Processing Remote Content

Content
View full analysis
undefined }); """) ``` ### Technical Analysis The scraper explicitly launches Chromium with `--no-sandbox`. Chromium's process sandbox is a major containment boundary designed to restrict renderer and browser subprocess access to the host. The Skill navigates to remotely supplied web content from Meta and processes ad creatives. If Chromium or one of its media, JavaScript, image, or rendering components contains an exploitable vulnerability, disabling the sandbox can turn a renderer compromise into broader access to the runtime environment. The automation-masking initialization script is not itself code execution from an untrusted source, but it indicates deliberate anti-automation behavior. It is not a substitute for browser isolation and does not justify removing the sandbox. Disabling the sandbox is not necessary for the declared scraping functionality in a properly configured environment. ### Attack Path 1. The Skill starts Chromium with `--no-sandbox`. 2. Chromium navigates to Meta Ad Library and processes remote HTML, JavaScript, images, video, fonts, and advertising content. 3. A malicious advertiser, compromised remote service, or other hostile content source delivers content that exploits a Chromium vulnerability. 4. The e ...[truncated 876 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:265
Finding

API Credentials Transmitted in URL Query Parameters

Content
View full analysis
list[dict]: if not access_token: raise ValueError("META_ACCESS_TOKEN is required for Phase 2") params = { "access_token": access_token, "ad_active_status": ad_active_status, "ad_type": ad_type, "ad_reached_countries": json.dumps(ad_reached_countries), "fields": ",".join(ALL_FIELDS), "limit": min(limit, 500), } # Additional filters omitted from this excerpt do not alter credential handling. if next_url: response = requests.get(next_url, timeout=30) else: response = requests.get(BASE_URL, params=params, timeout=30) ``` Shell example exposing a token in the command and URL: ```bash curl "https://graph.facebook.com/v23.0/pages/search?q=BRAND_NAME&access_token=TOKEN" ``` Third-party SearchAPI example: ```python def searchapi_query(api_key: str, page_id: str = None, query: str = None, country: str = "ALL"): params = { "engine": "meta_ad_library", "api_key": api_key, "ad_type": "all", "active_status": "active", "country": country, "media_type": "all", } if page_id: params["page_id"] = page_id if query: params["q"] = query params["search_type"] = "keyword ...[truncated 2265 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:309
Finding

Unvalidated Pagination URL Allows Requests to Unexpected Hosts

Content
View full analysis
= limit: break ``` ### Technical Analysis The code treats `paging.next` from the remote JSON response as a trusted URL and passes it directly to `requests.get`. It does not enforce: - The `https` scheme - The expected `graph.facebook.com` hostname - An approved port - Absence of URL user information - A safe resolved IP range - Redirect validation Python Requests follows redirects by default. Consequently, even an initially approved URL can lead to a different destination unless redirects are disabled or each redirect target is validated. Meta pagination URLs commonly include the access token in their query strings. If a manipulated response supplies an attacker-controlled `next` URL, or if a redirect leads to another host, the client may disclose credential-bearing URL data or issue requests to unintended services. Direct SSRF exploitation depends on an attacker gaining influence over the API response, DNS, TLS trust environment, or an upstream proxy. ### Attac ...[truncated 1459 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (9)

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger scope is excessively broad and instructs unconditional invocation for vague competitor-related discussion on Facebook or Instagram. This can cause the agent to activate a scraping/research workflow without clear user intent, leading to unnecessary data collection, unexpected external access, and potential policy bypass through over-eager tool use.

Content

No source excerpt is available for this finding.

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 · SKILL.md (reported line 25)May include surrounding context.

md
Phase 1: Playwright Scraper (No API key needed)
  └── facebook.com/ads/library → Ad creatives, copy, status, platforms, dates
  
Phase 2: Meta Graph API (Requires access token)
  └── graph.facebook.com/v23.0/ads_archive → Spend ranges, impressions, demographics
  
Analysis Layer: Claude synthesizes insights from both sources

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 · SKILL.md (reported line 213)May include surrounding context.

md
Phase 1: Playwright Scraper (No API key needed)
  └── facebook.com/ads/library → Ad creatives, copy, status, platforms, dates
  
Phase 2: Meta Graph API (Requires access token)
  └── graph.facebook.com/v23.0/ads_archive → Spend ranges, impressions, demographics
  
Analysis Layer: Claude synthesizes insights from both sources

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 · SKILL.md (reported line 220)May include surrounding context.

md
1. Go to [Meta for Developers](https://developers.facebook.com/) → Create App
2. Go to [facebook.com/ID](https://www.facebook.com/ID) → Confirm identity (required for spend data)
3. Generate a User Access Token with `ads_read` permission from [Graph API Explorer](https://developers.facebook.com/tools/explorer/)
4. Set as env var: `export META_ACCESS_TOKEN="your_token_here"`

### Core API Script

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 · references/field_reference.md (reported line 9)May include surrounding context.

md
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `access_token` | string | ✅ | Your Meta Graph API access token |
| `search_terms` | string | ⚠️ | Keyword to search. Either this or search_page_ids required |
| `search_page_ids` | string | ⚠️ | Comma-separated page IDs. Most precise method |
| `ad_reached_countries` | JSON array | ✅ | e.g. `["US"]`, `["IN","PK"]`, `["ALL"]` |

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill instructs writing executable scripts and raw ad data to /tmp without prominently disclosing local file creation, retention, or cleanup behavior. In shared or persistent environments, this can expose scraped data or leave behind executable artifacts that other processes or users may access.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The Playwright setup hard-codes locale="en-US", which imposes a specific language/locale behavior regardless of user preference. The file does not offer opt-in, locale selection, or a clear region-specific justification for this constraint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The example code sends an API key plus potentially sensitive search targets such as page IDs and competitor queries to a third-party service, but the documentation does not disclose that this causes user data and research activity to be shared outside Meta or the local environment. In a competitive-intelligence skill, those queries may reveal business strategy, customer targeting, or monitoring interests, making the omission materially risky even if the transfer is intentional for functionality.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The ad-details example performs another third-party request using an API key and identifiers such as ad_archive_id and page_id without warning that these values will be disclosed to an external provider. Because the skill is designed for ad surveillance and competitor intelligence, these lookups can expose sensitive investigative intent and operational patterns to the third party.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.