T09 · Insecure Skill Coding Practices
- Location
src/scholar_research/search.py:15- Finding
Academic Search Queries Transmitted over Plaintext HTTP
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This academic research skill is mostly purpose-aligned, but it should be reviewed because it can fetch arbitrary PDF URLs, write downloaded content locally without size or type limits, and documents an unsafe placeholder Git install command.
Review this skill before installing. It is not clearly malicious, but only use it with non-sensitive research queries, avoid the placeholder Git install command, and run PDF download/extraction in a restricted environment because arbitrary or malicious PDFs could be fetched and written to disk.
src/scholar_research/search.py:15Academic Search Queries Transmitted over Plaintext HTTP
src/scholar_research/figure_extract.py:175Arbitrary PDF URL Retrieval Enables Server-Side Request Forgery
src/scholar_research/figure_extract.py:202Remote Downloads Have No Size or File-Type Validation
README.md:16Documentation Recommends Installation from an Unpinned Placeholder Git Repository
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).
and analysis tool that queries multiple databases (arXiv, PubMed, OpenAlex, CrossRef), scores papers by relevance/quality, and generates field timelines.
# From GitHub
pip install git+https://github.com/yourusername/scholar-research.git
# Or install locally
pip install -e .
# Search for a topic
python -m scholar_research "quantum computing" --top=5
# Search with custom output
python -m scholar_research "machine learning" --top=3 --output json
# Install dev dependencies
pip install -e ".[dev]"
#
The supplied code is only a scoring/analysis module. It calculates credibility scores from paper metadata, sorts papers, computes score distributions/statistics, and includes helper classes that query OpenAlex and CrossRef for author/journal information. That partially aligns with the 'credibility scoring' portion of the description, but most of the declared functionality is not present in this chunk: no search across open-access sources, no paper summarization, no visualization, no timeline creation, and no figure extraction. Additionally, the code makes outbound network requests to OpenAlex and CrossRef despite the declared permissions being empty. This makes the description incomplete/inaccurate relative to the actual behavior of this code chunk.
The code chunk is a search/retrieval component only. Its primary behavior is calling external academic metadata/search APIs and normalizing results. While this partially aligns with the 'search' portion of the description, the broader declared functionality is not represented in this code: there is no paper analysis, no summarization, no credibility scoring, no visualization, no timeline creation, and no figure extraction. Additionally, the declared description emphasizes peer-reviewed papers from open access sources, but the code does not enforce peer-review filtering and includes sources such as arXiv (preprints) and CrossRef/PubMed metadata endpoints that are not themselves guarantees of open-access peer-reviewed full text. Therefore the description materially overstates and mischaracterizes what this code actually does.
The declared description presents a broader research skill that can search, analyze, and summarize academic papers from open-access sources and provide credibility scoring, visualization, timeline generation, and figure extraction. The supplied code only covers a subset: summarization, timeline generation, and text-based visualization over already-provided paper data. It does not perform paper search/retrieval, source access, or figure extraction, and it does not actually score credibility in the main implementation. Because important declared capabilities are absent from the actual behavior of this code chunk, the description does not accurately represent what this chunk does.
The skill advertises behaviors that inherently require network access, file handling, and possibly shell-capable execution through external tooling, yet it declares no explicit tool scope or permissions. This creates an overprivileged or ambiguously privileged execution model where a host may grant broader access than intended, increasing the chance of unauthorized network requests, file reads, or command execution if the implementation is later added or swapped in.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
- **Rate Limit**: 3 requests per second
### 3. OpenAlex
- **Base URL**: `https://api.openalex.org/`
- **Endpoints**:
- Works: `/works`
- Authors: `/authors`
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
- **Rate Limit**: 60 requests/minute
### 5. CrossRef
- **Base URL**: `https://api.crossref.org/`
- **Documentation**: https://www.crossref.org/documentation/retrieve-metadata/rest-api/
- **Rate Limit**: Polite pool (include email)
- **Note**: Requires email for "polite" usage
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
- **Rate Limit**: 100 requests/day (free tier)
### 7. Unpaywall
- **Base URL**: `https://api.unpaywall.org/v2/`
- **Documentation**: https://unpaywall.org/products/api
- **Rate Limit**: 100,000 requests/day
- **Note**: Requires email
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
# Install
sudo apt install poppler-utils
# Extract text
pdftotext paper.pdf -
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
"""Extract text from PDF"""
try:
# Use pdftotext if available
result = subprocess.run(
["pdftotext", pdf_path, "-"],
capture_output=True,
text=True,
The module executes the external pdftotext command on user-supplied PDF paths, which is a subprocess operation covered by the warning requirement for code files. Although the purpose is inferable, this file provides no user-facing notice, prompt, or explicit warning that external system tools will be executed.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
try:
# Try using pdfimages (Poppler)
base_name = os.path.join(output_dir, "fig")
subprocess.run(
["pdfimages", "-list", "-png", pdf_path, base_name],
capture_output=True,
timeout=30
The code invokes the external pdfimages utility to extract images from the PDF, which is a subprocess action and also causes output files to be created in the output directory. This file does not include a confirmation, user-visible log, or explicit warning describing that behavior.
The manifest describes a skill for searching, analyzing, summarizing papers, and extracting figures from open-access sources, but this file also includes a standalone PDFDownloader that fetches remote URLs and writes PDFs into a local downloads directory. Network retrieval may support the broader skill, but bundling download-and-store behavior inside the figure extraction module goes beyond the narrower behavior claimed by this module's own documentation and the manifest's emphasis on analysis outputs.
This code fetches remote content and writes it directly to a local PDF file, which affects user storage and system state. In this file there is no confirmation prompt, user-facing notice before the write, or explanatory comment/docstring warning about the download-and-save behavior.
This function performs an outbound request to OpenAlex using user-influenced input, creating an external transmission path. In the context of a research skill, such network access is expected, but it still represents a real privacy boundary crossing and could leak user-supplied names or research context to a third party.
def get_author_info(self, author_name: str) -> Dict:
"""Get author info from OpenAlex"""
try:
url = f"https://api.openalex.org/authors?search={author_name}&per_page=1"
response = requests.get(url, timeout=10)
data = response.json()
This function sends a user-controlled journal identifier to CrossRef over the network, which is a real external transmission of potentially sensitive query context. The skill's purpose makes this behavior functionally relevant rather than suspicious, so the primary risk is privacy/compliance exposure rather than code execution or direct compromise.
def get_journal_info(self, journal_name: str) -> Dict:
"""Get journal info from CrossRef"""
try:
url = f"https://api.crossref.org/journals/{journal_name}"
response = requests.get(url, timeout=10)
data = response.json()
The skill is designed to send search queries and metadata to external academic services such as OpenAlex. In context this is expected functionality rather than malicious exfiltration, but it still creates a real data-transmission surface that can leak sensitive user queries if not disclosed and controlled.
"db": "pubmed"
},
"openalex": {
"base_url": "https://api.openalex.org/works",
"per_page": 50
},
"doaj": {
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"base_url": "https://doaj.org/api/v2/search/articles"
},
"core": {
"base_url": "https://api.core.ac.uk/v3/works"
},
"semantic_scholar": {
"base_url": "https://api.semanticscholar.org/graph/v1/paper/search",
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"base_url": "https://doaj.org/api/v2/search/articles"
},
"core": {
"base_url": "https://api.core.ac.uk/v3/works"
},
"semantic_scholar": {
"base_url": "https://api.semanticscholar.org/graph/v1/paper/search",
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"base_url": "https://api.core.ac.uk/v3/works"
},
"semantic_scholar": {
"base_url": "https://api.semanticscholar.org/graph/v1/paper/search",
"limit": 50
},
"biorxiv": {
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"base_url": "https://api.core.ac.uk/v3/works"
},
"semantic_scholar": {
"base_url": "https://api.semanticscholar.org/graph/v1/paper/search",
"limit": 50
},
"biorxiv": {
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"base_url": "https://api.core.ac.uk/v3/works"
},
"semantic_scholar": {
"base_url": "https://api.semanticscholar.org/graph/v1/paper/search",
"limit": 50
},
"biorxiv": {
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"base_url": "https://api.core.ac.uk/v3/works"
},
"semantic_scholar": {
"base_url": "https://api.semanticscholar.org/graph/v1/paper/search",
"limit": 50
},
"biorxiv": {
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"limit": 50
},
"biorxiv": {
"base_url": "https://api.biorxiv.org/details/biorxiv"
},
"medrxiv": {
"base_url": "https://api.biorxiv.org/details/medrxiv"