Back to skill

Security audit

AI Builder Signal Digest (Transparent + Sourced)

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but its helper script can be tricked into fetching non-arXiv URLs from crafted input links.

Install only if you will run it on trusted link lists or in a network-restricted environment. Before broader use, the arXiv fetch should validate scheme and hostname strictly, reject redirects to private or local addresses, and bound response size.

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
scripts/make_digest.py:89
Finding

Server-Side Request Forgery Through Unvalidated arXiv URLs

Content
View full analysis
str | None: """Best-effort: fetch arXiv abs page and extract the first 1–2 sentences of abstract.""" # Keep very lightweight; regex over HTML. req = urllib.request.Request( url, headers={"User-Agent": "ai-builder-signal-digest/1.0"}, method="GET", ) try: with urllib.request.urlopen(req, timeout=timeout_s) as resp: html = resp.read().decode("utf-8", errors="replace") except Exception: return None ``` The request is reached using an unrestricted substring check: ```python if not why and "arxiv.org/abs/" in url: abs_sum = summarize_arxiv_abstract(url) if abs_sum: why = abs_sum ``` JSONL input validation only verifies that the value begins with `http`: ```python url = r.get("canonical_url") title = r.get("title") if not isinstance(url, str) or not url.startswith("http"): continue ``` ### Technical Analysis The script treats any URL containing the text `arxiv.org/abs/` as an arXiv abstract URL. It does not parse the URL and require the hostname to be exactly `arxiv.org` or another explicitly approved arXiv hostname. Consequently, attacker-controlled URLs such as the following satisfy the check even though their actual destination is not arXiv: ```text http://127.0.0.1/admin?source=arxiv.org/abs/test https://attacker.example/redirect?source=arxiv.org/abs/test ``` The URL is passed directly to `urllib.request.urlopen()`. Python's URL opener also follows ordinary HTTP redirects by default, and redirect destinations are not revalidated. An a ...[truncated 2373 chars]
Remediation
View remediation
`. 9. Apply outbound network controls so the process cannot access localhost, private networks, link-local ranges, or cloud metadata services unless explicitly required. 10. Replace the substring test with strict validation before calling the fetch function. For example: ```python import ipaddress import socket import urllib.parse ALLOWED_ARXIV_HOSTS = {"arxiv.org", "www.arxiv.org"} def validate_arxiv_url(url: str) -> bool: try: parsed = urllib.parse.urlsplit(url) host = parsed.hostname if parsed.scheme != "https" or host not in ALLOWED_ARXIV_HOSTS: return False if parsed.username or parsed.password: return False if not parsed.path.startswith("/abs/"): return False for result in socket.getaddrinfo(host, 443, type=socket.SOCK_STREAM): address = ipaddress.ip_address(result[4][0]) if not address.is_global: return False ...[truncated 218 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (2)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill instructs the agent to run a local Python script, read from local files, write output to /tmp, and potentially fetch GitHub or paper metadata, but it does not declare any tool scope or permission boundaries. This creates an implicit capability expansion where an orchestrator or reviewer cannot clearly constrain file and network access, increasing the risk of unintended data exposure or misuse if the skill is invoked in a sensitive environment.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% 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 · scripts/make_digest.py (reported line 58)May include surrounding context.

python
def fetch_github_repo_info(repo: str, timeout_s: int = 10) -> tuple[int | None, int | None, str | None, str | None]:
    """Return (stars, forks, description, err). Unauthenticated; may rate-limit."""
    api = f"https://api.github.com/repos/{repo}"
    req = urllib.request.Request(
        api,
        headers={

Static analysis

No suspicious patterns detected.