vercel / vercel/ai-elements

SchemaDisplayPath renders children via dangerouslySetInnerHTML without sanitisation

Open Beginner friendly
#486 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
2.4k
Forks
283
Avg merge
32m
Merged PRs (30d)
1

Description

Summary

SchemaDisplayPath in schema-display.tsx renders caller-supplied content through dangerouslySetInnerHTML without escaping, so any consumer that displays a schema originating outside the app is exposed to script injection.

Where

schema-display.tsx (~line 110):

const highlightedPath = path.replaceAll(
  /\{([^}]+)\}/g,
  '<span class="text-blue-600 dark:text-blue-400">{$1}</span>'
);

return (
  <span
    className={cn("font-mono text-sm", className)}
    dangerouslySetInnerHTML={{ __html: children ?? highlightedPath }}
    {...props}
  />
);

Both operands of the ?? are unsafe:

  • children is passed straight into __html with no sanitisation at all.
  • highlightedPath interpolates path into an HTML string via regex, so any markup already in path survives into the DOM.
Why it matters

The natural use for this component is rendering an API or tool schema, and those routinely come from somewhere other than the app itself — an MCP server's tool definitions being the obvious case in an AI SDK context. A schema path is not a trust boundary anyone thinks about, which is what makes this easy to hit by accident.

Suggested fix

No dangerouslySetInnerHTML is needed here — the highlighting can be expressed as React nodes, which escapes by construction:

const parts = path.split(/(\{[^}]+\})/g);

return (
  <span className={cn("font-mono text-sm", className)} {...props}>
    {children ?? parts.map((part, i) =>
      /^\{[^}]+\}$/.test(part) ? (
        <span key={i} className="text-blue-600 dark:text-blue-400">{part}</span>
      ) : (
        part
      )
    )}
  </span>
);

That also lets children be a normal React node rather than an HTML string, which is likely what callers expect.

Version

Found in ai-elements@1.9.0, installed via the shadcn registry.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading schema-display.tsx around line 110 and trace how SchemaDisplayPath receives path and children. Replace the unsafe HTML rendering with React-node rendering as outlined in the issue, then verify that schema content is displayed with highlighted brace segments while markup in path or children is escaped rather than interpreted.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend, security
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
84/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.