Back to skill

Security audit

scraping-twitter-list-members

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it says, but its examples put an Apify API token in URLs and do not clearly warn users about sending targets and scraped profile data to a third party.

Review before installing. Use this only for public Twitter/X lists you are authorized to process, assume list URLs and results are handled by Apify/apidojo, prefer MCP or header-based authentication over token-in-URL curl examples, use a narrowly scoped Apify token, and rotate the token if it may have appeared in logs or command history.

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

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:85
Finding

Apify API Token Transmitted in URL Query Parameters

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 85-97
Vulnerability Type: Credential exposure through URL query parameters
Risk Level: Medium

Vulnerable Code

bash
curl -X POST \
  "https://api.apify.com/v2/acts/apidojo~twitter-list-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"listUrl": "https://twitter.com/i/lists/<LIST_ID>"}'
bash
curl "https://api.apify.com/v2/actor-runs/$RUN_ID?token=$APIFY_TOKEN" | grep '"status"'
bash
curl "https://api.apify.com/v2/actor-runs/$RUN_ID/dataset/items?token=$APIFY_TOKEN&format=json"

Technical Analysis

The documented REST fallback authenticates to Apify by placing APIFY_TOKEN in URL query parameters. Authentication is necessary for the Skill's declared functionality, but including a reusable secret in a URL is not the minimum-risk authentication mechanism.

After environment-variable expansion, the token becomes part of the complete URL supplied to curl. Credential-bearing URLs can be exposed through process inspection while the command is running, verbose client diagnostics, proxy and gateway logs, monitoring telemetry, error reports, or other systems that record request URLs. The commands use HTTPS, which protects the request in transit from ordinary passive interception, but it does not prevent disclosure at the endpoint or through local and intermediary metadata collection.

The network destination is the expected Apify API, and the audit found no evidence that the token is intentionally sent to an unrelated domain. The vulnerability is therefore insecure credential handling rather than unauthorized exfiltration.

Attack Path

  1. A user configures a valid APIFY_TOKEN and follows the documented REST fallback.
  2. The shell expands $APIFY_TOKEN, embedding the reusable credential in the URL passed to curl.
  3. A local process observer, diagnostic system, proxy, gateway, telemetry platform, or URL-logging compone ...[truncated 924 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove token=$APIFY_TOKEN from every Apify API URL.
  2. Pass the credential through an authorization header supported by Apify, for example:
bash
curl -X POST \
  "https://api.apify.com/v2/acts/apidojo~twitter-list-scraper/runs" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"listUrl": "https://twitter.com/i/lists/<LIST_ID>"}'
  1. Apply the same header-based authentication to polling and dataset retrieval:
bash
curl \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  "https://api.apify.com/v2/actor-runs/$RUN_ID"
bash
curl \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  "https://api.apify.com/v2/actor-runs/$RUN_ID/dataset/items?format=json"
  1. Use a narrowly scoped Apify token that grants only the permissions required to execute the specified actor and retrieve its results.
  2. Avoid logging request headers and redact authorization values from diagnostics, command traces, and error reports.
  3. Document token rotation and revocation procedures. Rotate any token suspected of having appeared in URL, proxy, telemetry, or diagnostic logs.
  4. Review the referenced scripts/run_actor.js before distributing it. That file was absent from the audited project, so its credential handling and output behavior could not be verified.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (7)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill instructs users to send Twitter list URLs and retrieve scraped profile datasets through a third-party service without clearly warning that user-supplied targets and resulting data are transmitted to Apify/apidojo. In security-sensitive environments, omission of this disclosure can cause unintentional sharing of potentially sensitive targeting information, workflow metadata, or collected data with an external processor.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest and surrounding documentation describe a scraper that returns Twitter list members and their profile metadata, not tweets. Stating that maxItems controls the maximum tweets returned directly contradicts the declared purpose and output of the skill.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

This command transmits user-provided input to an external service and includes the APIFY_TOKEN in the request URL, which increases the chance of credential leakage via shell history, logs, process listings, proxy logs, or copied output. While external API use is core to the skill, the token-in-URL pattern and absent warning make the transmission more dangerous than necessary.

Content

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

REST API fallback:

bash
curl -X POST \
  "https://api.apify.com/v2/acts/apidojo~twitter-list-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"listUrl": "https://twitter.com/i/lists/<LIST_ID>"}'

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · SKILL.md (reported line 84)May include surrounding context.

REST API fallback:

bash
curl -X POST \
  "https://api.apify.com/v2/acts/apidojo~twitter-list-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"listUrl": "https://twitter.com/i/lists/<LIST_ID>"}'

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

Polling the run status sends authenticated requests to a third-party endpoint with the token embedded in the URL, again risking credential exposure through logs and tooling. The context makes outbound polling expected, but the authentication pattern unnecessarily widens the chance of secret leakage.

Content

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

Save id as RUN_ID. Poll until status = SUCCEEDED:

bash
curl "https://api.apify.com/v2/actor-runs/$RUN_ID?token=$APIFY_TOKEN" | grep '"status"'

Fetch results:

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

Fetching dataset items from Apify is an external transmission and retrieval step that may expose scraped profile data to a third-party processor and, because the token is in the URL, can also leak credentials. In this skill's context the transfer is expected, but users should be clearly informed and the secret-handling pattern should be improved.

Content

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

Fetch results:

bash
curl "https://api.apify.com/v2/actor-runs/$RUN_ID/dataset/items?token=$APIFY_TOKEN&format=json"

Step 3: Handle Edge Cases

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The Inputs table documents startUrls and listIds as the supported parameters, while the actor invocation examples later pass listUrl instead. This is an active documentation inconsistency about how the skill is supposed to be used, which can misstate the intended interface of the code/workflow.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.