feat(prompts): security-hardening for upstream prompt aggregation (F2/F10/F12) - #1005
Merged
Conversation
…/F10/F12) Step 2a of the PR #973 follow-up: bring aggregated upstream prompts to parity with the tool path's security controls. The feature remains OFF by default (aggregate_upstream_prompts=false); this hardens it for when a user opts in. - F2 (P1): scan + sanitise upstream prompt content. - Sanitise prompts/get results with the same detector + policy tool results get: redact secrets, strip control sequences, spotlight untrusted text, and block on a critical secret. Reaches TextContent and embedded text resources; binary/image/audio untouched. Extracts a shared saniseTextValue helper reused by the tool and prompt paths. - TPA-scan each aggregated prompt's name/description/argument descriptions at refresh time and drop any "dangerous" verdict, the analogue of tool- description poisoning detection. - F10 (P2): activity logging for prompts/get. New prompt_get activity type + event + emitter + handler (with sensitive-data detection over args/content), a minted request-id for `activity list --request-id` correlation, and the CLI --type allowlist entry. - F12 (P2): size + count caps. Per-message text truncated at 1 MiB (UTF-8-safe, clear marker), per-server prompt count capped at 200 and total aggregated at 1000 — all logged, never silent. The three layers compose in one getPromptAggregated getter (single upstream round-trip): fetch -> F12 size-cap -> F2 sanitise -> F10 log, sharing one request-id so the sanitisation policy_decision and prompt_get rows join. Tests: prompt-result sanitisation (redact/block/embedded), poisoned-description drop, UTF-8-safe truncation + size cap + nil-safety, per-server count cap, and prompt_get activity persistence. Deferred to step 2b (polish): per-prompt approval-hash/rug-pull baseline, list- metadata redaction, prompt name-collision/colon hardening, REST/UI expose_prompts wiring, pagination, and consuming upstream prompts/list_changed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H7J8Yv5zr4tMQZaY3ot3Za
Deploying mcpproxy-docs with
|
| Latest commit: |
bcec686
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://9e843cdf.mcpproxy-docs.pages.dev |
| Branch Preview URL: | https://feat-prompts-security-harden.mcpproxy-docs.pages.dev |
|
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
📦 Build ArtifactsWorkflow Run: View Run Available Artifacts
How to DownloadOption 1: GitHub Web UI (easiest)
Option 2: GitHub CLI gh run download 32225343916 --repo smart-mcp-proxy/mcpproxy-go
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Step 2a of the PR #973 follow-up. Brings aggregated upstream prompts to parity with the tool path's security controls. The feature stays OFF by default (
aggregate_upstream_prompts=false, shipped in #973); this hardens it for when a user opts in.What this closes (from the multi-model review of #973)
F2 (P1) — scan + sanitise upstream prompt content
Prompt names, descriptions, and message content previously reached the client with zero inspection, while the tool path scans and sanitises. Two layers:
prompts/getresults with the same detector + policy tool results get: redact secrets, strip control sequences, spotlight untrusted text, and block on a critical secret. ReachesTextContentand embedded text resources; binary/image/audio untouched. Extracts a sharedsanitiseTextValuehelper reused by both the tool and prompt paths."dangerous"verdict — the analogue of tool-description poisoning detection.F10 (P2) — activity logging for
prompts/getprompts/getwas invisible tomcpproxy activity listand telemetry. Adds aprompt_getactivity type + event + emitter + handler (with sensitive-data detection over args/content), a minted request-id foractivity list --request-idcorrelation, and the CLI--typeallowlist entry.F12 (P2) — size + count caps
No caps existed. Per-message text is truncated at 1 MiB (UTF-8-safe, clear marker); per-server prompt count is capped at 200 and the total aggregated list at 1000 — all logged, never silent.
Design
The three layers compose in one
getPromptAggregatedgetter (a single upstream round-trip): fetch → F12 size-cap → F2 sanitise → F10 log, sharing one request-id so the sanitisationpolicy_decisionandprompt_getrows join underactivity list --request-id.Tests
Prompt-result sanitisation (redact / block / embedded resource), poisoned-description drop, UTF-8-safe truncation + size cap + nil-safety, per-server count cap, and
prompt_getactivity persistence.Deferred to step 2b (polish)
Per-prompt approval-hash/rug-pull baseline, list-metadata redaction, prompt name-collision/
:-in-name hardening, per-server REST/UIexpose_promptswiring, pagination, and consuming upstreamprompts/list_changed.🤖 Generated with Claude Code