Skip to content

[BUG]: Alpine.js standard build requires 'unsafe-eval', blocking CSP hardeningΒ #4653

@marekdano

Description

@marekdano

🐞 Bug Summary

The admin UI loads the standard Alpine.js CDN build (admin.html:286–291), which evaluates template expressions via Function() at runtime. This requires 'unsafe-eval' in script-src. Any effort to remove 'unsafe-eval' from the Content Security Policy will silently break all Alpine directives (x-data, x-show, x-bind, @click, etc.) across the admin panel.


🧩 Affected Component

Select the area of the project impacted:

  • mcpgateway - API
  • mcpgateway - UI (admin panel)
  • mcpgateway.wrapper - stdio wrapper
  • Federation or Transports
  • CLI, Makefiles, or shell scripts
  • Container setup (Docker/Podman/Compose)
  • Other (explain below)

πŸ” Steps to Reproduce

  1. Deploy the admin UI with a CSP that omits 'unsafe-eval' from script-src
  2. Open the admin panel in a browser
  3. Open the browser console

πŸ€” Expected Behaviour

Alpine directives render and respond to interaction normally under a strict CSP.

πŸ““ Logs / Error Output

Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src ...".

All x-data components, x-show toggles, @click handlers, and x-for loops fail silently.


🧩 Additional Context

Root cause: The standard Alpine.js build (alpinejs on npm / jsDelivr CDN) compiles expressions at runtime using new Function(). The CSP build (@alpinejs/csp) ships pre-compiled expression evaluators and does not require 'unsafe-eval'.

Affected scope: All 20 admin templates using Alpine directives (~228 directive usages), including observability views, tool cards, overflow menus, and the dark-mode toggle.

Two viable paths:

  1. Switch to @alpinejs/csp β€” replace the CDN script tag and npm dependency with @alpinejs/csp. The CSP build is API-compatible but requires that complex expressions (ternaries, method calls) be moved into x-data object definitions rather than inline attribute strings. Some directives in the current templates may need light refactoring.
  2. Bundle Alpine into the Vite output β€” import Alpine in mcpgateway/admin_ui/index.js, remove it from the external array in vite.config.js, and drop the CDN script tag. If using the standard build, this does not remove the 'unsafe-eval' requirement; it must be combined with option 1 to be effective.

Related: The admin bundle already excludes Alpine as an external global (window.Alpine). The alpinejs npm package is pinned at 3.15.11 in package-lock.json.

Related: PR #4424 (CSP hardening) identified this gap β€” the policy introduced there cannot be fully enforced until these handlers are migrated.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingsecurityImproves securityuiUser Interface

Type

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions