Back to skill

Security audit

Pangolinfo Amazon Scraper

Security checks for vulnerabilities and agentic risk

Overview

This Amazon scraping skill is mostly coherent, but it asks the agent to handle user credentials and permanently cache a long-lived API key in a local plaintext file.

Only install this if you are comfortable giving the skill access to Pangolin credentials and having a reusable API key stored in your home directory. Prefer creating a dedicated, revocable Pangolin API key, avoid sharing passwords in chat, remove ~/.pangolin_api_key when finished, and monitor or rotate the key if it may have been exposed.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/pangolin.py:135
Finding

Permanent API Token Is Written Using Unsafe Non-Atomic File Handling

Content
View full analysis

Vulnerability Details

File Location: scripts/pangolin.py, lines 135-153
Vulnerability Type: Insecure secret storage and symbolic-link file overwrite
Risk Level: Medium

Vulnerable Code

python
def save_cached_api_key(api_key):
    """Save API key to cache file."""
    API_KEY_CACHE_PATH.write_text(api_key)
    try:
        API_KEY_CACHE_PATH.chmod(0o600)
    except OSError:
        pass
    # Windows: restrict file access to current user
    if sys.platform == "win32":
        try:
            import subprocess
            subprocess.run(
                ["icacls", str(API_KEY_CACHE_PATH), "/inheritance:r",
                 "/grant:r", f"{os.environ.get('USERNAME', '')}:F"],
                capture_output=True, check=False,
            )
        except Exception:
            pass

Technical Analysis

Path.write_text() creates or truncates the cache file before restrictive permissions are applied. The initial permissions therefore depend on the process umask. On systems with a permissive umask, the permanent API token may briefly or persistently be readable by other local users.

Permission-hardening failures are silently ignored. Consequently, the function can report successful authentication even when the token remains stored with insecure permissions.

The operation also follows an existing symbolic link. It does not verify that ~/.pangolin_api_key is a regular file owned by the current user. A local process capable of manipulating this path can redirect the write to another user-writable file or monitor the destination during creation. The token is documented as permanent, increasing the consequences of disclosure.

The Windows hardening command also uses check=False and suppresses all exceptions, so access-control failures do not prevent continued use of the insecure cache.

Attack Path

  1. A local malicious process running in a context that can manipulate ...[truncated 1501 chars]
Remediation
View remediation

Remediation Suggestions

  • Prefer an operating-system credential store such as Keychain, Credential Manager, or Secret Service instead of a plaintext file.
  • Make persistent caching opt-in and provide a command to remove or revoke the cached token.
  • On POSIX systems, create the file securely with os.open() using O_WRONLY | O_CREAT | O_EXCL, mode 0o600, and O_NOFOLLOW where supported.
  • For updates, write to a securely created temporary file in the same directory, flush it with fsync(), and atomically replace the validated destination.
  • Use lstat() to reject symbolic links and verify that an existing cache is a regular file owned by the current user.
  • Set restrictive permissions at creation time rather than writing first and calling chmod() afterward.
  • Fail closed if ownership or access-control hardening cannot be verified.
  • On Windows, check the icacls return code and stop caching if the ACL cannot be restricted.
  • Avoid printing any portion of the token unless diagnostic preview behavior is explicitly requested.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:85
Finding

Setup Instructions Encourage Disclosure of Long-Lived Credentials Through Chat and Shell History

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 85-106
Vulnerability Type: Insecure credential collection and handling guidance
Risk Level: Medium

Vulnerable Instructions

markdown
### Step 3: Collect credentials and authenticate automatically

When the user provides their credentials, **you (the AI agent) should configure them securely**. The script will automatically cache the API key at `~/.pangolin_api_key` for all future calls.

