T09 · Insecure Skill Coding Practices
- Location
SKILL.md:56- Finding
Apify API Token Exposed Through URL Query Strings
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill does what it claims, but its examples handle an Apify API token unsafely and collect potentially personal Threads data through a third-party scraper without enough user warning.
Review before installing. Use this skill only for Threads data you are authorized to collect and process, and assume target usernames, keywords, run metadata, and scraped results are handled by Apify and the named actor. Do not use the token-in-URL examples as written; prefer Authorization headers, use a dedicated least-privilege Apify token where possible, avoid logging full request URLs, and rotate any token already used in copied commands or shared logs.
SKILL.md:56Apify API Token Exposed Through URL Query Strings
Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.
description: |
This skill should be used when the user asks to
"scrape Threads posts", "get Threads data",
"extract Threads content", "search Threads",
"monitor Threads hashtags", "analyze Threads engagement",
"get posts from a Threads user",
or needs to collect data from Meta Threads.
The skill explicitly sends user-supplied search terms and receives scraped Threads data through Apify, and the documented output includes profile fields plus contact-related fields such as emails, phones, bio_links, and external_links. Because the skill lacks any warning or consent language about third-party transmission and possible collection of personal/sensitive data, users may unknowingly export personal data to an external processor.
The hardcoded Apify API base URL evidences that the skill is designed to transmit data off-platform to a third party. In context this is intended behavior, but it still represents a real privacy and data-governance risk because the skill handles scraped content that can include profile and contact information.
import requests, os, time
TOKEN = os.environ["APIFY_API_TOKEN"]
BASE = "https://api.apify.com/v2"
# Step 1: Start the run
response = requests.post(
This code transmits parameters and the API token to Apify to start a remote scraping job. External transmission is expected for this skill, but it is still security-relevant because user inputs and access credentials are sent to a third party, and the token is placed in the URL query string, which can be logged by clients, proxies, or monitoring systems.
BASE = "https://api.apify.com/v2"
# Step 1: Start the run
response = requests.post(
f"{BASE}/acts/futurizerush~meta-threads-scraper/runs?token={TOKEN}",
json={"mode": "user", "usernames": ["futurizerush"], "max_posts": 5},
)
This example sends search keywords to Apify to perform remote collection of Threads content. While functionally intended, it exposes user queries to an external service and inherits the same token-in-URL risk, making it a genuine data-transmission concern rather than a false positive.
requests.post(
f"{BASE}/acts/futurizerush~meta-threads-scraper/runs?token={TOKEN}",
json={
"mode": "search",
The hashtag search example transmits user-selected keywords and credentials to a third-party API. The danger is not hidden code execution but privacy and credential exposure: the actor provider learns what is being searched, and query-string tokens can leak into logs or observability systems.
requests.post(
f"{BASE}/acts/futurizerush~meta-threads-scraper/runs?token={TOKEN}",
json={"mode": "keyword", "keywords": ["automation"], "max_posts": 20},
)
The bash example posts directly to Apify with the API token embedded in the URL, which is especially prone to leakage via shell history, process listings, CI logs, or copied terminal output. It also initiates third-party processing of potentially sensitive search targets or usernames without any user-facing privacy warning.
# Step 1: Start the run
RUN_RESPONSE=$(curl -s -X POST \
"https://api.apify.com/v2/acts/futurizerush~meta-threads-scraper/runs?token=$APIFY_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"mode": "user", "usernames": ["futurizerush"], "max_posts": 5}')
This curl endpoint shows direct third-party transmission to Apify and, together with the surrounding command, uses URL-based secret passing. The context makes the transmission expected, but not harmless: request details and credentials may be exposed through logging or shell tooling.
# Step 1: Start the run
RUN_RESPONSE=$(curl -s -X POST \
"https://api.apify.com/v2/acts/futurizerush~meta-threads-scraper/runs?token=$APIFY_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"mode": "user", "usernames": ["futurizerush"], "max_posts": 5}')
Polling the actor-run status continues sending the API token to Apify in the URL, creating repeated opportunities for secret leakage through logs and network instrumentation. Although operationally normal, repeated authenticated requests broaden the exposure window for the credential.
# Step 2: Poll until done
while true; do
STATUS=$(curl -s "https://api.apify.com/v2/actor-runs/$RUN_ID?token=$APIFY_API_TOKEN" \
| jq -r '.data.status')
[ "$STATUS" = "SUCCEEDED" ] && break
[ "$STATUS" = "FAILED" ] || [ "$STATUS" = "ABORTED" ] && echo "Failed: $STATUS" && exit 1
Fetching dataset items from Apify retrieves scraped content that may include personal/profile/contact data, again using a token in the URL. This is dangerous because it combines external data exfiltration/retrieval with weak secret-handling practices and no warning to users about the data sensitivity.
done
curl -s "https://api.apify.com/v2/datasets/$DATASET_ID/items?token=$APIFY_API_TOKEN" | jq '.'
## Output Format