Skip to content

🐛 Fixed unsafe notification HTML - #29756

Draft
9larsons wants to merge 1 commit into
mainfrom
codex/sanitize-notification-messages
Draft

🐛 Fixed unsafe notification HTML#29756
9larsons wants to merge 1 commit into
mainfrom
codex/sanitize-notification-messages

Conversation

@9larsons

@9larsons 9larsons commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

What changed

  • Sanitised notification messages on write and again on read so existing stored notifications are covered.
  • Reused the existing notification-email sanitisation policy for Admin notifications.
  • Preserved semantic HTML and safe links while removing scripts, event handlers, unsafe URLs, images, layout wrappers, and all inline CSS.
  • Rejected malformed non-string messages and safely neutralised legacy malformed values.

Why

Ghost Admin renders notification messages as HTML. The notification-creation permissions are restricted separately in #29754, but sanitisation is still needed at the rendering trust boundary for service-generated messages and existing stored data.

This follows the server-side sanitisation direction reported by @pptx704 in #29746. The client-side text rendering from that PR is intentionally omitted because normal release notifications rely on links.

Compatibility

The tests include the complete current critical-alert body and all four of its links, plus the current normal release message. The critical alert's inline presentation is intentionally removed; its full semantic content and links remain. This matches the sanitisation already applied to the notification email path. The internal mail-error producer emits plain text and is unchanged.

Testing

  • Notification service unit tests: 13 passed
  • Sanitizer unit tests: 4 passed
  • Notification email unit tests: 3 passed
  • Update-check unit tests: 14 passed
  • Notifications Admin API tests: 9 passed
  • TypeScript check
  • Focused ESLint
  • Commit hooks
  • Independent compatibility and adversarial review passes, repeated after fixes, with no remaining P1/P2 findings

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 5a5ea063-22df-4590-b9db-43e5d1b4f9d2

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nx-cloud

nx-cloud Bot commented Aug 4, 2026

Copy link
Copy Markdown

🤖 Nx Cloud AI Fix

Ensure the fix-ci command is configured to always run in your CI pipeline to get automatic fixes in future runs. For more information, please see https://nx.dev/ci/features/self-healing-ci


View your CI Pipeline Execution ↗ for commit ddb4670

Command Status Duration Result
nx run ghost:test:ci:integration ✅ Succeeded 3m 10s View ↗
nx run ghost:test:integration ✅ Succeeded 3m 28s View ↗
nx run ghost:test:e2e ✅ Succeeded 2m 47s View ↗
nx run ghost:test:legacy ✅ Succeeded 2m 48s View ↗
nx run ghost-monorepo:lint:boundaries ✅ Succeeded 21s View ↗
nx run-many -t test:unit -p ghost ✅ Succeeded 34s View ↗
nx run-many -t lint -p ghost,ghost-monorepo ✅ Succeeded 19s View ↗
nx run @tryghost/admin:build ✅ Succeeded 8s View ↗
nx run-many --target=build --projects=tag:publi... ✅ Succeeded <1s View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-08-04 17:43:18 UTC

@codecov

codecov Bot commented Aug 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 72.41379% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.54%. Comparing base (b08428f) to head (ddb4670).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
...ore/server/services/notifications/notifications.js 65.21% 8 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #29756      +/-   ##
==========================================
- Coverage   75.54%   75.54%   -0.01%     
==========================================
  Files        1614     1614              
  Lines      142570   142600      +30     
  Branches    17609    17615       +6     
==========================================
+ Hits       107702   107723      +21     
- Misses      33793    33801       +8     
- Partials     1075     1076       +1     
Flag Coverage Δ
e2e-tests 77.66% <72.41%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

ref #29746

Notification messages are rendered as trusted HTML in Admin. Sanitising on read and write protects both new and previously stored records while preserving semantic update-service content and links.
@9larsons
9larsons force-pushed the codex/sanitize-notification-messages branch from ee602dc to ddb4670 Compare August 4, 2026 17:31
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