Back to skill

Security audit

autoecom

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed ecommerce social-posting automation, but it needs Review because live publishing, scheduled routines, broad fetching, and persistent learning are not tightly enforced or scoped.

Install only if you are comfortable giving this skill API keys, scheduled execution, external posting access, and ongoing analytics-based learning. Use a dedicated Upload-Post profile, keep TikTok in draft mode, require a dry-run and explicit approval before every real publish, restrict file/network permissions where your harness supports it, and rotate any API key pasted into chat.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • 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

Error
Location
autoecom.py:79
Finding

Unrestricted URL Fetching and Arbitrary File Write

Content
View full analysis

Vulnerability Details

File Location: autoecom.py:79-82 and autoecom.py:172-178
Vulnerability Type: Server-Side Request Forgery and unrestricted file output
Risk Level: High

Vulnerable Code

python
def http_get(url: str, *, timeout: int = 30) -> requests.Response:
    res = requests.get(url, headers={"User-Agent": UA}, timeout=timeout)
    res.raise_for_status()
    return res
python
def cmd_download(args: argparse.Namespace) -> None:
    out = Path(args.out).resolve()
    out.parent.mkdir(parents=True, exist_ok=True)
    log(f"GET {args.url}")
    res = http_get(args.url, timeout=60)
    out.write_bytes(res.content)
    print(json.dumps({
        "url": args.url,
        "path": str(out),
        "bytes": len(res.content),
        "content_type": res.headers.get("content-type"),
    }, indent=2))

Related URL-fetching behavior also occurs when processing product pages and product images through http_get.

Technical Analysis

The download command accepts an unrestricted URL and an unrestricted destination path. The implementation does not:

  • Restrict URLs to HTTP or HTTPS.
  • Reject loopback, private, link-local, multicast, or reserved IP addresses.
  • Revalidate the destination of HTTP redirects.
  • Restrict downloads to expected storefront or CDN domains.
  • Enforce response-size or image-type limits.
  • Confine output to the project, state, or output directories.

This is particularly significant because the documented workflow derives logo and product-image URLs from remotely controlled storefront content. A malicious or compromised storefront could return image references targeting internal services, including loopback services, private network applications, or cloud instance metadata endpoints. The requests library follows redirects by default, so validating only the original URL would not be sufficient.

The output path is resolved but not check ...[truncated 1863 chars]

Remediation
View remediation

Remediation Suggestions

  1. Permit only https and, where explicitly required, http URLs.
  2. Resolve hostnames before connecting and reject loopback, private, link-local, multicast, unspecified, and reserved IPv4 and IPv6 addresses.
  3. Disable automatic redirects or validate every redirect target with the same rules.
  4. Prefer an allowlist derived from the configured storefront domain and explicitly approved CDN domains.
  5. Stream responses with a strict byte limit rather than loading the entire body before validation.
  6. Require expected image MIME types and verify downloaded content with Pillow before saving it as an image.
  7. Restrict output paths to a designated directory:
    • Resolve both the approved root and requested path.
    • Verify the requested path is a descendant of the approved root.
    • Reject symlink escapes and existing sensitive files.
  8. Run network-facing operations under a low-privilege account with restricted network egress.
  9. Apply the same URL validation to product-page requests and image URLs loaded from plan.json.

T02 · Agent Memory Poisoning

Warning
Location
autoecom.py:291
Finding

Persistent Learned Instructions Are Reused Without Validation

Content
View full analysis

Vulnerability Details

File Location: autoecom.py:291-318 and autoecom.py:928-958
Vulnerability Type: Persistent prompt and agent-memory poisoning
Risk Level: Medium

Vulnerable Code

python
def imagery_prior() -> str:
    """Read HOT_IMAGERY.md and return as a prompt prefix, or '' if absent."""
    if not HOT_IMAGERY_FILE.exists():
        return ""
    body = HOT_IMAGERY_FILE.read_text(encoding="utf-8").strip()
    if not body:
        return ""
    return (
        "PRIOR LEARNINGS — visual patterns that have outperformed for this brand. "
        "Apply when interpreting the slide brief; do not contradict explicit slide instructions.\n\n"
        f"{body}\n\n---\n\n"
    )
