T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/search_client.py:186- Finding
Bundled client exceeds the Skill's declared URL-extraction scope
- Content
View full analysis
Vulnerability Details
File Location:
scripts/search_client.py, lines 186-260
Vulnerability Type: Undeclared API capability and excessive use of delegated credentials
Risk Level: MediumTechnical Analysis
SKILL.mddeclares a narrowly scoped Tavily URL-extraction Skill whose core capability is converting user-provided URLs into clean text. However, the bundled client also provides averityoperation that sends a user query to four separate search services and subsequently submits all returned results to an AI synthesis endpoint.Relevant code:
python def cmd_verity(args: argparse.Namespace) -> None: """Multi-source search with confidence scoring.""" api_key = get_api_key() count = args.count print(f"\nSearching across multiple sources for: \"{args.query}\"\n") # Phase 1: Parallel retrieval sources: dict[str, dict[str, Any]] = {} tasks = { "Web": ("/scholar/search/web", {"query": args.query, "max_num_results": count}), "Smart": ("/scholar/search/smart", {"query": args.query, "max_num_results": count}), "Scholar": ("/scholar/search/scholar", {"query": args.query, "max_num_results": count}), "Tavily": ("/tavily/search", {"query": args.query, "max_results": count, "include_answer": True}), } def fetch(name: str, endpoint: str, body: dict[str, Any]) -> tuple[str, dict[str, Any]]: return name, aisa_post(api_key, endpoint, body) with ThreadPoolExecutor(max_workers=4) as pool: futures = { pool.submit(fetch, name, ep, body): name for name, (ep, body) in tasks.items() } for future in as_completed(futures): name = futures[future] try: _, data = future.result() sources[name] = data print(f" [OK] {name}") except Exception as e: print(f" [FAIL] {na ...[truncated 3592 chars]- Remediation
View remediation
Remediation Suggestions
- Replace the multi-purpose client in this Skill with a minimal extraction-only implementation that exposes only
/tavily/extract. - Remove the
web,scholar,smart,tavily,sonar, andverityhandlers and their argument-parser registrations from the extraction package. - If broader capabilities are intentional, publish them as separate Skills with accurate descriptions, explicit activation conditions, and separate credentials or API scopes.
- Configure server-side credentials with endpoint-level restrictions so an extraction credential cannot invoke search, deep-research, or synthesis APIs.
- Before transmission, clearly disclose the destination, request type, number of URLs or queries, and whether returned content will be submitted for secondary synthesis.
- Add conservative request-count and input-size limits to prevent accidental quota exhaustion.
- Reject empty URLs and validate URL schemes and maximum list length before sending extraction requests.
- Document that user-provided URLs, queries, and extracted or aggregated content are transmitted to
https://api.aisa.one. - Add automated tests that compare exposed CLI commands against the capabilities declared in
SKILL.md, preventing future scope drift.
- Replace the multi-purpose client in this Skill with a minimal extraction-only implementation that exposes only
