Skip to content

fix(scan): show every submitter-typed value to the security agent as untrusted - #475

Open
deanrie wants to merge 1 commit into
cursor:mainfrom
deanrie:fix/scan-prompt-untrusted-fields
Open

deanrie wants to merge 1 commit into
cursor:mainfrom
deanrie:fix/scan-prompt-untrusted-fields

Conversation

@deanrie

@deanrie deanrie commented Oct 26, 2026

Copy link
Copy Markdown

What

The security scan prompt now shows every value a submitter typed between the <<<UNTRUSTED>>> delimiters, not only each component's content, and a delimiter that a submitter writes inside a value is rewritten so it cannot close the block early.

Why

The prompt's first rule tells the agent that anything between the delimiters is user-submitted and must be treated as data. On main only content is between them. The plugin's name, description, repository, homepage and keywords, each component's name, slug, description and metadata, and the name, slug and repository of every similar plugin under POTENTIAL DUPLICATES are interpolated as plain prompt text, which that rule implicitly marks as trusted. The similar-plugin names belong to other submitters, so one listing can steer the scans of later plugins with a close name.

The content block is not sealed either: content may contain <<</UNTRUSTED>>>, which ends the block, and whatever follows reads as prompt.

Change

  • buildPrompt moves to a pure module, lib/plugins/scan-prompt.ts (buildScanPrompt, untrusted(), the delimiter constants), so the text can be checked without the SDK or Supabase. scan.ts imports it; SimilarPluginRow is defined there and re-exported from scan.ts as before.
  • untrusted(value) rewrites any <<<UNTRUSTED>>> / <<</UNTRUSTED>>> inside the value (any case, inner spaces) to <<<DELIMITER-IN-CONTENT>>>, then wraps it.
  • Every submitter-typed value goes through untrusted(). The instructions say the blocks hold text typed by this plugin's submitter and by other submitters, and that the rewritten marker is itself prompt_injection evidence. Section headers say who typed what. Component type, the similarity score and the repo sentence stay as plain text.
  • The verdict schema, categories, severities and the OUTPUT section are unchanged.

Checked

This is defence in depth: a model can still be argued into a verdict by text it was told to distrust, and the admin review queue remains the backstop. It does make the prompt match its own first rule.

…untrusted, and neutralise delimiters inside values
@vercel

vercel Bot commented Oct 26, 2026

Copy link
Copy Markdown

@deanrie is attempting to deploy a commit to the Anysphere Team on Vercel.

A member of the Team first needs to authorize it.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant