T09 · Insecure Skill Coding Practices
- Location
scripts/retrieve.py:292- Finding
Default-Enabled Transmission of Private Memory Content to an External Reranking Service
- Content
View full analysis
Vulnerability Details
File Location:
scripts/retrieve.py:292-307, 333-356
Vulnerability Type: Sensitive information exposure through implicit external reranking
Risk Level: HighVulnerable Code
python def rerank_enabled() -> bool: raw = os.environ.get('MEMORY_RERANK', '').strip().lower() if raw in {'0', 'false', 'off', 'no'}: return False if raw in {'1', 'true', 'on', 'yes'}: return True return RERANK_ENABLED_DEFAULT def load_siliconflow_key() -> str | None: for env_name in ('SILICONFLOW_API_KEY', 'API_KEY'): val = os.environ.get(env_name) if val: return val return Nonepython api_key = load_siliconflow_key() if not api_key: return {'enabled': True, 'applied': False, 'reason': 'no_api_key'} documents = [f"{h.get('title', '')}\n{h.get('text', '')}".strip() for h in subset] payload = json.dumps({'model': RERANK_MODEL, 'query': query, 'documents': documents}).encode('utf-8') req = urllib.request.Request( RERANK_URL, data=payload, headers={'Authorization': f'Bearer {api_key}', 'Content-Type': 'application/json'}, method='POST', ) try: with urllib.request.urlopen(req, timeout=RERANK_TIMEOUT) as resp: data = json.loads(resp.read().decode('utf-8', errors='ignore'))Technical Analysis
The Skill indexes and retrieves content from
MEMORY.md,memory/learnings.md, and dated memory files. These files may contain private decisions, preferences, incident records, operational details, credentials, or other sensitive long-term agent data.Remote reranking is enabled by default through
RERANK_ENABLED_DEFAULT = True. If the process environment contains eitherSILICONFLOW_API_KEYor the genericAPI_KEYvariable, the Skill sends the user's query and up to ten selected memory documents tohttps://api.siliconflow.cn/v1/rerank.The transmitted documen ...[truncated 3306 chars]
- Remediation
View remediation
Remediation Suggestions
-
Disable remote reranking by default. Set
RERANK_ENABLED_DEFAULT = Falseand require an explicit setting such asMEMORY_RERANK=1. -
Remove the generic credential fallback. Accept only
SILICONFLOW_API_KEY, preventing unrelatedAPI_KEYvalues from activating the integration or being sent to SiliconFlow. -
Require informed consent. Before the first external request, clearly disclose that the query and selected memory excerpts will leave the local machine. In interactive contexts, request confirmation; in automated contexts, require explicit configuration.
-
Provide a strict offline mode. Add an option that categorically prevents network requests, regardless of environment variables. Local-first installations should preferably use this mode by default.
-
Minimize transmitted content. Send only the smallest necessary excerpt, remove unnecessary titles or metadata, and impose strict document and character limits.
-
Redact sensitive data. Filter likely API keys, access tokens, passwords, private keys, connection strings, email addresses, and other sensitive patterns before constructing the request. Allow users to configure additional redaction rules.
-
Prevent repeated disclosure in smart-query mode. Perform candidate selection locally and invoke remote reranking at most once for the final candidate set, rather than once for every rewritten query.
-
Document data handling accurately. State the provider, endpoint, transmitted fields, activation conditions, retention implications, and how to disable all networking.
-
Add regression tests. Verify that no network call occurs when reranking is not explicitly enabled, that generic
API_KEYdoes not activate SiliconFlow, and that configured redaction removes secrets from request payloads.
-
