Skip to content

fix: escape user-controlled query in HTML title to prevent injection#8

Open
AmSach wants to merge 1 commit into
frost-beta:mainfrom
AmSach:fix/html-injection-presentResults
Open

fix: escape user-controlled query in HTML title to prevent injection#8
AmSach wants to merge 1 commit into
frost-beta:mainfrom
AmSach:fix/html-injection-presentResults

Conversation

@AmSach

@AmSach AmSach commented Jun 18, 2026

Copy link
Copy Markdown

Summary

presentResults() embeds the user's search query directly into an HTML <title> element using template literal interpolation. Because the generated HTML file is then opened in the user's default browser, a query string containing characters such as </title><script>..., attribute-breaking quotes, or <img onerror=...> payloads is rendered verbatim. This is a self-XSS at minimum (since the file is opened on the user's own machine) but is still a real correctness/security bug: any code embedded this way executes with the privileges of the page that is being opened.

Reproduction

Run any successful search:

sisi search '</title><script>alert(1)</script>'

The HTML file written to os.tmpdir() and opened in the browser contains a <script> tag that breaks out of the title.

Fix

Add a small escapeHtml() helper that HTML-encodes &, <, >, " and ', and apply it to the query when building the title in src/search.ts. Filenames are already passed through pathToFileURL(), which percent-encodes special characters, so they remain safe inside the existing href / src attributes.

Diff

+function escapeHtml(value: string): string {
+  return value
+    .replace(/&/g, '&amp;')
+    .replace(/</g, '&lt;')
+    .replace(/>/g, '&gt;')
+    .replace(/"/g, '&quot;')
+    .replace(/'/g, '&#39;');
+}
...
-<title>sisi search "${query}"</title>
+<title>sisi search "${escapeHtml(query)}"</title>

Found while browsing the codebase — happy to iterate if you'd prefer a different approach. — Sent via @AmSach bot

The presentResults() function embeds the user's search query directly into
an HTML <title> tag using template literal interpolation. A query string
such as </title><script>alert(1)</script> was rendered verbatim into the
result page that is opened in the user's browser, allowing arbitrary
HTML/JavaScript injection.

Add an escapeHtml() helper and apply it to the query when building the
title so untrusted characters are HTML-encoded before being written to
the page.
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