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. 72 · Caution
Evidence
The sandbox observed nothing beyond the static findings; the proposal cites those.
Diff · removes 11 caught lines
Download .patchdiff --git a/README.md b/README.md --- a/README.md +++ b/README.md @@ -290,1 +290,0 @@ -<summary><strong>OAuth2 mode</strong> (multi-user, Redmine 6.1+)</summary> Each MCP request carries its own `Authorization: Bearer <token>`, so every user authe @@ -309,1 +308,0 @@ -<summary><strong>OAuthProxy mode</strong> (hosted deployments with client self-registration)</summary> FastMCP acts as the MCP-facing authorization server: it h @@ -329,1 +327,0 @@ -<summary><strong>api-key-login mode</strong> (per-user identity without OAuth: Easy Redmine, Redmine older than 6.1)</summary> The server acts as its own OAuth @@ -393,1 +390,0 @@ -<summary><strong>Visual Studio Code (Native MCP Support)</strong></summary> VS Code has built-in MCP support via GitHub Copilot (requires VS Code 1.102+). **Usi diff --git a/src/redmine_mcp_server/_errors.py b/src/redmine_mcp_server/_errors.py --- a/src/redmine_mcp_server/_errors.py +++ b/src/redmine_mcp_server/_errors.py @@ -38,1 +38,0 @@ -# HTTP basic auth embedded in URL: https://user:pass@host diff --git a/src/redmine_mcp_server/_oauth_proxy.py b/src/redmine_mcp_server/_oauth_proxy.py --- a/src/redmine_mcp_server/_oauth_proxy.py +++ b/src/redmine_mcp_server/_oauth_proxy.py @@ -100,1 +100,0 @@ -"proxy tokens and derive encrypted storage." diff --git a/src/redmine_mcp_server/_ssrf.py b/src/redmine_mcp_server/_ssrf.py --- a/src/redmine_mcp_server/_ssrf.py +++ b/src/redmine_mcp_server/_ssrf.py @@ -230,1 +230,0 @@ -# Embedded credentials (http://user:pass@host) would leak to any diff --git a/pages/index.html b/pages/index.html --- a/pages/index.html +++ b/pages/index.html @@ -15,1 +15,0 @@ -Loaded non-blocking (print→all swap) so first paint never waits on the cross-origin CSS; the fallback stacks render immediately and Geist swaps in. @@ -1250,1 +1249,0 @@ -<summary>Which Redmine versions are supported?</summary> <div class="qa-body"> <p>The integration suite passes in full against Redmine 6.1 and 7.0. Older versio @@ -1282,1 +1280,0 @@ -<summary>How does it handle a whole team rather than one user?</summary> <div class="qa-body"> <p>Several ways. A single shared API key is the simple default. O @@ -1298,1 +1295,0 @@ -<summary>What does it cost?</summary> <div class="qa-body"> <p>Nothing. It is MIT licensed, published on PyPI and GHCR, and listed in the official MCP Registry.
Zero-context hunks: apply with git apply --unidiff-zero fix.patch on the tagged source of 2.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: redmine-mcp-server: Collapsed <details> block carrying instructions (KillerSkills verdict caution 72)
## 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 72/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/redmine-mcp-server/2.21.0 ## Findings with a location - `README.md:290` · Collapsed <details> block carrying instructions — README.md:290 · Collapsed <details> block carrying instructions · informational: not an instruction file · informational: not an instruction file - `src/redmine_mcp_server/_errors.py:38` · URL with embedded credentials — src/redmine_mcp_server/_errors.py:38 · URL with embedded credentials — may be phishing or credential leaking - `README.md:329` · Collapsed <details> block carrying instructions — README.md:329 · Collapsed <details> block carrying instructions · informational: not an instruction file · informational: not an instruction file - `src/redmine_mcp_server/_oauth_proxy.py:100` · Credential pass-through configuration — src/redmine_mcp_server/_oauth_proxy.py:100 · Credential pass-through configuration — agent relays sensitive credentials - `README.md:309` · Collapsed <details> block carrying instructions — README.md:309 · Collapsed <details> block carrying instructions · informational: not an instruction file · informational: not an instruction file - `README.md:393` · Collapsed <details> block carrying instructions — README.md:393 · Collapsed <details> block carrying instructions · informational: not an instruction file · informational: not an instruction file - `src/redmine_mcp_server/_ssrf.py:230` · URL with embedded credentials — src/redmine_mcp_server/_ssrf.py:230 · URL with embedded credentials — may be phishing or credential leaking - `pages/index.html:1282` · Collapsed <details> block carrying instructions — pages/index.html:1282 · Collapsed <details> block carrying instructions · informational: not an instruction file · informational: not an instruction file · informational: not an instruction file - `pages/index.html:1298` · Collapsed <details> block carrying instructions — pages/index.html:1298 · Collapsed <details> block carrying instructions · informational: not an instruction file · informational: not an instruction file · informational: not an instruction file - `pages/index.html:1250` · Collapsed <details> block carrying instructions — pages/index.html:1250 · Collapsed <details> block carrying instructions · informational: not an instruction file · informational: not an instruction file · informational: not an instruction file - `pages/index.html:15` · HTML comment carrying imperative instructions to the agent — pages/index.html:15 · HTML comment carrying imperative instructions to the agent · informational: not an instruction file · informational: not an instruction file · informational: not an instruction f ## 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 jztan/redmine-mcp-server --clone && cd redmine-mcp-server curl -s https://killerskills.ai/skills/pypi/redmine-mcp-server/2.21.0/patch.diff | git apply --unidiff-zero git checkout -b killerskills/2.21.0 && git commit -am "redmine-mcp-server: Collapsed <details> block carrying instructions" gh pr create --fill --body-file <(curl -s https://killerskills.ai/skills/pypi/redmine-mcp-server/2.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.