**If user provides an API key (recommended):**
Write it directly to the cache file — avoids shell history entirely:
```bash
echo "<api_key>" > ~/.pangolin_api_key
chmod 600 ~/.pangolin_api_key 2>/dev/null
python3 scripts/pangolin.py --auth-only

If user provides email + password: Set env vars in the session and clean up after auth:

bash
export PANGOLIN_EMAIL="user@example.com"
export PANGOLIN_PASSWORD="their-password"
python3 scripts/pangolin.py --auth-only
unset PANGOLIN_EMAIL PANGOLIN_PASSWORD

This avoids passwords appearing in shell history (unlike inline VAR=x command syntax) and cleans up credentials after the API key is cached.

text

### Technical Analysis

The Skill explicitly instructs the AI Agent to collect and configure the user's Pangolin credentials. Credentials supplied to an Agent may be retained in conversation transcripts, tool-call records, telemetry, or execution logs. This is unnecessary when authentication can be performed directly by the user through a private terminal prompt or vendor-controlled flow.

The shell-history claim is also inaccurate. When the displayed `export PANGOLIN_PASSWORD="their-password"` or `echo "<api_key>"` commands are entered interactively, the complete command can be recorded in shell history. Quoting the value does not prevent history retention.

Environment variables are inherited by child processes and can be exposed through debugging tools, crash reports, process
...[truncated 1699 chars]
Remediation
View remediation

Remediation Suggestions

  • Do not ask users to provide passwords or API keys in an AI conversation.
  • Direct users to authenticate locally through a masked getpass prompt, standard input, browser-based OAuth, or a vendor-managed device authorization flow.
  • If an API key must be entered locally, read it from a terminal prompt without echoing and pass it directly to secure storage.
  • Do not place credentials in command-line arguments or commands likely to be saved in shell history.
  • Clearly warn users that chat transcripts, shell history, environment variables, and tool logs may retain secrets.
  • Prefer short-lived, narrowly scoped, revocable tokens over permanent account tokens.
  • Avoid retaining the account password after token issuance.
  • Provide explicit token revocation, rotation, cache removal, and incident-response instructions.
  • Ensure logs and error messages redact full credentials and authorization headers.
  • Replace the claim that export avoids shell history with accurate platform-specific security guidance.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (19)

Tainted flow: 'req' from os.environ.get (line 388, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/pangolin.py (reported line 165)May include surrounding context.

python
method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            result = json.loads(resp.read())
    except urllib.error.URLError as e:
        # Improvement 1: macOS SSL certificate handling

Tainted flow: 'req' from os.environ.get (line 388, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/pangolin.py (reported line 394)May include surrounding context.

python
headers=headers,
                method="POST",
            )
            with urllib.request.urlopen(req, timeout=timeout) as resp:
                return json.loads(resp.read())

        except urllib.error.HTTPError as e:

Direct flow: os.environ.get (credential/environment) → subprocess.run (code execution)

High
Category
Data Flow
Confidence
80% confidence
Finding

Data flows directly from a source (env vars, files, network) to a sink (network output, exec, file write) without intermediate validation.

Content

Scanner excerpt · scripts/pangolin.py (reported line 146)May include surrounding context.

python
if sys.platform == "win32":
        try:
            import subprocess
            subprocess.run(
                ["icacls", str(API_KEY_CACHE_PATH), "/inheritance:r",
                 "/grant:r", f"{os.environ.get('USERNAME', '')}:F"],
                capture_output=True, check=False,

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill advertises and relies on high-risk capabilities including environment access, file reads/writes, network access, and shell execution, but does not declare any explicit tool scope or permissions boundary. That makes it easier for an agent runtime to over-grant capabilities and for users or reviewers to miss that the skill can persist secrets locally and execute commands, which meaningfully increases the attack surface.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
84% confidence
Finding

The setup flow explicitly encourages durable credential/session persistence by caching a permanent API key for future calls. In the context of a scraping skill, retaining reusable authentication material beyond the current task increases the blast radius of host compromise and enables unintended future access without renewed user intent.

Content

Scanner excerpt · SKILL.md (reported line 79)May include surrounding context.

md
### Step 2: Guide registration

> 1. Go to [pangolinfo.com](https://www.pangolinfo.com) and create an account
> 2. After login, find your API Key in the dashboard
>
> 1. 访问 [pangolinfo.com](https://www.pangolinfo.com) 注册账号

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation tells the agent to collect user credentials and persist an API key at ~/.pangolin_api_key for future reuse. For a data-retrieval scraper, instructing the agent to obtain and store secrets on disk creates a credential-handling role with lasting access, so compromise of the host, logs, or later agent actions could expose reusable secrets beyond the immediate task.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill directs permanent caching of an API key in the user's home directory without requiring a clear, explicit warning and consent flow about local credential persistence. A permanent cached key can silently outlive the user's immediate request and be reused by other processes, future sessions, or malicious code on the machine.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill provides shell commands that write API keys to disk and export credentials into the session environment. Even though it claims to avoid shell history, this still normalizes agent-mediated secret handling in shell contexts where secrets may leak via process inspection, terminal capture, audit logs, crash reports, or subsequent commands.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 93)May include surrounding context.

Write it directly to the cache file — avoids shell history entirely:

bash
echo "<api_key>" > ~/.pangolin_api_key
chmod 600 ~/.pangolin_api_key 2>/dev/null
python3 scripts/pangolin.py --auth-only

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · SKILL.md (reported line 119)May include surrounding context.

md
### Important

- **The user only needs to provide credentials ONCE** — the script caches the API key permanently at `~/.pangolin_api_key`
- Do not ask the user to manually edit `.bashrc` or `.zshrc` — the script handles persistence automatically
- If the user doesn't have an account yet, explain Pangolin's credit system (1 credit per Amazon json request, 5 credits per review page) and direct them to [pangolinfo.com](https://www.pangolinfo.com)
- If auth succeeds but credits are exhausted (error code `2001`), tell the user to top up at pangolinfo.com
- The API key is permanent and does not expire unless the account is deactivated

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file documents that the script will automatically re-authenticate with email/password, which implies use of sensitive credentials, but it provides no warning about privacy or security implications. Because SQP-2 applies to markdown files when descriptions omit warnings about behaviors affecting user data or system integrity, this is a valid missing-warning issue.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Documenting token caching at ~/.pangolin_token without any warning about file permissions or token persistence encourages storage of a long-lived authentication secret in a predictable local path. If the host is shared, backed up insecurely, or compromised by another local process, the token could be recovered and reused to access the Pangolin account and consume credits or retrieve account-linked data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The file instructs users to place account credentials in environment variables, which is sensitive authentication data, but it does not include any caution about shell history, process exposure, or secure handling. Under SQP-2 for markdown files, omission of such warnings is reportable.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

For a skill whose stated role is looking up Amazon data via Pangolin APIs, spawning icacls is an extra host-level capability unrelated to scraping itself. Even though it is used to harden the cache file, subprocess execution is a materially broader capability than the manifest implies.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/pangolin.py (reported line 146)May include surrounding context.

python
if sys.platform == "win32":
        try:
            import subprocess
            subprocess.run(
                ["icacls", str(API_KEY_CACHE_PATH), "/inheritance:r",
                 "/grant:r", f"{os.environ.get('USERNAME', '')}:F"],
                capture_output=True, check=False,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The script sends email and password values to the Pangolin authentication API over the network, but the user-facing description and help text do not explicitly warn that credentials will be transmitted for login. This is a network transmission of sensitive data, which falls under the warning requirement for code files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The client writes the API key to a predictable cache file in the user's home directory automatically and without explicit consent. Even with best-effort permissions, local secret persistence can expose long-lived credentials to other local processes, backups, misconfigured ACLs, or multi-user environments.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

This markdown file describes sending bizContext.zipcode to a third-party scraping endpoint, and later shows response fields containing review author and country data. Because SQP-2 applies to markdown files, the omission of any warning about privacy, third-party data transmission, or responsible handling of scraped personal/location-related data is a documentation safety gap.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The skill persists authentication material locally and exposes an authentication-only mode that returns an API key preview, which expands handling of sensitive secrets beyond simple scraping. In a scraping skill context, extra credential persistence increases the chance of secret disclosure on shared hosts or through unintended local access.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.