T09 · Insecure Skill Coding Practices
- Location
scripts/apify_client.py:70- Finding
Apify API Token Exposed in URL Query Strings
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly matches its stated Apify social-media retrieval purpose, but it needs review because it uses a billing API token with weak token handling, weak URL/count controls, and broad external actor execution risk.
Review before installing. Use a least-privilege Apify token with spending limits, avoid sensitive or private URLs/usernames, and be aware that actor runs may incur charges. The publisher should switch to Authorization-header authentication, add strict URL and count validation, reject unknown actor IDs, and make the third-party data-processing notice explicit.
scripts/apify_client.py:70Apify API Token Exposed in URL Query Strings
scripts/fetch_single_post.py:23Weak URL Validation Allows Out-of-Scope Targets to Be Submitted to Hosted Actors
scripts/fetch_posts.py:24Unbounded Retrieval Counts Permit Cost and Resource Amplification
scripts/apify_client.py:18Externally Maintained Apify Actors Are Invoked Without Version Pinning
The description presents a broad, unified social retrieval capability across four platforms (TikTok, Instagram, X/Twitter, and YouTube) and across multiple data types (profiles, posts, comments). The supplied code chunk is much narrower: it is a single script dedicated to fetching comments only, for TikTok, Instagram, and X/Twitter. Although it detects YouTube URLs, it does not retrieve YouTube comments and instead exits with an error stating YouTube requires a dedicated actor. There is no implementation here for profile retrieval or general post retrieval. Cross-platform normalization is present for comments, which aligns partially, but the primary scope and supported platforms/data types are materially narrower than declared.
The declared description says the skill supports retrieval of profile, post, and comment data across four platforms. However, this code chunk implements only post/video retrieval: TikTok videos, Instagram posts, Twitter tweets, and YouTube channel videos. It normalizes results and uses Apify actors as described, so the platform scope and normalization aspect are aligned. The mismatch is that profile and comment retrieval capabilities are declared but not evidenced in this supplied code chunk, making the actual behavior materially narrower than the declared purpose.
The declared description claims unified retrieval for profile, post, and comment data across four platforms with normalization. The supplied code only supports profile fetching: it accepts usernames or a YouTube channel URL, invokes platform-specific Apify actors to retrieve one profile-related record, and normalizes it as a profile. There is no functionality here for fetching posts or comments, and no triggers or extra permissions are involved. While the Apify-based, cross-platform, normalized profile aspect is consistent, the declared scope is materially broader than the actual behavior of this code chunk.
The skill declares it requires an environment variable and uses networked scripts, but it does not declare an explicit tool/permission scope. That creates a transparency and governance gap: users and enforcement systems may not understand that execution will access secrets and send data to external services, increasing the chance of overbroad or unexpected capability use.
The skill sends user-provided social media identifiers/URLs and retrieves third-party data through Apify, but it does not warn users that their inputs and resulting data will be transmitted to an external service. This omission can cause privacy, compliance, and consent problems, especially when users may assume processing is local or limited to the host platform.
The reference documentation shows an API token passed in the URL query string for both POST and GET examples. Query-string credentials are commonly exposed via logs, browser history, proxies, analytics, and shared command output, so documenting this pattern without warning encourages insecure credential handling.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import urllib.error
import urllib.parse
API_BASE = "https://api.apify.com/v2"
# Actor ID mapping
ACTORS = {
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import urllib.error
import urllib.parse
API_BASE = "https://api.apify.com/v2"
# Actor ID mapping
ACTORS = {
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import urllib.error
import urllib.parse
API_BASE = "https://api.apify.com/v2"
# Actor ID mapping
ACTORS = {
The helper explicitly allows callers to bypass the fixed ACTORS map by supplying any full Apify actor ID via ACTORS.get(actor_key, actor_key). In a skill advertised as a unified social-media retrieval hub, this expands capability beyond the declared scope and can be abused to trigger arbitrary third-party Apify actors, causing unreviewed external actions, unexpected data access, or billable job execution under the user's token.
The synchronous execution path has the same trust-boundary issue as the async runner: it accepts arbitrary actor identifiers instead of restricting execution to the documented social-media actors. That means any consumer of this helper can invoke unintended Apify actors immediately, leading to scope creep, external side effects, and possible misuse of the API token and account resources.
The module docstring explicitly limits comment retrieval to TikTok, Instagram, and X/Twitter and directs users to a separate YouTube actor. In code, YouTube URLs are detected but then rejected with an error, which conflicts with the manifest's claim of unified Apify-based retrieval for YouTube comment data within this skill.
This code sends the user-supplied post URL to an external actor service via run_actor, which is a network operation that transmits user-provided data. While the file has a general docstring about fetching comments, it does not clearly disclose that URLs are sent to a third-party actor/service before execution.
The Instagram fetch path makes an outbound call with directUrls containing the user-supplied link. The script does not provide a clear warning that external network services will receive the URL, which is relevant to user privacy and expected behavior.
This path performs an outbound request to an external actor using a conversation_id derived from the user's URL. The script lacks a clear disclosure that external services are queried with data derived from the supplied post URL.
This Python code file makes outbound calls via run_actor using usernames or channel URLs supplied by the user, which sends that data to external services. While the docstrings describe fetching profiles, there is no explicit user-facing warning, confirmation, or privacy disclosure indicating that entered identifiers will be transmitted off-system.
The argument definition documents supported explicit platforms as only tiktok, instagram, and twitter, while the code separately detects YouTube URLs and emits a dedicated unsupported-platform error path. This documentation and control flow send conflicting signals about whether YouTube is considered part of the script's supported scope.
No suspicious patterns detected.