Back to skill

Security audit

meta-ads-subagent

Security checks for vulnerabilities and agentic risk

Overview

This skill has a clear Meta Ads automation purpose, but it handles powerful ad-account credentials and live campaign changes with unsafe scoping and approval gaps.

Review before installing. Use only with a segregated Meta system user and the minimum ad accounts required, do not paste tokens into chat, and require the publisher to add secure credential setup, read-only/dry-run mode, explicit approval for every pause or campaign update, safer URL validation, removal of real customer data, and clearer separation of CRM/GHL behavior.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:228
Finding
Shell Command Injection Through Untrusted Advertisement URLs<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 228-230 and 260-273 **Vulnerability Type**: Command injection caused by unsafe shell interpolation **Risk Level**: High ### Vulnerable Code Snippet ```bash curl -sIL -o /dev/null -w "%{http_code} %{url_effective}\n" <URL> ``` The surrounding instructions direct the agent to extract URLs from structured creative fields and free-form advertisement body content, then substitute those values into the command. ### Technical Analysis Advertisement destination URLs and free-form creative body fields are externally controlled data. The documented command places the extracted value directly into a shell command without requiring argument-array execution, scheme validation, shell escaping, or even mandatory quoting. If the agent performs textual substitution and invokes the command through a shell, shell metacharacters in a crafted value can terminate or extend the intended `curl` command. Redirect targets also require validation because an initially legitimate URL can redirect to an unsafe scheme, internal resource, or unexpected destination. The issue is especially severe because the agent environment may contain Meta access tokens, Habilis credentials, advertising account identifiers, and local Hermes configuration files. ### Attack Path 1. An attacker obtains control over an advertisement creative, destination field, affiliate link, shortened link, or free-form body field that the Skill audits. 2. The attacker inserts a value containing shell metacharacters and an additional command. 3. The Skill extracts the value as a destination URL. 4. The agent substitutes it into the documented `curl` command and executes it through a shell. 5. The shell interprets the injected portion as a separate command. 6. The injected command executes with the same operating-system privileges as the agent. ### Impact Assessment Successful exploitation could permit arbitrary command execution under the agent ...[truncated 599 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not invoke a shell to test URLs. Use an HTTP client API with arguments passed as structured values. - If a subprocess is necessary, use an argument array such as `["curl", "-sIL", ..., url]` with shell processing disabled. - Permit only `http` and `https` schemes. - Reject control characters, whitespace anomalies, shell metacharacters, embedded credentials, and malformed hostnames. - Apply DNS and IP validation to prevent access to loopback, link-local, private, metadata, and other internal network ranges. - Revalidate every redirect destination. - Enforce request timeouts, response-size limits, and a maximum redirect count. - Run URL checks in a network-restricted sandbox without access to credentials. - Add regression tests using URLs containing semicolons, command substitution, newlines, pipes, redirects, and encoded metacharacters. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:103
Finding
Unsafe Collection and Plaintext Persistence of Privileged Meta Tokens<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 103-110 and 211-214 **Vulnerability Type**: Insecure credential collection and plaintext secret storage **Risk Level**: High ### Vulnerable Code Snippet The onboarding instructions tell the agent to offer the following behavior: ```text The user may paste the credentials directly into the chat so the agent can save and validate them. Alternatively, the user may save them in /root/.hermes/metaads/.env. ``` The token-management instructions additionally prescribe: ```bash hermes config set META_ACCESS_TOKEN <token> ``` They direct the token to be stored in both: ```text ~/.hermes/.env ~/.hermes/config.yaml ``` and then instruct the agent to reload the MCP process with: ```bash pkill -f mcp-meta-ads ``` ### Technical Analysis The requested Meta token carries permissions including `ads_management`, `ads_read`, and `pages_show_list`. Asking users to paste this token into chat unnecessarily exposes it to conversation history, agent telemetry, tool traces, debugging logs, and support exports. The Skill then directs the token to be duplicated across plaintext files. This increases the number of compromise points and conflicts with the README's zero-storage claim. The package does not specify restrictive file permissions, encryption at rest, log redaction, token lifetime restrictions, or cleanup of old token values. The behavior exceeds minimum privilege. Meta Ads functionality requires a token to be supplied securely to the relevant client or MCP process, but it does not require the token to appear in chat or to be duplicated in multiple plaintext files. ### Attack Path 1. A user follows onboarding and pastes a privileged Meta token into the chat. 2. The token becomes part of the conversation or agent execution record. 3. The agent saves the token in one or more plaintext Hermes files. 4. Chat administrators, telemetry systems, backups, plugins, local users, or compromised processes g ...[truncated 1034 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Never ask users to paste access tokens into chat. - Use a non-echoing interactive secret prompt, operating-system keychain, dedicated secret manager, or secure MCP credential setup flow. - Store the token in only one authoritative location. - Apply owner-only permissions to any unavoidable local secret file. - Do not place secrets directly in general-purpose YAML configuration if secure variable references are available. - Redact tokens from logs, command output, errors, telemetry, and generated reports. - Avoid passing secrets as command-line arguments because process listings and shell history may expose them. - Use narrowly scoped system-user tokens and grant access only to required advertising accounts. - Document token expiration, revocation, rotation, and incident-response procedures. - Replace the zero-storage claim with an accurate data-flow statement unless the implementation is changed to avoid persistent storage. ]]>

