Skip to content

docs(ai): spec for #37153 escape dotAI viewtool output by default - #37533

Open
hassandotcms wants to merge 1 commit into
mainfrom
37153-ai-viewtool-escape-output
Open

hassandotcms wants to merge 1 commit into
mainfrom
37153-ai-viewtool-escape-output

Conversation

@hassandotcms

Copy link
Copy Markdown
Contributor

Spec only (PR 1 of 2) for #37153. Part of epic #37255 (dotAI Security Hardening). Full issue detail is in dotCMS/private-issues#675.

Problem

The $ai Velocity viewtool hands the AI provider's reply to templates exactly as returned. Nothing escapes it, and dotCMS Velocity does not auto-escape references. A template that prints the model's answer ($summary.openAiResponse.choices.get(0).message.content, as documented) renders whatever HTML the model emitted. A model steered by indexed content or a crafted prompt can emit <img src=x onerror=...>, and the script runs for every visitor of that page. The unsafe path is the default.

Proposed fix

Escape by default, by source. Every call through $ai returns a copy of the payload in which exactly four things are HTML-escaped with the OWASP encoder:

  1. everything the provider returned (the whole payload of raw, generateText, generateImage; the openAiResponse subtree of summarize);
  2. the echoed query;
  3. the echoed image originalPrompt;
  4. the search excerpt dotCMSResults[].matches[].extractedText, because the embeddings API stores every visitor's query text in an index named cache, and a template can search that index.

Nothing else changes. Contentlet fields in search results, including title, are returned as today, the same as $dotcontent gives them. Payload shape and type are unchanged, so existing property paths keep resolving.

One opt-in: $ai.unsafe. Same tool, escaping off, exactly today's behavior for every method. No per-method *Unescaped siblings, no config flag.

Not in scope

REST endpoints (/api/v1/ai/*) are untouched. No sanitizing, no config kill-switch, no changes to what the model is asked (#37152), retrieval permissions (#37151), rate limiting (#37155) or stack traces (#37154, same classes, no dependency either way).

Impact

Template contract change on the success path only. Model output that contains markup renders as text until the author switches to $ai.unsafe. Templates that already escape the output themselves will double-encode. A release note for template authors is a deliverable of PR 2. No API, schema or data changes. Rollback-safe.

Please review specs/37153-ai-viewtool-escape-output/spec.md. The payload-shapes block near the top shows every field the spec refers to. On approval, planning and implementation follow in PR 2.

This PR fixes: #37153

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

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

dotAI: escape viewtool output by default

1 participant