Back to skill

Security audit

ANNE Library Downloader

Security checks for vulnerabilities and agentic risk

Overview

This skill is aimed at academic downloading, but it asks for institutional credentials and bulk access without enough safety boundaries or disclosure.

Review this skill carefully before installing. Only use it with accounts and materials you are authorized to access, avoid storing institutional passwords in shell history or shared environments, and treat the Playwright/Node helper and unpinned dependencies as issues that should be fixed before relying on automated downloads.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/download.py:87
Finding

JavaScript Injection Through Unescaped URL Interpolation

Content
View full analysis
{{ const browser = await chromium.launch({{ headless: true }}); const context = await browser.newContext(); const page = await context.newPage(); // Navigate to URL await page.goto('{url}', {{ waitUntil: 'networkidle' }}); // Wait for content await page.waitForTimeout(2000); // Handle authentication if needed // (Would need credentials for institutional access) // Get PDF link or download directly const pdfLink = await page.$('a[href$=".pdf"]'); if (pdfLink) {{ const href = await pdfLink.getAttribute('href'); console.log(href); }} await browser.close(); }})(); ''' # Save and run script with tempfile.NamedTemporaryFile(mode='w', suffix='.js', delete=False) as f: f.write(script) temp_path = f.name try: result = subprocess.run(['node', temp_path], capture_output=True, text=True) return result.stdout.strip() ``` ### Technical Analysis The `url` parameter is inserted directly into a generated JavaScript program inside a single-quoted string. No JavaScript-safe encoding, validation, or separation between code and data is applied. An attacker-controlled URL containing a single quote can terminate the argument to `page.goto()`. The attacker can then append arbitrary JavaScript and comment out the remaining generated source. Because the resulting temporary file is executed using Node.js, injected JavaScript has access to Node APIs, including `child_process`, filesystem operations, environment variables, and n ...[truncated 1704 chars]
Remediation
View remediation
{ const url = process.argv[2]; const browser = await chromium.launch({ headless: true }); const context = await browser.newContext(); const page = await context.newPage(); await page.goto(url, { waitUntil: 'networkidle' }); await browser.close(); })(); ''' result = subprocess.run( ['node', temp_path, url], capture_output=True, text=True, check=True ) ``` ]]>

T08 · Insecure Dependencies

Warning
Location
claw.json:10
Finding

Unpinned and Unverified Third-Party Dependencies

Content
View full analysis
=1.40.0", "requests": ">=2.28.0", "beautifulsoup4": ">=4.12.0" } ``` `SKILL.md:14-20`: ```bash # Install dependencies pip install playwright requests beautifulsoup4 # Install browser for Playwright playwright install chromium ``` ### Technical Analysis The dependency declarations permit any version greater than or equal to the listed minimum versions. The installation instructions are even less restrictive and install whatever versions the package index currently resolves. No lock file, artifact hashes, upper bounds, trusted index configuration, or pinned Playwright browser revision is supplied. Consequently, separate installations can receive different package and browser versions. If a future release is compromised, malicious, or incompatible, it can enter the environment without a source change or renewed review of this Skill. The audited names correspond to common packages, and no evidence in the reviewed project establishes that the currently named dependencies are malicious. The risk arises from mutable and unverified resolution rather than a confirmed malicious package. ### Attack Path 1. A user follows the documented installation commands or a package manager resolves the ranges in `claw.json`. 2. The installer queries its configured package source and selects the latest matching artifacts. 3. A compromised upstream release, package-index account, mirror, or dependency artifact is selected. 4. The package is installed without comparison against a reviewed lock file or cryptographic hash. 5. Malicious package code may execute during installation or when imported by the Skill. 6. `playwright install chromium` also retrieves a browser artifact whose revision is not explicit ...[truncated 562 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (6)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly promotes automated authentication to institutional library systems and bulk downloading from multiple academic platforms, but provides no warning about privacy, credential handling, terms-of-service restrictions, or the potential operational impact of automation on third-party systems. In this context, the omission is security-relevant because users may supply institutional credentials and run large-scale automation without understanding the risks of account lockout, credential exposure, or abusive access patterns.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation instructs users to place library usernames and passwords in environment variables without any warning about the sensitivity of those secrets or the risks of exposure through shell history, process inspection, shared environments, or misconfigured logging. Because these are institutional credentials used for automated access, mishandling could lead to unauthorized account use, account compromise, or broader access to licensed resources.

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/download.py (reported line 75)May include surrounding context.

python
# Try Crossref API
    query = f"{title} {author}".strip()
    url = f"https://api.crossref.org/works?query={quote(query)}&rows=1"
    
    try:
        response = requests.get(url, timeout=10)

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
84% confidence
Finding

The code writes attacker-controlled URL content directly into a temporary JavaScript file and executes it with Node. Because the URL is interpolated into a single-quoted JS string without escaping, a crafted URL containing quotes can break out of the string and achieve arbitrary JavaScript execution on the host running the skill.

Content

Scanner excerpt · scripts/download.py (reported line 123)May include surrounding context.

python
temp_path = f.name
    
    try:
        result = subprocess.run(['node', temp_path], capture_output=True, text=True)
        return result.stdout.strip()
    finally:
        os.unlink(temp_path)

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The code constructs a Crossref API query from the user's book title and author and transmits it over the network. Although there is an error print, there is no user-facing disclosure here that search terms will be sent to an external service, which is a privacy-relevant network action.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

This function writes a temporary .js file to disk and invokes it via Node using subprocess. While the operation may be part of the implementation, the function contains no confirmation or user-facing notice about creating a file and launching an external process.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.