fix(mcp): run secret-redaction predicate on the new-server '+ Add' save path (#11265)#11360
Conversation
|
I'm starting a first review of this pull request. You can view the conversation on Warp. I completed the review and no human review was requested for this pull request. Comment Powered by Oz |
There was a problem hiding this comment.
Overview
This PR routes the new MCP server + Add save path through the same secret-redaction predicate used by the edit-existing flow and keeps the predicate gated on user or enterprise redaction settings.
Concerns
⚠️ [IMPORTANT] For this user-facing change, please include screenshots or a screen recording demonstrating the fixed+ Addsave path working end to end. The attached recording reproduces the pre-fix bypass with this PR's fix not applied, so it does not verify the user-visible behavior after the change.
Verdict
Found: 0 critical, 1 important, 0 suggestions
Request changes
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
|
Re-recorded the demo against a build with this PR's fix applied (PR #10839 predicate + this PR's new-server detection loop + DEMO-PATCH-B). Toast /oz-review |
|
I'm re-reviewing this pull request in response to a review request. You can view the conversation on Warp. I reviewed this pull request and requested human review from: Comment Powered by Oz |
Oz no longer requests changes for this pull request after the latest automated review.
There was a problem hiding this comment.
Overview
This PR adds the missing secret-redaction check to the new MCP server + Add save path and updates the shared predicate so saves are blocked only when user or enterprise secret redaction is active. The attached spec context contains no approved spec commitments, and the PR description includes end-to-end visual evidence for the user-facing behavior.
Concerns
- No blocking correctness, spec-alignment, or security concerns found in the annotated diff.
Verdict
Found: 0 critical, 0 important, 0 suggestions
Approve
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
…ig (warpdotdev#8761) When a user defines an MCP server config (Settings → MCP Servers → Add) that contains a value matching the secret-detection regexes — for example, `"Authorization": "Bearer <real-token>"` — the save was rejected with the error "This MCP server contains secrets. Visit Settings > Privacy to modify your secret redaction settings." *even when the user had explicitly disabled secret redaction in Settings → Privacy*. Root cause: `detect_secrets_in_templatable_mcp_server` in `settings_view::mcp_servers::edit_page` called `find_secrets_in_text` unconditionally and rejected the save if any match was found, without consulting the user's redaction-enabled toggle or the workspace-level enterprise-enforcement flag. The error message itself told the user to visit the Privacy settings — but those settings had no effect on this code path. Fix: gate the save-blocking decision on whether redaction is actually in force. Extracted a pure `should_block_save_for_secrets(safe_mode_enabled, enterprise_enforced, contains_secrets)` predicate so the policy is one expression in one place: (safe_mode_enabled || enterprise_enforced) && contains_secrets When both the user-level toggle (`SafeModeSettings::safe_mode_enabled`) AND the enterprise enforcement flag (`UserWorkspaces::is_enterprise_secret_redaction_enabled`) are off, the user has explicitly opted to embed secrets in the config and we save it as written. Enterprise enforcement still wins over a personal toggle — orgs that mandate redaction cannot be bypassed at the MCP-config layer. Tests: 5 unit tests covering the predicate's truth table: - does_not_block_when_redaction_off_even_if_secrets_present (the warpdotdev#8761 case) - blocks_when_user_redaction_on_and_secrets_present - blocks_when_enterprise_enforced_and_secrets_present - does_not_block_when_no_secrets_regardless_of_toggle (2x2 sweep) - blocks_when_both_redactions_on_and_secrets_present Verified locally: cargo nextest run -p warp -E 'test(should_block_save_for_secrets) or test(does_not_block_when) or test(blocks_when_)' 5 tests run: 5 passed cargo clippy -p warp --tests -- -D warnings Finished (no warnings) cargo fmt -p warp -- --check clean Fixes warpdotdev#8761 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ve path (warpdotdev#11265) The new-MCP-server save branch in `MCPServersEditPageView::handle_action` calls `ParsedTemplatableMCPServerResult::from_user_json` directly and skips `parse_templatable_json` — which is where warpdotdev#10839's predicate (`detect_secrets_in_templatable_mcp_server` → `should_block_save_for_secrets`) is invoked. As a result, a config pasted into `+ Add` and saved bypasses the redaction check entirely even with Settings → Privacy → Secret redaction enabled or enterprise enforcement active. The same JSON saved via the edit-existing flow is correctly blocked. Mirror the existing per-parsed-server detection loop from `parse_templatable_json` into the new-server branch. The predicate itself (added in warpdotdev#10839 with five truth-table tests) is unchanged — this PR closes the gap by routing the `+ Add` path through it. ## Reproduction Recipe + recording: https://github.com/david-engelmann/warp-taper/blob/main/scripts/recipes/11265-mcp-add-server-bypass.json Evidence GIF: https://raw.githubusercontent.com/david-engelmann/warp-taper/main/docs/evidence/11265-mcp-add-server-bypass/master.gif (also posted in the warpdotdev#11265 issue thread) ## Testing ``` $ cargo nextest run -p warp -E 'test(should_block_save_for_secrets) or test(does_not_block_when) or test(blocks_when_)' 5 tests run: 5 passed $ cargo clippy -p warp --tests -- -D warnings clean $ cargo fmt -p warp -- --check clean ``` Fixes warpdotdev#11265 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
c330c49 to
edad1bc
Compare
|
Rebased to clear the merge conflict from recent master movement. Rebuilt on top of #10839's current head ( Dependency unchanged: still stacked on #10839 (the |
|
Hey @david-engelmann, I'm taking over here on review. Will take a look later today! |
|
Hey @david-engelmann, thanks for the PR and for filing this issue! I took a peek, for now I'm working on merging in this PR, which predates yours by a few hours. It's not super relevant now anyways, but for reference I found a few issues with your PR on first glance. Namely, I think you re-iterate logic that already appears in |
|
Closing per the comment above. |
Description
The new-MCP-server save branch in
MCPServersEditPageView::handle_actioncallsParsedTemplatableMCPServerResult::from_user_json(&json)directly and skipsparse_templatable_json— which is where #10839's predicate (detect_secrets_in_templatable_mcp_server→should_block_save_for_secrets) is invoked. As a result, a config pasted into the + Add dialog and saved bypasses the redaction check entirely, even withSettings → Privacy → Secret redactionenabled or enterprise enforcement active. The same JSON saved via the edit-existing flow is correctly blocked.Fix
Mirror the existing per-parsed-server detection loop from
parse_templatable_jsoninto the new-server branch inapp/src/settings_view/mcp_servers/edit_page.rs:The predicate itself (added in #10839 with the truth-table tests) is unchanged — this PR closes the gap by routing the
+ Addpath through it. Net diff: +17 / -0 lines.Stacked on #10839
This PR depends on
should_block_save_for_secretsanddetect_secrets_in_templatable_mcp_serverfrom #10839. The branch was cut fromdavid/8761-mcp-secret-redaction-config-save(the #10839 branch); once #10839 merges, the GitHub diff here will narrow to just the new-server-branch loop.Demo — fix in action
End-to-end Settings UI recording demonstrating the fix. Build state for this recording: PR #10839's predicate + this PR's new-server detection loop + DEMO-PATCH-B (so
SECRETS_REGEXrecompiles when the toggle is flipped — needed to demonstrate this PR's fix in isolation; the underlying recompile gap is tracked at #11262). The token sits in the top-levelurlto keep the demo isolated from #11263's env/headers templatization gap.safe_mode_enabled = trueat runtime).+ Add→ paste a config withsk-FAKE0000000000FAKEdemoWARP11360fixin the top-levelurl.MY MCPS.Recipe:
scripts/recipes/11360-mcp-add-server-fix.json, driven byscripts/warp-driver.swift(OCR-gated, no manual driving).Demo — pre-fix bypass (for contrast)
The earlier reproduction recording shows the same save proceeding silently against the unpatched build:
Build state: DEMO-PATCH-B + DEMO-PATCH-C applied locally (the proposed fixes for #11262 / #11263), this PR's fix not applied — so the bug is fully isolated to the
+ Addsave branch. Phases:+ Add→ paste a baseline (no-secret) configdemo-baseline-11265→ Save → established inMY MCPS. Establishes a server for the control comparison.+ Addagain → paste a config withsk-FAKE0000000000FAKEdemoWARP11265in the top-levelurl→ Save → server lands inMY MCPSasdemo-add-bypass-11265. BUG: the new-server save bypassed the predicate entirely.Recipe:
scripts/recipes/11265-mcp-add-server-bypass.json.Testing
The predicate's existing 5-case truth-table tests (from #10839) continue to cover the logic — this PR only adds a new call site, not new logic. The local-repro recording above exercises the new call site end-to-end.
Server API dependencies
None — this is client-only.
Agent Mode
Unchecked (external contribution).
Changelog
CHANGELOG-BUG-FIX: Defining a new MCP server via Settings → MCP Servers → + Add no longer bypasses the secret-redaction check when Settings → Privacy → Secret redaction (or enterprise enforcement) is active.Fixes #11265