Back to skill

Security audit

Techla FB Repost

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent with its Facebook reposting purpose, but it handles powerful posting and API credentials in ways that can leak them.

Review before installing. Use this only with Pages you own or are authorized to manage, and assume Apify, Google, and Facebook will receive the referenced content, prompts, images, and post text. Do not paste real tokens into commands or chats; use a protected secret store or environment variables, restrict token scopes, and rotate any token already used through these examples. The verify command should be fixed before use so it never requests or prints access_token values.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/scrape_fb.py:11
Finding
Apify credentials are exposed through command-line arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/scrape_fb.py:11-12` and `SKILL.md:28-31` **Vulnerability Type**: Credential exposure through process arguments **Risk Level**: Medium ### Vulnerable Code ```python APIFY_TOKEN = sys.argv[2] if len(sys.argv) > 2 else None FB_URL = sys.argv[1] if len(sys.argv) > 1 else None ``` The documented invocation explicitly places the credential on the command line: ```bash python3 scripts/scrape_fb.py "<FB_POST_URL>" "<APIFY_TOKEN>" ``` ### Technical Analysis The Apify API token is supplied through `argv`. Command-line arguments can be retained in shell history, captured by process-monitoring or observability systems, and exposed to other local users who have permission to inspect processes. Although sending an Apify token to Apify is necessary for the declared scraping functionality, accepting that token through a command-line argument is not necessary and creates avoidable local exposure. ### Attack Path 1. A user follows the documented command and supplies an Apify token as the second argument. 2. The complete command is saved in shell history or observed through process inspection. 3. A local attacker or log reader extracts the token. 4. The attacker reuses the token against Apify APIs until it is revoked or expires. ### Impact Assessment A compromised token may permit unauthorized actor runs, access to account-associated Apify resources subject to the token's permissions, consumption of paid platform resources, and exposure of datasets accessible with that token. This does not directly grant local code execution or Facebook Page access. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Read `APIFY_TOKEN` from a protected environment variable or secret manager instead of `sys.argv`. - Permit only the non-sensitive Facebook URL as a command-line argument. - If environment variables are unsuitable, read the secret from stdin without echoing it. - Update `SKILL.md` so that examples never place real tokens in shell commands. - Redact credentials from process telemetry, exception reporting, and debug logs. - Rotate any token that has already been used through the documented command interface. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_image.py:12
Finding
Gemini API keys are exposed through command-line arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_image.py:12-14` and `SKILL.md:62-65` **Vulnerability Type**: Credential exposure through process arguments **Risk Level**: Medium ### Vulnerable Code ```python PROMPT = sys.argv[1] if len(sys.argv) > 1 else None API_KEY = sys.argv[2] if len(sys.argv) > 2 else None OUTPUT_PATH = sys.argv[3] if len(sys.argv) > 3 else "/tmp/gemini_image.png" ``` The documented invocation places the Gemini key in the process argument list: ```bash python3 scripts/generate_image.py "<IMAGE_PROMPT>" "<GEMINI_API_KEY>" /tmp/fb_image.png ``` ### Technical Analysis API keys should not be transported through command-line arguments because process arguments may be visible in process listings, shell history, Agent execution logs, and monitoring systems. The image-generation operation requires a Gemini credential, but exposing it through `argv` exceeds the minimum disclosure needed to perform the task. ### Attack Path 1. A user or Agent starts the image generator with a Gemini key in the command. 2. The command is retained in history, a transcript, process telemetry, or monitoring output. 3. An attacker with access to that data extracts the key. 4. The attacker submits unauthorized Gemini API requests under the victim's project or quota. ### Impact Assessment Exploitation may result in unauthorized model usage, quota exhaustion, financial cost, and access to other Google AI operations authorized by the same key and its API restrictions. The impact depends on how narrowly the key is restricted. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Retrieve the key from a secret manager or an environment variable such as `GEMINI_API_KEY`. - Remove the key from the documented command syntax. - Restrict the key to the required Google Generative Language API, expected clients, and appropriate quotas. - Avoid recording secret-bearing environment values in debug output. - Rotate any key that may have been exposed in shell history or execution transcripts. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/post_fb.py:102
Finding
Facebook Page access tokens are exposed through command-line arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/post_fb.py:102-122` and `SKILL.md:68-76` **Vulnerability Type**: Credential exposure through process arguments **Risk Level**: High ### Vulnerable Code ```python if __name__ == "__main__": command = sys.argv[1] if len(sys.argv) > 1 else None if command == "upload-photo": if len(sys.argv) < 5: print(json.dumps({"error": "Usage: upload-photo <PAGE_ID> <TOKEN> <IMAGE_PATH>"})) sys.exit(1) result = upload_photo(sys.argv[2], sys.argv[3], sys.argv[4]) elif command == "post": if len(sys.argv) < 5: print(json.dumps({"error": "Usage: post <PAGE_ID> <TOKEN> '<MESSAGE>' [<PHOTO_ID>]"})) sys.exit(1) photo_id = sys.argv[5] if len(sys.argv) > 5 else None result = post_to_page(sys.argv[2], sys.argv[3], sys.argv[4], photo_id) elif command == "verify": if len(sys.argv) < 4: print(json.dumps({"error": "Usage: verify <PAGE_ID> <TOKEN>"})) sys.exit(1) result = get_page_info(sys.argv[2], sys.argv[3]) ``` Documented examples also place the Page token on the command line: ```bash python3 scripts/post_fb.py upload-photo "<PAGE_ID>" "<PAGE_TOKEN>" /tmp/fb_image.png python3 scripts/post_fb.py post "<PAGE_ID>" "<PAGE_TOKEN>" "<MESSAGE>" "<PHOTO_ID>" ``` ### Technical Analysis The Page access token is a high-value publishing credential and is accepted directly through `argv` for upload, post, and verification operations. It can therefore be disclosed through shell history, process inspection, Agent transcripts, or process telemetry. The Page identifier, message, image path, and photo identifier may legitimately be command arguments. The access token does not need to be present there and should be independently retrieved from protected secret storage. ### Attack Path 1. A user follows the documented upload, post, or verify command. 2. The Page token appear ...[truncated 708 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Load the Page token from a protected environment variable or secret manager. - Remove `<TOKEN>` from every command syntax and usage error. - Use a narrowly scoped Page token containing only permissions required by the posting workflow. - Separate verification and publishing credentials if the platform supports narrower permissions. - Redact tokens from Agent transcripts, process telemetry, and error reports. - Rotate exposed Page tokens and review recent Page activity for unauthorized actions. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/scrape_fb.py:48
Finding
Apify tokens are embedded in request URLs<![CDATA[ ## Vulnerability Details **File Location**: `scripts/scrape_fb.py:48-64` and `scripts/scrape_fb.py:113-118` **Vulnerability Type**: Sensitive credential in URL query strings **Risk Level**: Medium ### Vulnerable Code ```python status_url = f"{API_BASE}/actor-runs/{run_id}" for _ in range(30): # Max 30 attempts status_resp = requests.get(f"{status_url}?token={APIFY_TOKEN}", timeout=30) status_data = status_resp.json() status = status_data["data"]["status"] if status == "SUCCEEDED": break elif status in ["FAILED", "ABORTED", "TIMED-OUT"]: print(json.dumps({"error": f"Actor run failed with status: {status}"})) sys.exit(1) time.sleep(2) # Get dataset items dataset_url = f"{API_BASE}/datasets/{dataset_id}/items" items_resp = requests.get(f"{dataset_url}?token={APIFY_TOKEN}", timeout=30) ``` The alternative actor repeats the same pattern: ```python status_resp = requests.get(f"{status_url}?token={APIFY_TOKEN}", timeout=30) ... items_resp = requests.get(f"{dataset_url}?token={APIFY_TOKEN}", timeout=30) ``` The actor-start requests also include the token in their JSON body: ```python payload = { "token": APIFY_TOKEN, "startUrls": [{"url": FB_URL}], "maxPosts": 1, "waitForFinish": 60 } ``` ### Technical Analysis Query-string credentials are commonly captured by HTTP client instrumentation, reverse proxies, access logs, monitoring products, and exception telemetry. HTTPS protects the request while it is in transit but does not prevent the full URL from being logged by the client, endpoint, or authorized intermediaries. Putting the token in the actor input body also unnecessarily exposes it to actor input records. Authentication should be separated from operation input and supplied through the provider-supported authorization mechanism. ### Attack Path 1. The scraper polls an actor run or retrieves a dataset using `?token=<APIFY_TOKEN>`. 2. A proxy, instrumentation library, access l ...[truncated 471 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Use Apify's supported authorization header, such as `Authorization: Bearer <APIFY_TOKEN>`. - Do not include the authentication token in query strings or actor input JSON. - Centralize request construction in a configured `requests.Session` with an authorization header. - Configure HTTP logging and telemetry to redact authorization headers. - Call `raise_for_status()` on polling and dataset responses and return sanitized errors. - Rotate tokens if URLs containing them may already have entered logs. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_image.py:27
Finding
Gemini API keys are embedded in request URLs<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_image.py:27` and `scripts/generate_image.py:59` **Vulnerability Type**: Sensitive credential in URL query strings **Risk Level**: Medium ### Vulnerable Code ```python def generate_with_imagen(): """Generate image using Imagen 3.0""" url = f"https://generativelanguage.googleapis.com/v1beta/models/imagen-3.0-generate-002:predict?key={API_KEY}" ``` The fallback repeats the same credential transport: ```python def generate_with_gemini_flash(): """Fallback to Gemini Flash image generation""" url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp-image-generation:generateContent?key={API_KEY}" ``` ### Technical Analysis The Gemini key is interpolated into each request URL. Full URLs can be collected by local request instrumentation, proxies, observability platforms, endpoint access logs, and exception telemetry. TLS prevents passive network observers from reading the URL but does not address logging by participating systems. Sending a credential to Google's API is required, but placing it in the URL is avoidable and increases its exposure surface. ### Attack Path 1. The image generator constructs a URL containing the API key. 2. An HTTP monitor, proxy, tracing system, or diagnostic tool records the URL. 3. An attacker or unauthorized log reader extracts the key. 4. The key is reused for unauthorized API requests. ### Impact Assessment Exploitation may cause unauthorized Gemini API usage, quota depletion, and billing impact. If the key lacks API or client restrictions, it may also authorize other enabled Google APIs associated with the same project. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Send the key using Google's supported `x-goog-api-key` request header rather than the URL. - Configure URL logging to omit query parameters and redact known secret patterns. - Apply API restrictions, client restrictions, and quotas to the key. - Use separate keys for distinct environments and workloads. - Rotate keys that may already have appeared in logs or telemetry. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/post_fb.py:75
Finding
Facebook verification unnecessarily retrieves and prints an access token<![CDATA[ ## Vulnerability Details **File Location**: `scripts/post_fb.py:75-87` and `scripts/post_fb.py:115-124` **Vulnerability Type**: Excessive sensitive-data retrieval and output disclosure **Risk Level**: High ### Vulnerable Code ```python def get_page_info(page_id, token): """Get page info to verify token works.""" url = f"{BASE_URL}/{page_id}" params = { "fields": "name,access_token", "access_token": token } try: response = requests.get(url, params=params, timeout=30) return response.json() except Exception as e: return {"error": str(e)} ``` The returned API object is subsequently printed without allowlisting or redaction: ```python elif command == "verify": if len(sys.argv) < 4: print(json.dumps({"error": "Usage: verify <PAGE_ID> <TOKEN>"})) sys.exit(1) result = get_page_info(sys.argv[2], sys.argv[3]) else: print(json.dumps({ "error": "Unknown command", "usage": "upload-photo | post | verify" })) sys.exit(1) print(json.dumps(result, ensure_ascii=False)) ``` ### Technical Analysis Verifying that a Page token works only requires non-sensitive fields such as `id` or `name`. Requesting `access_token` is unnecessary for verification and violates data minimization. Because the entire response is printed, any returned token may enter terminal output, Agent transcripts, CI logs, or centralized log storage. This behavior exceeds the minimum privilege and data-access requirements of the declared verification function. ### Attack Path 1. A user or Agent invokes the `verify` command with a valid Page token. 2. The script requests `name,access_token` from Facebook Graph API. 3. Facebook returns the Page information, potentially including an access token. 4. The script serializes the complete response to stdout. 5. The output is retained in a terminal transcript, Agent conversation, CI log, or monitoring system. 6. A party with access to ...[truncated 443 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Change the requested fields from `name,access_token` to a non-sensitive allowlist such as `id,name`. - Return a minimal verification result, for example: ```python return { "success": True, "page_id": result.get("id"), "page_name": result.get("name") } ``` - Never print or return access-token fields. - Add recursive output redaction for keys such as `access_token`, `token`, `api_key`, and `authorization`. - Supply the input token through protected secret storage rather than a query string or command-line argument. - Rotate any Page token that may already have been printed and review Page activity for unauthorized use. ]]>
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
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (29)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Mô tả khai báo một quy trình đầy đủ cho repost bài Facebook: đọc bài từ link Facebook, viết lại nội dung, tạo ảnh minh họa, rồi đăng lên Facebook Page. Tuy nhiên, mã nguồn được cung cấp chỉ thực hiện một phần hẹp của quy trình đó: gọi Google Gemini/Imagen để sinh ảnh từ prompt và ghi ảnh ra file. Không có bất kỳ xử lý nào liên quan đến Facebook URLs, scraping/đọc nội dung bài viết, biến đổi văn bản, hay gọi Facebook Graph API để đăng bài. Vì vậy, mục đích thực tế của đoạn mã khác biệt đáng kể so với mô tả tổng thể của skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Mô tả khai báo một pipeline đầy đủ: đọc bài từ link Facebook, rewrite nội dung, tạo ảnh minh họa bằng Gemini, rồi đăng lên Page. Nhưng mã thực tế chỉ là tiện ích đăng bài cơ bản qua Facebook Graph API: upload ảnh từ đường dẫn local, post message, và verify page/token. Phần 'đăng lên Facebook Page qua Graph API' là phù hợp, nhưng đó chỉ là một phần nhỏ của mô tả. Các năng lực cốt lõi được khai báo như lấy nội dung từ link Facebook, viết lại bài, và tạo ảnh bằng Gemini hoàn toàn không xuất hiện trong code. Vì vậy đây là mismatch rõ ràng giữa declared purpose và actual behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
Mô tả khai báo một pipeline đầy đủ gồm: lấy bài Facebook, rewrite nội dung, tạo ảnh minh họa, và đăng lại lên Facebook Page. Tuy nhiên code thực tế chỉ thực hiện phần đầu là scrape dữ liệu bài viết Facebook thông qua Apify actor, sau đó trả về JSON chứa text/media/metrics. Không có bất kỳ tích hợp nào với Gemini, không có xử lý sinh nội dung hay phong cách viết lại, và cũng không có gọi Facebook Graph API để đăng bài. Vì vậy mô tả vượt xa đáng kể so với hành vi thực tế của code và đây là mismatch rõ ràng.

Vague Triggers

High
Confidence
97% confidence
Finding
The activation rule says to use the skill whenever there is a Facebook link plus a repost-related request, which is overly broad for a workflow that handles scraping, AI rewriting, image generation, and social posting. Over-triggering can cause the agent to solicit sensitive credentials or prepare external posting actions in situations where the user did not clearly intend that level of automation.

Credential Access

High
Category
Privilege Escalation
Content
1. **APIFY_TOKEN** — https://console.apify.com/account/integrations
2. **GEMINI_API_KEY** — https://aistudio.google.com/app/apikey  
3. **FB_PAGE_ID** — ID Facebook Page
4. **FB_PAGE_ACCESS_TOKEN** — Page Access Token (permission `pages_manage_posts`)

> Gợi ý user lưu vào OpenClaw secrets/env vars để không nhập lại.
Confidence
95% confidence
Finding
The skill explicitly requests a Facebook Page Access Token with posting permissions, along with other API credentials, which creates a high-risk credential handling path. Because this skill's context includes scraping and automated publication to external platforms, compromised or over-shared tokens could be used for unauthorized posting, reputational damage, and third-party account abuse.

Credential Access

High
Category
Privilege Escalation
Content
### Facebook Page Token
1. Go to Facebook Developer Console
2. Create app with "Pages" product
3. Get User Access Token with `pages_manage_posts` permission
4. Exchange for Page Access Token:
   ```
   GET https://graph.facebook.com/{USER_ID}/accounts?access_token={USER_TOKEN}
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
### Facebook Page Token
1. Go to Facebook Developer Console
2. Create app with "Pages" product
3. Get User Access Token with `pages_manage_posts` permission
4. Exchange for Page Access Token:
   ```
   GET https://graph.facebook.com/{USER_ID}/accounts?access_token={USER_TOKEN}
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. Go to Facebook Developer Console
2. Create app with "Pages" product
3. Get User Access Token with `pages_manage_posts` permission
4. Exchange for Page Access Token:
   ```
   GET https://graph.facebook.com/{USER_ID}/accounts?access_token={USER_TOKEN}
   ```
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding
The skill orchestrates external network actions including scraping Facebook content, calling Gemini, and posting to Facebook, but it declares no explicit tool scope or allowed-tools boundary. That makes the operational surface broader and less auditable, increasing the chance of unintended network access or misuse of connected capabilities.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill encourages storing highly sensitive API keys and a Facebook Page access token in secrets or environment variables without any warning about token sensitivity, scope minimization, or rotation. In a skill that can post to Facebook and call third-party services, mishandling these credentials could enable account misuse, unauthorized posting, or abuse of paid API resources.

External Transmission

Medium
Category
Data Exfiltration
Content
### Facebook Posts Scraper (Primary)
- Actor ID: `apify~facebook-posts-scraper`
- Run URL: `POST https://api.apify.com/v2/acts/apify~facebook-posts-scraper/runs`

Request body:
```json
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The documentation provides direct instructions for publishing to a live Facebook Page via the Graph API without requiring any explicit user confirmation, dry-run mode, or warning that the action causes real external side effects. In the context of an agent skill whose purpose is to repost content automatically, this increases the risk of unintended publication, unauthorized posting, and reputational harm if the agent acts on ambiguous prompts.

Missing User Warnings

Medium
Confidence
80% confidence
Finding
The usage string instructs users to pass GEMINI_API_KEY as a command-line argument, and the key is then embedded in outbound request URLs. Although the purpose of the script involves calling the API, there is no warning that the credential is sensitive or that passing secrets via command-line arguments may expose them in shell history or process listings.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The script sends the user-provided PROMPT to Google's generativelanguage.googleapis.com endpoint, but there is no warning in code comments, output, or documentation about transmitting user data to a third-party service. For code files, network calls that transmit user data should have some form of disclosure unless the warning is clearly documented elsewhere.

External Transmission

Medium
Category
Data Exfiltration
Content
}
    
    try:
        response = requests.post(url, json=payload, headers=headers, timeout=60)
        response.raise_for_status()
        data = response.json()
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
}
    
    try:
        response = requests.post(url, json=payload, headers=headers, timeout=60)
        response.raise_for_status()
        data = response.json()
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
83% confidence
Finding
The script writes generated image bytes directly to OUTPUT_PATH, which is supplied via command-line argument, but provides no user-facing disclosure at the point of write beyond the bare usage string. For code files, file writes that lack confirmation prompts, visible warnings, or clearer explanatory comments can qualify as missing user warnings.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The usage instructions require the user to pass a TOKEN on the command line, and the code then sends that credential in HTTP requests. There is no warning in comments, help text, or output that the token is sensitive or that passing secrets via command-line arguments may expose them in shell history or process listings.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
This code performs outbound HTTP requests to Facebook's Graph API and uploads a local image file, but the implementation provides no confirmation prompt or runtime disclosure before sending user content off-system. The module docstring shows usage syntax, but it does not warn that local files and message content will be transmitted to Facebook.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
`get_page_info` requests `fields=name,access_token`, which retrieves a page access token even though simple verification does not require returning that secret. Pulling broader sensitive data than necessary violates least privilege and increases the chance of credential exposure through logs, downstream tool output, or misuse by an agent.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The script sends both the user-supplied Facebook URL and the Apify token to a third-party scraping service, but the only disclosure is a brief usage string in the docstring. In this skill context, that matters because users may expect local processing while the skill actually transmits content targets and credentials off-platform to Apify, creating privacy, compliance, and secret-handling risk.

External Transmission

Medium
Category
Data Exfiltration
Content
sys.exit(1)

ACTOR_ID = "apify~facebook-posts-scraper"
API_BASE = "https://api.apify.com/v2"

def run_actor():
    """Run Apify actor and get dataset items."""
Confidence
88% confidence
Finding
The hardcoded Apify API base indicates that the skill is designed to send data to an external third-party service. By itself the constant is not malicious, but in context it confirms an external data flow that users may not anticipate, especially for scraped content workflows involving social media URLs and access tokens.

External Transmission

Medium
Category
Data Exfiltration
Content
}
    
    try:
        response = requests.post(run_url, json=payload, headers=headers, timeout=70)
        response.raise_for_status()
        run_data = response.json()
Confidence
96% confidence
Finding
This code transmits the Facebook URL and Apify token to api.apify.com, which is an external service outside the local skill boundary. In a reposting skill, such exfiltration is somewhat aligned with function, but it is still security-relevant because it exposes potentially sensitive user targets and credentials to a third party and broadens the trust boundary.

Tainted flow: 'status_url' from requests.post (line 108, network input) → requests.get (network output)

Medium
Category
Data Flow
Content
# Poll for completion
        status_url = f"{API_BASE}/actor-runs/{run_id}"
        for _ in range(30):  # Max 30 attempts
            status_resp = requests.get(f"{status_url}?token={APIFY_TOKEN}", timeout=30)
            status_data = status_resp.json()
            status = status_data["data"]["status"]
Confidence
65% confidence
Finding
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Tainted flow: 'status_url' from requests.post (line 108, network input) → requests.get (network output)

Medium
Category
Data Flow
Content
# Poll for completion
        status_url = f"{API_BASE}/actor-runs/{run_id}"
        for _ in range(30):  # Max 30 attempts
            status_resp = requests.get(f"{status_url}?token={APIFY_TOKEN}", timeout=30)
            status_data = status_resp.json()
            status = status_data["data"]["status"]
Confidence
65% confidence
Finding
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Static analysis

No suspicious patterns detected.