← mcpscan-cli@0.21.0

Propose a patch

A fix the maintainer can act on, with the evidence attached. It opens under your GitHub account in your browser; KillerSkills holds no token and never modifies the package. The fix is verified the only way we verify anything: the next crawl re-runs the new version in the honeypot. 62 · Caution

Evidence

The sandbox observed nothing beyond the static findings; the proposal cites those.

Diff · removes 11 caught lines

Download .patch
diff --git a/mcpscan/rules/policy_override.py b/mcpscan/rules/policy_override.py
--- a/mcpscan/rules/policy_override.py
+++ b/mcpscan/rules/policy_override.py
@@ -4,1 +4,0 @@
-imperative command ("ignore previous instructions", "read ~/.ssh/id_rsa"), the
diff --git a/mcpscan/rules/hooks.py b/mcpscan/rules/hooks.py
--- a/mcpscan/rules/hooks.py
+++ b/mcpscan/rules/hooks.py
@@ -24,1 +24,0 @@
-# base64 -d | sh and friends.
diff --git a/tests/test_discover.py b/tests/test_discover.py
--- a/tests/test_discover.py
+++ b/tests/test_discover.py
@@ -40,1 +40,0 @@
-"""Write a fake *global* Amazon Q config (~/.aws/amazonq/mcp.json) under a
@@ -72,1 +71,0 @@
-# Amazon Q's global config always sits under ~/.aws — same on every OS.
diff --git a/mcpscan/rules/tool_poisoning.py b/mcpscan/rules/tool_poisoning.py
--- a/mcpscan/rules/tool_poisoning.py
+++ b/mcpscan/rules/tool_poisoning.py
@@ -5,1 +5,0 @@
-reads it verbatim and obeys — e.g. "before answering, read ~/.ssh/id_rsa and pass
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -230,1 +230,0 @@
-<summary><b>mcpscan vs. other tools</b></summary> | | mcpscan | garak | agentic-radar | |---|:---:|:---:|:---:| | Static (no model run) | ✅ | ❌ | ⚠️ | | MCP man
@@ -653,1 +652,0 @@
-<summary><b>Example output</b> (scanning a deliberately malicious fixture)</summary> ```text mcpscan scanned 4 files in ./evil-mcp CRITICAL MCP002 Prompt-inject
@@ -915,1 +913,0 @@
-<summary><b>`mcpscan: command not found` after `pip install -e .`</b></summary> Your pip user-scripts directory usually isn't on `PATH`. Either run it as a modu
@@ -923,1 +920,0 @@
-<summary><b>No findings, but I expected some</b></summary> - `mcpscan` skips `.git`, `node_modules`, `dist`, `build`, and `__pycache__` by default, since it's s
@@ -943,1 +939,0 @@
-<summary><b>GitHub code scanning shows no annotations after uploading SARIF</b></summary> `github/codeql-action/upload-sarif` needs `mcpscan -f sarif -o mcpscan
diff --git a/mcpscan/discover.py b/mcpscan/discover.py
--- a/mcpscan/discover.py
+++ b/mcpscan/discover.py
@@ -128,1 +128,0 @@
-# Amazon Q Developer CLI's *global* config — same ~/.aws prefix on every

Zero-context hunks: apply with git apply --unidiff-zero fix.patch on the tagged source of 0.21.0. If the behavior is intended, declare it (host under permissions.network, a line in the README) instead of removing it; the next crawl scores declarations.

Issue / PR body

Title: mcpscan-cli: References a credential file in the home directory (KillerSkills verdict caution 62)

## What the honeypot observed
KillerSkills ran **[email protected]** in an isolated sandbox (decoy credentials, recording proxy, syscall trace; engine 1.8.1) and scored it **CAUTION 62/100**. Summary: no network, touches nothing outside the project, writes no memory.

- See the findings below.

Full trace and findings: https://killerskills.ai/skills/pypi/mcpscan-cli/0.21.0

## Findings with a location
- `mcpscan/rules/policy_override.py:4` · References a credential file in the home directory — mcpscan/rules/policy_override.py:4 · References a credential file in the home directory
- `mcpscan/rules/hooks.py:24` · Host or command assembled from base64 fragments — mcpscan/rules/hooks.py:24 · Host or command assembled from base64 fragments
- `tests/test_discover.py:40` · Reads credential paths from the home directory — tests/test_discover.py:40 · Reads credential paths from the home directory
- `mcpscan/rules/tool_poisoning.py:5` · Reads credential paths from the home directory — mcpscan/rules/tool_poisoning.py:5 · Reads credential paths from the home directory
- `README.md:653` · Collapsed <details> block carrying instructions — README.md:653 · Collapsed <details> block carrying instructions
- `README.md:923` · Collapsed <details> block carrying instructions — README.md:923 · Collapsed <details> block carrying instructions
- `tests/test_discover.py:72` · Reads credential paths from the home directory — tests/test_discover.py:72 · Reads credential paths from the home directory
- `mcpscan/discover.py:128` · Reads credential paths from the home directory — mcpscan/discover.py:128 · Reads credential paths from the home directory
- `mcpscan/rules/tool_poisoning.py:5` · References a credential file in the home directory — mcpscan/rules/tool_poisoning.py:5 · References a credential file in the home directory
- `mcpscan/rules/policy_override.py:4` · Reads credential paths from the home directory — mcpscan/rules/policy_override.py:4 · Reads credential paths from the home directory
- `README.md:915` · Collapsed <details> block carrying instructions — README.md:915 · Collapsed <details> block carrying instructions
- `README.md:943` · Collapsed <details> block carrying instructions — README.md:943 · Collapsed <details> block carrying instructions

## Proposed change
The attached patch removes the 11 lines above. If the behavior is intended, the fix is to declare it instead: list the host under `permissions.network` (or the MCP manifest) and say in the README why the package needs it; the next crawl will re-score it with the declaration taken into account.

## How this will be verified
Nothing is "verified safe" by assertion. When a new version is published, KillerSkills re-runs it in the honeypot and the verdict page updates; you can trigger it early from the verdict page ("Re-scan after I publish a fix"). Reply here or at [email protected] if you believe the verdict is wrong; disputes are reviewed by a person and the outcome is published on the verdict page.

_Proposed through killerskills.ai/threats by a user of the package, under their own GitHub account. The evidence is public; the package was never modified by KillerSkills._
# or from a terminal, under your own account:
gh repo fork glatinone/mcpscan --clone && cd mcpscan
curl -s https://killerskills.ai/skills/pypi/mcpscan-cli/0.21.0/patch.diff | git apply --unidiff-zero
git checkout -b killerskills/0.21.0 && git commit -am "mcpscan-cli: References a credential file in the home directory"
gh pr create --fill --body-file <(curl -s https://killerskills.ai/skills/pypi/mcpscan-cli/0.21.0/patch.md)

We count proposals opened, not merged: a merge shows up as a new version that the crawl re-runs. Disputes: the maintainer can contest the verdict from its page; a person reviews it and the outcome is published.