Replace eval-based JS interop with named functions in polypilot-interop.js#219
Replace eval-based JS interop with named functions in polypilot-interop.js#219
Conversation
Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>
🔍 Multi-Model Code Review — PR #219Reviewed by: Claude Opus 4.6, Claude Sonnet 4.6, GPT-5.3 Codex Overall this is a strong security improvement — replacing ~26 🔴 CRITICAL —
|
| # | Severity | Finding | Models |
|---|---|---|---|
| 1 | 🔴 | setAppFontSize undefined — runtime crash on font size |
Opus + verified |
| 2 | 🔴 | clearElementValue undefined — runtime crash on search clear |
Opus + verified |
| 3 | 🟡 | Needs rebase — agent click handler + ShowLogPopup callers diverged | Sonnet + verified |
| 4 | 🟢 | Double semicolon typo | Opus + Sonnet |
Recommended action:
- Add the 2 missing function definitions to
polypilot-interop.js - Rebase onto current
mainand migrate the newShowAgentsPopupclick handler +ShowLogPopupcallers - Fix double semicolon
Once addressed, this is a solid security improvement ready to merge.
~26 instances of
JS.InvokeVoidAsync("eval", $"...")across 5 Razor files interpolated C# values directly into JS strings — an XSS/injection surface. Replaced all of them with parameterized calls to named global functions.New:
wwwroot/js/polypilot-interop.jsNamed functions covering every eval use case:
setThemeAttribute(theme)eval($"...setAttribute('data-theme', '{dataTheme}')")startSidebarResize(startX)eval($"...var startX = {e.ClientX}...")setInputValue(id, value, cursorAtStart)eval($"...'{inputId}'...{JsonSerializer.Serialize(text)}...")showPopup(trigger, headerHtml, contentHtml)showPromptsPopup(..., sessionName)CSS.escape()for safe selector constructionensureDashboardKeyHandlers()focusAndSelect(id),focusAndSetValue(id, val)getElementById+ focus/value evalsclearDashRef(),clearSettingsRef()wireSettingsSearch(),wireSessionNameInputEnter()ensureTextareaAutoResize(),ensureLoadMoreObserver(),scrollMessagesToBottom()Pre-defines
window.__setDashRefandwindow.__setSettingsRefso the evals that dynamically defined them are removed entirely.Call-site changes
Before:
After:
Cleanup
EscapeForJshelper inExpandedSessionView.razorremoved (was only needed to embed C# values into JS strings)EscapeForJson HTML before passing it — strings are now passed as parameters, not codeOriginal prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.