Skip to content

Sanitize HTML in content returned by monitored instances - #5717

Merged
andreasfritz merged 4 commits into
masterfrom
fix/health-details-xss
Sep 25, 2026
Merged

andreasfritz merged 4 commits into
masterfrom
fix/health-details-xss

Conversation

@andreasfritz

Copy link
Copy Markdown
Contributor

No description provided.

String-valued health/info detail values from a monitored instance's
actuator response were inserted via v-html without sanitization,
while the sibling object-valued path already sanitized its output.
This allowed a malicious or compromised instance to store markup
that executes as script in an administrator's browser session
(stored XSS, CWE-79).

Apply the same sanitizeHtml() call used by sba-formatted-obj.vue
before autolinking the value.
A follow-up scan of every v-html usage in spring-boot-admin-server-ui
found three more sinks rendering untrusted, remote-instance-controlled
data without sanitization or escaping:

- env/refresh.vue: property names from an instance's /actuator/refresh
  response were concatenated into a raw HTML string and rendered via
  v-html. Replaced with a v-for/v-text list so Vue escapes each entry.

- NotificationFilterSettings.vue: the registered application/instance
  name (attacker-controlled at registration time) was interpolated
  into an i18n string containing literal <code> markup and rendered
  via v-html; vue-i18n does not escape interpolated params. Switched
  to <i18n-t> with a scoped slot so the name is rendered as text.

- m-bean-operation.vue: a JMX MBean operation name (controlled by the
  monitored JVM, e.g. a compromised instance) was interpolated the
  same way. Fixed identically with <i18n-t>.

Also switched sba-alert.vue's error message from v-html to v-text as
defense in depth, since Jolokia-derived error strings can originate
from a monitored instance and no legitimate use case needs HTML
rendering there.

Added regression tests asserting injected markup/scripts are never
parsed as HTML for the health-details, m-bean-operation, and
NotificationFilterSettings components.
Previous commit switched sba-alert.vue from v-html to v-text as a
blunt defense-in-depth measure, but error messages sometimes contain
intentional HTML (e.g. <strong>) that callers want rendered.

Keep v-html but sanitize the message through sanitizeHtml() first,
matching the pattern already used by sba-formatted-obj.vue and
health-details.vue. Safe markup renders; script tags and event
handler attributes are stripped.

Adds a dedicated spec file covering plain text, safe HTML, and
malicious payloads for both string and Error inputs.
A deeper audit of innerHTML/v-html sinks fed by application/instance
names uncovered a previously-missed vulnerable path: ActionHandler.ts
interpolates the attacker-controllable application name / instance id
into i18n strings (some containing literal <code> markup) and passes
the result to $sbaModal.confirm() and notificationCenter.success/
error(). Both render their message via innerHTML - functionally
identical to v-html - with no sanitization, for every restart/
shutdown/unregister confirmation dialog and result toast.

Wrap every such call in sanitizeHtml(), consistent with the pattern
already used in health-details.vue and sba-alert.vue. Restore the
<code>{name}</code> markup in the i18n files (previously stripped as
a workaround) now that the value is sanitized at the render boundary
instead of avoided via <i18n-t> + v-text.

Also revert NotificationFilterSettings.vue and m-bean-operation.vue
from the <i18n-t> + v-text workaround back to v-html + sanitizeHtml(),
so all v-html sinks in the codebase follow one consistent mitigation
pattern.

Adds ActionHandler.spec.ts (previously untested) covering all
shutdown/restart/unregister paths for both handlers, and updates the
NotificationFilterSettings/m-bean-operation specs to assert dangerous
markup is stripped while safe formatting tags are preserved.
Copilot AI lite review requested due to automatic review settings September 25, 2026 06:53
@andreasfritz
andreasfritz requested a review from a team as a code owner September 25, 2026 06:53
@andreasfritz
andreasfritz enabled auto-merge (squash) September 25, 2026 06:54

@ulischulte ulischulte left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

One or more issues must be addressed before approval.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
What changed in this PR

Hardens dynamic UI content against XSS while preserving safe formatting and autolinking.

Changes:

  • Sanitizes health details, modal headers, alerts, action messages, and notification settings.
  • Replaces environment refresh HTML construction with Vue text bindings.
  • Adds focused XSS regression tests.
File Description
spring-boot-admin-server-ui/​src/​main/​frontend/​views/​instances/​jolokia/​m-bean-operation.vue Updated as part of this pull request.
spring-boot-admin-server-ui/​src/​main/​frontend/​views/​instances/​jolokia/​m-bean-operation.spec.ts Updated as part of this pull request.
spring-boot-admin-server-ui/​src/​main/​frontend/​views/​instances/​env/​refresh.vue Updated as part of this pull request.
spring-boot-admin-server-ui/​src/​main/​frontend/​views/​instances/​details/​health-details.vue Updated as part of this pull request.
spring-boot-admin-server-ui/​src/​main/​frontend/​views/​instances/​details/​health-details.spec.ts Updated as part of this pull request.
spring-boot-admin-server-ui/​src/​main/​frontend/​views/​applications/​NotificationFilterSettings.vue Updated as part of this pull request.
spring-boot-admin-server-ui/​src/​main/​frontend/​views/​applications/​NotificationFilterSettings.spec.ts Updated as part of this pull request.
spring-boot-admin-server-ui/​src/​main/​frontend/​views/​applications/​ActionHandler.ts Updated as part of this pull request.
spring-boot-admin-server-ui/​src/​main/​frontend/​views/​applications/​ActionHandler.spec.ts Updated as part of this pull request.
spring-boot-admin-server-ui/​src/​main/​frontend/​components/​sba-alert.vue Updated as part of this pull request.
spring-boot-admin-server-ui/​src/​main/​frontend/​components/​sba-alert.spec.ts Updated as part of this pull request.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +24 to +28
sanitizeHtml(
t('applications.suppress_notifications_on', {
name: object.id || object.name,
}),
)
@hzpz hzpz changed the title Fix/health details xss Sanitize HTML in content returned by monitored instances Sep 25, 2026
@andreasfritz
andreasfritz merged commit 8717a2c into master Sep 25, 2026
2 checks passed
@andreasfritz
andreasfritz deleted the fix/health-details-xss branch September 25, 2026 07:04
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.

4 participants