other

Warning
Location
references/meta_ads_optimization_insights.md:3
Finding
Real Customer Advertising and Financial Metadata Bundled in the Skill<![CDATA[ ## Vulnerability Details **File Location**: `references/meta_ads_optimization_insights.md`, lines 3-6, 11-39, and 54-60 **Vulnerability Type**: Sensitive business data exposure **Risk Level**: Medium ### Vulnerable Data Snippet ```text Account: act_327126129438619 Business ID: 100754338860752 Page actor IDs: 112665111651993 / 1336366589550605 Pixel ID: 1079270794502909 ``` The same file includes live-looking campaign and ad identifiers, campaign status, daily budget, spend, impressions, clicks, conversion metrics, spend-cap values, available balance, and performance conclusions. ### Technical Analysis These identifiers are not authentication secrets by themselves, but they are customer-specific operational data bundled in a generic distributable Skill. The data is unnecessary for the Skill's declared functionality because synthetic examples can demonstrate the same optimization principles. Combining account, business, page, pixel, campaign, ad-set, and advertisement identifiers gives recipients a detailed map of the customer's advertising environment. Financial and conversion metrics also expose commercially sensitive performance information. ### Attack Path 1. An attacker or unrelated recipient downloads the public or shared Skill package. 2. The recipient opens the bundled optimization reference. 3. The recipient extracts the customer name, account IDs, page IDs, pixel ID, campaign IDs, ad IDs, financial values, and performance data. 4. The information is correlated with public business records, social-media pages, advertisements, or previously leaked data. 5. The recipient uses the resulting profile for targeted phishing, impersonation, account-recovery abuse, competitive analysis, or social engineering. ### Impact Assessment The disclosed data can facilitate: - Mapping of a real customer's Meta advertising assets. - Disclosure of advertising spend, balance, targeting, and conversion performance. - Competitive intelligence about active of ...[truncated 329 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove all real customer and production account data from the distributed package. - Replace every identifier, company name, budget, balance, metric, date, and campaign name with clearly synthetic examples. - Obtain explicit authorization before publishing any case-study data. - Minimize published metrics and aggregate them where exact values are unnecessary. - Add automated release checks for Meta token prefixes, advertising account IDs, business IDs, page IDs, pixel IDs, campaign IDs, email addresses, and customer names. - Review repository history and previously published package versions, then request removal or replacement where supported. - Establish a release checklist requiring privacy and customer-data review. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:178
Finding
Autonomous Campaign Suspension Without Adequate Human Approval Boundaries<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 49-56, 178-184, 232-237, and 252-256 **Vulnerability Type**: Unsafe autonomous mutation of financially impactful advertising resources **Risk Level**: Medium ### Vulnerable Instruction Snippet The Skill directs the agent to perform the following actions: ```text Immediately pause advertisements whose destination is broken. Automatically pause advertisements or ad sets when CPA exceeds the configured target by 30%. ``` The fallback procedure further instructs the agent to escalate from an advertisement-level failure to the parent campaign: ```text If the campaign is active and the advertisement or ad set refuses the pause, escalate by pausing the campaign through mcp_meta_ads_update_campaign. ``` Human confirmation is required for creating or activating campaigns above a daily budget threshold, but equivalent approval is not required before suspending advertisements, ad sets, or an entire parent campaign. ### Technical Analysis Pausing advertising resources is a financially and operationally significant write action. The decision may be based on transient HTTP failures, redirects that reject HEAD requests, bot protection, regional responses, delayed conversion attribution, incomplete seven-day metrics, or an incorrectly configured CPA target. The fallback from one failed advertisement-level update to pausing its parent campaign broadens the action's scope. A campaign can contain unrelated advertisements and ad sets, so campaign-level suspension is not necessarily a least-privilege substitute for pausing one advertisement. The Skill provides some useful safeguards, such as initially creating campaigns in a paused state and requiring approval for high-budget activation. However, these controls do not adequately constrain autonomous suspension. ### Attack Path 1. A landing page temporarily returns an error, blocks the audit client, or mishandles a HEAD request; alternatively, incompl ...[truncated 1299 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Make audit mode read-only by default. - Require explicit, per-action human approval before pausing an advertisement, ad set, or campaign. - Never escalate from advertisement-level suspension to campaign-level suspension without separate confirmation. - Verify landing-page failures with multiple GET requests from independent locations before taking action. - Do not rely solely on HEAD responses because many valid sites reject or mishandle them. - Require a minimum sample size, attribution delay, and configurable observation window before applying CPA rules. - Present the exact resource ID, parent hierarchy, evidence, expected blast radius, and rollback plan to the user. - Implement an allowlist of accounts and campaigns on which write operations are permitted. - Record an immutable audit log for every proposed, approved, executed, and reverted mutation. - Provide a dry-run mode that reports recommended actions without changing Meta resources. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (18)

Credential Access

High
Category
Privilege Escalation
Content
### 🚀 Quick Onboarding & First-Time Setup
1. **Get your Habilis MCP Token**:
   - Access the developer portal at [https://xvix.com.br](https://xvix.com.br) to generate your access token.
2. **Configure Environment Variables**:
   ```bash
   export HABILIS_API_KEY="hab_live_..."
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
- 📊 **3-Level Taxonomy**: Structured naming for Campaigns, Ad Sets, and Ads for effortless tracking.
- 🎨 **1080x1080 Creative Generator**: Autonomous SVG banner generation and asset uploads.
- 🛑 **Autonomous CPA Guardrails**: Automatically pauses underperforming ads exceeding CPA thresholds.
- 🔒 **Zero-Storage Security**: Meta access tokens remain exclusively on the client machine.

---
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
- [ ] **1. Habilis MCP Token (Obrigatório)**:
  - Obtenha seu token de acesso no portal de desenvolvedores: [https://xvix.com.br](https://xvix.com.br).
  - Defina: `export HABILIS_API_KEY="hab_live_..."`
- [ ] **2. Meta Ads Access Token (Cliente)**:
  - Token de usuário do sistema ou Graph API com escopo `ads_management` (reside estritamente no seu ambiente local).
  - Defina: `export META_ACCESS_TOKEN="EAA..."`
- [ ] **3. ID da Conta de Anúncios (`META_AD_ACCOUNT_ID`)**:
Confidence
90% confidence
Finding
The skill requires access tokens for Habilis and Meta Ads, indicating credential access as part of normal operation. In context, this becomes dangerous because the same document later encourages handling and persistence of those credentials through insecure chat and local-file workflows, increasing the likelihood of secret compromise.

Missing User Warnings

High
Confidence
99% confidence
Finding
The skill explicitly invites users to paste a sensitive Meta access token into chat without strong warnings or a safer alternative as the default path. Collecting secrets through chat risks transcript retention, logging, model exposure, and accidental disclosure to operators or downstream systems.

Ssd 3

High
Confidence
99% confidence
Finding
The onboarding script tells users to paste sensitive access tokens directly into chat for the assistant to save and validate, which is a direct secret-handling anti-pattern. In the context of an automation skill with broad operational authority, leaked tokens could enable unauthorized ad account access, campaign changes, spending, or data extraction.

MCP Config Access

High
Category
Agent Snooping
Content
- Ao construir ou estender fluxos de Onboarding, parametrização ou exportação de credenciais no frontend do Habilis (`src/components/SkillDownloaderModal.tsx`, `src/lib/onboarding-schema.ts`, etc.):
  1. **Zero Persistência no Backend**: Tokens de acesso, senhas de API, IDs de conta de anúncios, Pixels e Page IDs digitados pelos clientes **NUNCA** devem ser gravados no banco de dados (`data/habilis_db.json`), SQLite, logs ou arquivos no servidor.
  2. **Processamento In-Memory**: O formulário opera exclusivamente em memória volátil do navegador via React State (`useState`).
  3. **Interpolação em Tempo Real**: Os snippets de código (`claude_desktop_config.json`, `.cursor/mcp.json`, comandos cURL, CLI do Hermes) e arquivos para download (`SKILL.md`, `.env`) são gerados client-side utilizando `Blob` e URLs temporárias (`URL.createObjectURL`), sendo liberados imediatamente após o download (`URL.revokeObjectURL`).
  4. **Avisos Transparentes de Segurança**: A interface do modal deve sempre exibir badges e alertas claros de privacidade (`🔒 Zero-Storage Guarantee`) para gerar confiança nos assinantes do SaaS.

---
Confidence
90% confidence
Finding
Skill accesses MCP server configuration files (mcp.json). MCP configs contain server URLs, authentication tokens, and tool definitions — reading them allows the skill to discover and potentially abuse other tool integrations.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The setup instructions direct users to configure API tokens and connect to an external MCP endpoint, but they do not clearly disclose that advertising account data and credentials or credential-derived access will be transmitted to third-party services. This lack of transparency is risky because users may expose sensitive business data, ad account metadata, and operational control to external infrastructure without informed consent.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The README advertises automatic pausing of underperforming ads but does not clearly warn users that the skill can modify live campaign state and spending behavior. In an autonomous ads-management context, hidden or underemphasized write actions can cause business disruption, unintended pauses, and revenue loss if users assume the skill is advisory only.

Vague Triggers

Medium
Confidence
87% confidence
Finding
The trigger list includes short, generic phrases such as "meta ads", "facebook ads", "cpa alto" and "relatório de tráfego" without any scope constraints or exclusion examples. In a markdown/manifest-style header, these broad terms can collide with normal conversation about ads rather than an intentional request to invoke this skill.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The skill expands beyond Meta Ads management into CRM/GHL lead triage and conversation handling, which increases its access scope to customer communications and personal data without a clear need for the advertised purpose. This kind of scope creep weakens least-privilege boundaries and can enable unnecessary exposure or manipulation of inbound lead data.

Ssd 3

Medium
Confidence
88% confidence
Finding
Prompting for essential account data when credentials are missing is not inherently unsafe, but here it normalizes solicitation of sensitive identifiers and tokens inside the conversational workflow. Given the rest of the skill explicitly asks for tokens and stores them, this directive materially increases the likelihood of unsafe secret disclosure.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The onboarding flow instructs the agent to save user-supplied Meta credentials into a local .env file, which creates credential storage behavior inside the skill and encourages persistence of secrets outside a controlled secret-management flow. Persisting access tokens locally increases the chance of accidental disclosure, reuse by other processes, or compromise via filesystem access.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The execution flow directs the skill to retrieve GHL leads and resolve contact identifiers through external APIs, again broadening the skill beyond Meta Ads into CRM data handling. This expands access to potentially sensitive customer records and creates unnecessary cross-system permissions that raise privacy and abuse risks.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
This markdown file presents all operational guidance in Portuguese and does not indicate that the user can opt into another language. Under the policy, forcing a specific language without user choice is a natural-language policy violation unless the locale constraint is clearly documented and justified.

Natural-Language Policy Violations

Low
Confidence
77% confidence
Finding
The instructions require reports to be formatted for Telegram in a fixed style and character limit, which imposes a specific communication mode by default. Because no user opt-in or alternative delivery format is offered here, this can be read as an unnecessary forced locale/channel constraint in the skill's natural-language policy.

Context-Inappropriate Capability

Low
Confidence
89% confidence
Finding
Including shell-level process management instructions such as killing MCP processes extends the skill into host operational control unrelated to ad management. While not directly a data-exfiltration issue, it increases the chance of unintended service disruption or misuse of local system capabilities.

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
This markdown file contains user-facing instructions exclusively in Portuguese, starting with the section headings and continuing throughout the guide. Under the language/locale policy rule, forcing a specific language without offering the user an explicit choice can be a natural-language policy violation.

Natural-Language Policy Violations

Low
Confidence
92% confidence
Finding
The comments and placeholder labels indicate the skill/template is oriented to Portuguese-language output, but there is no natural-language indication that this locale is optional or intentionally region-specific. Under the language/locale policy, forcing a specific language without user opt-in can be a policy concern.

Static analysis

No suspicious patterns detected.