python
prior_prefix = imagery_prior()
if prior_prefix:
    log(f"using HOT_IMAGERY.md prior ({len(prior_prefix)} chars prepended to each slide)")

for i, slide in enumerate(slides, start=1):
    slot = raw_dir / f"slide_{i:02d}.png"
    if slot.exists() and not args.force:
        log(f"  slide {i:02d} already exists, skip (use --force to regenerate)")
        continue
    slide_prompt = slide.get("image_prompt") or "Stylized product shot."
    prompt = prior_prefix + slide_prompt

The weekly learning process writes model output directly into the persistent prior:

python
new_body = (resp.text or "").strip()
if not new_body:
    log(f"  {label}: model returned empty output, keeping current")
    return current
if target.exists():
    backup = LEARNINGS_FOLDER / f"{target.stem}.{now.strftime('%Y%m%d-%H%M%S')}.md.bak"
    backup.write_text(target.read_text(encoding="utf-8"), encoding="utf-8")
LEARNINGS_FOLDER.mkdir(parents=True, exist_ok=True)
target.write_text(new_body + "\n", encoding="utf-8")
log(f"  {target.name} updated ({len(new_body)} chars)")
return new_body

Technical Analysis

The weekly learning pipeline sends stored product names, hooks, imag ...[truncated 2327 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace free-form persistent Markdown with a strict JSON schema containing narrowly defined fields such as lighting, framing, background, and hook-length preferences.
  2. Validate field types, lengths, accepted values, and directive scope before persistence.
  3. Reject content containing unrelated instructions, tool requests, credential references, URLs, shell syntax, or attempts to override higher-level instructions.
  4. Keep remote product text in clearly delimited data fields and state in the synthesis prompt that it must never be interpreted as instructions.
  5. Require explicit user review before promoting newly synthesized priors into active files.
  6. Write proposed priors to a staging file and compare them with the active version before activation.
  7. Add source provenance and hashes to every generated rule so users can identify which records contributed to it.
  8. Apply maximum file and rule lengths and limit prior guidance to an approved vocabulary.
  9. Preserve rollback support, but also provide a one-command disable or restore function.
  10. Do not automatically prepend a prior that has not passed validation and approval.

T09 · Insecure Skill Coding Practices

Warning
Location
autoecom.py:560
Finding

Approval and Draft-Only Publishing Controls Are Not Enforced by the Executable

Content
View full analysis

Vulnerability Details

File Location: autoecom.py:560-623 and autoecom.py:1139-1146
Vulnerability Type: Missing authorization-state enforcement for social publishing
Risk Level: Medium

Vulnerable Code

python
def cmd_publish(args: argparse.Namespace) -> None:
    api_key = os.getenv("UPLOAD_POST_API_KEY")
    profile = os.getenv("UPLOAD_POST_PROFILE")
    if not api_key or not profile:
        raise SystemExit("UPLOAD_POST_API_KEY or UPLOAD_POST_PROFILE missing in .env")

    plan_path = Path(args.plan).resolve()
    plan = read_json(plan_path)
    out_dir = plan_path.parent

    slides = sorted(out_dir.glob("slide_*.png"))
    if not slides:
        raise SystemExit("no composed slides — run `compose` first")
    if len(slides) < 2:
        raise SystemExit(f"need at least 2 slides for a carousel, got {len(slides)}")
    if len(slides) > 10:
        log(f"capping carousel at 10 slides (had {len(slides)})")
        slides = slides[:10]

    caption = plan.get("caption", "")
    hashtags = plan.get("hashtags") or []
    description = caption + ("\n\n" + " ".join(hashtags) if hashtags else "")
    title = (plan.get("product") or {}).get("name") or "New product"

    platforms = [p.strip() for p in args.platforms.split(",") if p.strip()]

    data: list[tuple[str, str]] = [
        ("user", profile),
        ("title", title[:140]),
        ("caption", description),
    ]
    for p in platforms:
        data.append(("platform[]", p))
    if "tiktok" in platforms:
        post_mode = "MEDIA_UPLOAD" if args.tiktok_mode == "draft" else "DIRECT_POST"
        data.append(("post_mode", post_mode))

    if args.dry_run:
        print(json.dumps({
            "DRY_RUN": True,
            "endpoint": f"{UPLOAD_POST_BASE}/upload_photos",
            "slides": [str(p) for p in slides],
            "fields": data,
        }, indent=2, ensure_ascii=False))
    
...[truncated 3115 chars]
Remediation
View remediation

Remediation Suggestions

  1. Make dry-run generation a mandatory first phase rather than an optional flag.
  2. Generate a cryptographically random, short-lived confirmation token bound to:
    • The exact plan hash.
    • Slide file hashes.
    • Caption and hashtag content.
    • Selected platforms and publishing modes.
    • The Upload-Post profile.
  3. Require the token for real publication and reject expired, reused, or mismatched tokens.
  4. Record explicit approval through a trusted harness callback rather than inferring it from conversational context.
  5. Remove the direct TikTok choice if project policy requires draft-only uploads. Enforce MEDIA_UPLOAD in code.
  6. Validate platforms against an explicit allowlist and reject unknown values.
  7. Log the approver, approval time, plan hash, and final request fields without logging credentials.
  8. Consider a second confirmation when the final content differs from the dry-run payload.
  9. Restrict access to .env and run the publisher under a dedicated profile with only the minimum required social-account permissions.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (27)

Tainted flow: 'data' from os.getenv (line 1082, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · autoecom.py (reported line 615)May include surrounding context.

python
files.append(("photos[]", (s.name, fh, "image/png")))

        log(f"uploading {len(slides)} slides to {platforms} …")
        res = requests.post(
            f"{UPLOAD_POST_BASE}/upload_photos",
            headers={"Authorization": f"Apikey {api_key}"},
            data=data,

Tainted flow: 'api_key_up' from os.getenv (line 831, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · autoecom.py (reported line 867)May include surrounding context.

python
continue
        url = f"{UPLOAD_POST_BASE}/uploadposts/post-analytics/{rid}"
        try:
            r = requests.get(url, headers={"Authorization": f"Apikey {api_key_up}"}, timeout=30)
        except requests.RequestException as e:
            log(f"  {rid}: HTTP error {e}")
            continue

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The README instructs users to paste sensitive API keys into an agent conversation and to let the agent write them into a .env file, while the same document acknowledges that keys pasted into chat end up in conversation logs. In an agent harness with shell access, scheduling, and messenger integrations, this increases credential exposure risk through chat retention, logs, transcripts, or downstream integrations.

Content

Scanner excerpt · README.md (reported line 42)May include surrounding context.

Open Claude Code, Codex, Hermes, OpenClaw, or any agent with shell access and paste:

text
Set up https://github.com/mutonby/skill-autoecom for me. Read README.md and SKILL.md, clone the repo into ~/Documents/skill-autoecom, create the venv, install requirements.txt, copy .env.example to .env, and ask me for the values of STORE_URL, GEMINI_API_KEY, UPLOAD_POST_API_KEY, and UPLOAD_POST_PROFILE one by one. After .env is filled, run a health check against the Upload-Post API and tell me whether Instagram and TikTok are connected. Then PROGRAM TWO RECURRING ROUTINES IN MY AGENT HARNESS: (1) `/autoecom` daily at 09:00 local time — generate the carousel and send it to my configured messenger (Telegram / WhatsApp / whatever) for approval; (2) `/autoecom-learn` weekly on Monday at 09:00 — run `python autoecom.py learn` and post a digest of what was learned to the same messenger. Ask me which messenger I want before scheduling. Do not echo any API key back to me after I paste it.

The agent will handle the entire bootstrap including the two cron jobs. Without those routines, the daily round-robin stalls and the priors never refresh — see How it learns. Total time: ~2 minutes + however long it takes you to paste 4 keys.

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 · README.md (reported line 241)May include surrounding context.

python3 -m venv venv source venv/bin/activate pip install -r requirements.txt cp .env.example .env

edit .env: STORE_URL, GEMINI_API_KEY, UPLOAD_POST_API_KEY, UPLOAD_POST_PROFILE

text

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- **The Python script (`autoecom.py`)** handles only the mechanical bits you can't do yourself: download a URL, extract a hex palette from an image, parse JSON-

Credential Access

High
Category
Privilege Escalation
Confidence
87% confidence
Finding

The skill explicitly relies on a local .env file containing API keys and instructs the agent to read, write, and update it based on user-provided secrets. In an over-privileged agent context, this creates a meaningful credential exposure surface through file access, logs, accidental echoing, or misuse by other instructions in the skill.

Content

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

md
├── autoecom.py         # utility CLI: download, palette, product, generate, compose, publish, state
├── README.md           # human-readable setup
├── requirements.txt
├── .env
├── input/              # currently unused (reserved for brand assets the user wants forced in)
├── output/
│   └── 2026-05-06/

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 · autoecom.py (reported line 41)May include surrounding context.

python
from PIL import Image, ImageDraw, ImageFont

ROOT = Path(__file__).resolve().parent
load_dotenv(ROOT / ".env")

OUTPUT_FOLDER = Path(os.getenv("OUTPUT_FOLDER", ROOT / "output")).expanduser()
STATE_FOLDER = ROOT / "state"

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 · autoecom.py (reported line 328)May include surrounding context.

python
from PIL import Image, ImageDraw, ImageFont

ROOT = Path(__file__).resolve().parent
load_dotenv(ROOT / ".env")

OUTPUT_FOLDER = Path(os.getenv("OUTPUT_FOLDER", ROOT / "output")).expanduser()
STATE_FOLDER = ROOT / "state"

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 · autoecom.py (reported line 564)May include surrounding context.

python
from PIL import Image, ImageDraw, ImageFont

ROOT = Path(__file__).resolve().parent
load_dotenv(ROOT / ".env")

OUTPUT_FOLDER = Path(os.getenv("OUTPUT_FOLDER", ROOT / "output")).expanduser()
STATE_FOLDER = ROOT / "state"

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 · autoecom.py (reported line 834)May include surrounding context.

python
from PIL import Image, ImageDraw, ImageFont

ROOT = Path(__file__).resolve().parent
load_dotenv(ROOT / ".env")

OUTPUT_FOLDER = Path(os.getenv("OUTPUT_FOLDER", ROOT / "output")).expanduser()
STATE_FOLDER = ROOT / "state"

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 · autoecom.py (reported line 836)May include surrounding context.

python
from PIL import Image, ImageDraw, ImageFont

ROOT = Path(__file__).resolve().parent
load_dotenv(ROOT / ".env")

OUTPUT_FOLDER = Path(os.getenv("OUTPUT_FOLDER", ROOT / "output")).expanduser()
STATE_FOLDER = ROOT / "state"

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 · autoecom.py (reported line 1024)May include surrounding context.

python
from PIL import Image, ImageDraw, ImageFont

ROOT = Path(__file__).resolve().parent
load_dotenv(ROOT / ".env")

OUTPUT_FOLDER = Path(os.getenv("OUTPUT_FOLDER", ROOT / "output")).expanduser()
STATE_FOLDER = ROOT / "state"

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The help text says the default TikTok upload mode 'never auto-publishes', but the code maps any non-draft mode to DIRECT_POST. A misleading safety guarantee around posting behavior is dangerous in this skill context because it can cause unintended publication to a live social account, leading to brand, legal, or reputational harm.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: Pillow==12.2.0 — 16 advisory(ies): CVE-2026-55379 (Pillow `BdfFontFile`: `Image.new()` called without `_decompression_bomb_check()`); CVE-2026-55798 (Pillow: WindowsViewer.get_command() OS command injection via unescaped shell pat); CVE-2026-54060 (Pillow: `FontFile.compile()`: `Image.new()` called without `_decompression_bomb_) +13 more

High
Category
Supply Chain
Confidence
96% confidence
Finding

The file pins Pillow to a version reported by the scanner as having multiple known vulnerabilities, including image-processing decompression bomb issues and a potential command injection issue in Windows-specific viewer functionality. In this skill, Pillow is used to process externally sourced ecommerce and product images, which increases exposure because untrusted image content may be fetched and handled automatically as part of the pipeline.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill requests and uses broad capabilities including environment access, file read/write, and network operations, but does not declare any explicit tool scope or permissions boundary. In an agent environment, this increases the chance of over-privileged execution, making unintended file access, secret handling, or outbound data transmission harder to constrain or audit.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest description says to use the skill when the user 'wants daily product carousels, mentions autoecom, ecommerce content, product slides, shop content automation, or asks for the daily carousel batch.' Phrases like 'ecommerce content' and 'product slides' are broad and overlap with many ordinary requests, without clear exclusion conditions or narrower trigger constraints.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The skill is designed to send content and metadata to external services, including Upload-Post and the target ecommerce store, and later to Instagram/TikTok through the posting platform. External transmission is expected for functionality, but it still carries security and privacy risk because product plans, images, captions, and API-authenticated requests leave the local environment.

Content

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

md
- Connect Instagram (Business/Creator account linked to a Facebook Page) and TikTok via OAuth in the dashboard.
- In **Manage Users**, create a profile — its name is `UPLOAD_POST_PROFILE` (NOT the social handle).
- Generate an API key in **Settings**.
- Verify: `curl -H "Authorization: Apikey $UPLOAD_POST_API_KEY" https://api.upload-post.com/api/uploadposts/me`.

## Orchestration model

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Several required user-facing prompts and reports are written prescriptively in Spanish, including the scheduling confirmation, warning, weekly digest, and insufficient-data message. The file does not offer a language choice for these interactions, so it imposes a locale on users regardless of their preference.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
Check that the environment is ready and ask the user for whatever is missing:

1. **venv** — does `~/Documents/skill-autoecom/venv/bin/python` exist? If not, run setup step 1. Mechanical, do it without asking.
2. **`.env` file** — verify each required key:
   - `STORE_URL` → if missing, ask: *"¿Cuál es la URL de tu tienda? (la home, no una ficha)."*
   - `GEMINI_API_KEY` → if missing, ask: *"Falta la API key de Gemini. Pégamela (la generas en https://aistudio.google.com/apikey)."*

External Transmission

Medium
Category
Data Exfiltration
Confidence
86% confidence
Finding

The skill transmits content to an external service, Upload-Post, for publishing and analytics retrieval. External transmission is expected for a publishing skill, but it still carries privacy and operational risk because product images, captions, hashtags, and account-linked publishing metadata leave the local environment and are sent to a third party.

Content

Scanner excerpt · autoecom.py (reported line 49)May include surrounding context.

python
GEMINI_IMAGE_MODEL = os.getenv("GEMINI_IMAGE_MODEL", "gemini-2.5-flash-image")
GEMINI_TEXT_MODEL = os.getenv("GEMINI_TEXT_MODEL", "gemini-2.5-flash")
UPLOAD_POST_BASE = "https://api.upload-post.com/api"

LEARNINGS_FOLDER = ROOT / "learnings"
RUNS_FOLDER = LEARNINGS_FOLDER / "runs"

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code defines additional learning/analytics data stores and workflows beyond the manifest-described generation/publishing pipeline, which means the skill collects and retains extra behavioral and performance data not transparently disclosed to the user. Hidden capability expansion is dangerous because users may approve carousel generation without realizing their content performance and approval history are being mined for ongoing profiling and optimization.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The natural-language instruction explicitly says to "Write in the dominant language of the hooks themselves," which imposes a language choice based on prior content rather than user preference. This can violate language/locale policy because the skill does not offer the user any opt-in or override for output language.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This section retrieves remote post analytics and uses a model to synthesize new hook and imagery priors, but that optimization loop is not described in the manifest. The risk is undisclosed secondary use of user/content performance data, with automatic persistence into HOT_HOOKS.md and HOT_IMAGERY.md that will influence future model behavior without explicit opt-in.

Content

No source excerpt is available for this finding.

Tainted flow: 'url' from requests.get (line 349, network input) → requests.get (network output)

Medium
Category
Data Flow
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.

Content

Scanner excerpt · autoecom.py (reported line 867)May include surrounding context.

python
continue
        url = f"{UPLOAD_POST_BASE}/uploadposts/post-analytics/{rid}"
        try:
            r = requests.get(url, headers={"Authorization": f"Apikey {api_key_up}"}, timeout=30)
        except requests.RequestException as e:
            log(f"  {rid}: HTTP error {e}")
            continue

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The prompt says to "Write in the dominant language of the candidate hooks," which hard-codes language selection from data rather than from the user's preference. Because no opt-in or locale selection mechanism is provided, this is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.