Back to skill

Security audit

x-apify

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stated Twitter/X scraping purpose, but it needs review because it can spend paid Apify credits without an enforced cap and can forward unintended URLs to Apify.

Review before installing. Use an Apify account with spending limits, keep --max-results conservative, pass only x.com/twitter.com tweet URLs without secrets in query strings, avoid storing tokens in committed .env files or synced dotfiles, and use --no-cache or a private cache directory for sensitive searches.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:118
Finding

Unvalidated Tweet URL Is Disclosed to a Third-Party Apify Actor

Content
View full analysis
`. It does not parse the URL or verify that its scheme and hostname belong to X/Twitter. When an input starts with `http`, the original input is retained and placed directly into the `start ...[truncated 1648 chars]
Remediation
View remediation
` are rejected. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/fetch_tweets.py:348
Finding

Unbounded Result Count Can Trigger Excessive Paid Actor Usage

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/fetch_tweets.py:419
Finding

Output Path Confinement Can Be Bypassed by Prefix Collisions and Symlinks

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · SKILL.md (reported line 134)May include surrounding context.

export APIFY_API_TOKEN="apify_api_YOUR_TOKEN_HERE" export APIFY_ACTOR_ID="apidojo~tweet-scraper"

Or use .env file (never commit this!)

echo 'APIFY_API_TOKEN=apify_api_YOUR_TOKEN_HERE' >> .env

text

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · SKILL.md (reported line 135)May include surrounding context.

export APIFY_API_TOKEN="apify_api_YOUR_TOKEN_HERE" export APIFY_ACTOR_ID="apidojo~tweet-scraper"

Or use .env file (never commit this!)

echo 'APIFY_API_TOKEN=apify_api_YOUR_TOKEN_HERE' >> .env

text

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

L54 states 'Get a specific tweet + replies by URL' as a supported capability. However, L10 explicitly documents actor limits including 'no single-tweet or reply scraping,' which directly contradicts that earlier documented intent rather than merely omitting detail.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill declares environment, file read/write, and network-capable behavior but does not define an explicit tool scope such as permissions or allowed-tools. In an agent ecosystem, this can cause overbroad execution authority and makes it harder for operators to review or constrain what the skill is permitted to access.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest advertises retrieval of a specific tweet with replies, while the documentation later states the default actor does not support single-tweet fetches or conversation scraping. This mismatch can mislead users or calling agents into invoking unsupported behavior, potentially causing repeated failed runs, incorrect trust in output completeness, or avoidable spend.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 125)May include surrounding context.

md
## Setup

1. Create a free Apify account: https://apify.com/
2. Get your API token: https://console.apify.com/account/integrations
3. Set environment variables:

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

Advising users to place API tokens in ~/.bashrc or ~/.zshrc creates long-lived credential persistence in plaintext shell startup files. This increases exposure to local compromise, accidental disclosure through backups/dotfile sync, or token reuse across sessions beyond what is necessary.

Content

Scanner excerpt · SKILL.md (reported line 130)May include surrounding context.

  1. Set environment variables:
bash
# Add to ~/.bashrc or ~/.zshrc
export APIFY_API_TOKEN="apify_api_YOUR_TOKEN_HERE"
export APIFY_ACTOR_ID="apidojo~tweet-scraper"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The instructions explicitly tell users to append an API token into a local .env file without sufficient warning about local credential storage risks. If that file is left with weak permissions, copied into backups, or accidentally exposed, the Apify token could be reused for unauthorized API access and billing abuse.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill stores fetched tweet data on disk by default but does not clearly warn users that data will persist locally. On shared systems or sensitive workflows, this can expose search history, target handles, and scraped content to other local users, backups, or later unintended reuse.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/config.py (reported line 12)May include surrounding context.

python
from pathlib import Path

# API configuration
APIFY_API_BASE = "https://api.apify.com/v2"
# apidojo~tweet-scraper (Tweet Scraper V2). Checked on the Apify API 2026-08-31:
# public, not deprecated, $0.40 per 1,000 tweets, 0 failed of 4.7M public runs in 30 days.
# The payloads in fetch_tweets.py (searchTerms / startUrls / maxItems) are this actor's

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/fetch_tweets.py (reported line 73)May include surrounding context.

python
try:
        # Start the run
        response = requests.post(
            run_url,
            headers=headers,
            json=input_data,

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest and top-level description advertise 'get user profiles,' but this section documents --user with examples that 'Get tweets from a specific user' and earlier maps user timeline input to startUrls. That is a direct documentation-to-behavior mismatch because the feature described here is timeline scraping, not profile retrieval.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/config.py:43

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
SKILL.md:126