T09 · Insecure Skill Coding Practices
Warning
- Location
- tools/citecheck.py:54
- Finding
- Undisclosed External Transmission of Citation Data<![CDATA[ ## Vulnerability Details **File Location**: `tools/citecheck.py:54-55, 72-80, 89-90, 135-136, 151-152`; contradictory privacy claims at `README.md:117-125` **Vulnerability Type**: Undisclosed network communication and potential sensitive metadata disclosure **Risk Level**: Medium ### Complete Code Snippet ```python ARXIV_API = "https://export.arxiv.org/api/query" OPENALEX_API = "https://api.openalex.org/works" NS = {"a": "http://www.w3.org/2005/Atom", "ar": "http://arxiv.org/schemas/atom"} UA = {"User-Agent": "inference-expert-agents/citecheck 3.0"} TIMEOUT = 45 class Unreachable(Exception): """Network/registry failure — distinct from 'the citation is wrong'.""" def _get(url: str, timeout: int = TIMEOUT) -> bytes: try: req = urllib.request.Request(url, headers=UA) with urllib.request.urlopen(req, timeout=timeout) as r: return r.read() except urllib.error.HTTPError as e: raise Unreachable(f"HTTP {e.code} from {url.split('?')[0]}") from e except (urllib.error.URLError, TimeoutError, OSError) as e: raise Unreachable(f"{type(e).__name__} reaching {url.split('?')[0]}") from e ``` The values transmitted through these requests are constructed as follows: ```python q = urllib.parse.urlencode({"id_list": ",".join(ids), "max_results": 100}) root = ET.fromstring(_get(f"{ARXIV_API}?{q}")) ``` ```python q = urllib.parse.urlencode({"filter": f"doi:{doi}", "per-page": 1}) data = json.loads(_get(f"{OPENALEX_API}?{q}")) ``` ```python q = urllib.parse.urlencode({"filter": f"title.search:{query}", "per-page": 3}) data = json.loads(_get(f"{OPENALEX_API}?{q}")) ``` This behavior conflicts with the following claims in `README.md`: ```text - Network: none. All processing is local. - Data read/sent: only the text you pass to the tools; nothing is transmitted anywhere. ``` ### Technical Analysis `citecheck.py` performs HTTPS requests to `export.arxiv.org` and `api.openalex.org`. Depending on the selec ...[truncated 2434 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Correct the README permissions and privacy sections to state clearly that `citecheck.py` communicates with: - `https://export.arxiv.org` - `https://api.openalex.org` 2. Document exactly what is transmitted for each subcommand: arXiv IDs, DOI values, and title-query text. 3. Require explicit authorization through an option such as `--allow-network`; refuse network requests unless it is supplied. 4. Emit a concise warning before network use, particularly for `scan`, `check`, and `title`. 5. Provide a local-only mode that validates syntax or checks against a caller-supplied registry snapshot without making external requests. 6. Advise users not to submit confidential, unpublished, or personally identifying title queries. 7. Consider using POST requests where supported to reduce query leakage through URL logs, while noting that this does not prevent disclosure to the destination service. 8. Add tests that ensure the network consent gate is enforced and that documentation accurately reflects current behavior. ]]>
