Added GHSA security advisory feed for Ghost vulnerabilities#27884
Added GHSA security advisory feed for Ghost vulnerabilities#27884rob-ghost wants to merge 2 commits into
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@ghost/core/core/server/services/notifications/feeds/run-worker.ts`:
- Around line 14-27: The current worker listens for parentPort.once('message')
and posts 'cancelled' on a 'cancel' message, but the async bootstrap still runs
permissions.init(), settings.init(), and fn() and then posts 'done', causing
both 'cancelled' and 'done' to be emitted and work to continue after
cancellation; fix by introducing a cancellation flag (e.g. let cancelled =
false) set to true inside the message handler for message === 'cancel' and check
that flag before running the init/ fn sequence (or abort early) and before
postMessage('done') so that if cancelled is true you skip calling fn() and do
not post 'done' (ensure the listener remains parentPort.once('message') and the
checks occur immediately before permissions.init()/fn() and before posting
'done').
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: c57d7c69-3f21-4627-991a-ef0826918099
📒 Files selected for processing (12)
ghost/core/core/boot.jsghost/core/core/server/services/mail/templates/critical-update.htmlghost/core/core/server/services/notifications/alert-email-reactor.tsghost/core/core/server/services/notifications/feeds/ghsa/index.tsghost/core/core/server/services/notifications/feeds/ghsa/worker.tsghost/core/core/server/services/notifications/feeds/run-worker.tsghost/core/core/server/services/notifications/index.jsghost/core/core/server/services/notifications/index.tsghost/core/core/server/services/notifications/notification.tsghost/core/core/server/services/notifications/service.tsghost/core/core/shared/config/defaults.jsonghost/core/test/integration/services/notifications/notification.test.ts
💤 Files with no reviewable changes (1)
- ghost/core/core/server/services/notifications/index.js
| parentPort.once('message', (message) => { | ||
| if (message === 'cancel') { | ||
| postMessage('cancelled'); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| (async () => { | ||
| try { | ||
| await permissions.init(); | ||
| await settings.init(); | ||
| await fn(); | ||
| postMessage('done'); | ||
| } finally { |
There was a problem hiding this comment.
Prevent post-cancel execution from reporting success.
Line 14-18 acknowledges 'cancel', but Line 23-26 still executes fn() and posts 'done'. This can produce contradictory worker states (cancelled + done) and still run work after cancellation.
Proposed fix
export function runWorker(fn: () => Promise<unknown>): void {
+ let cancelled = false;
+
if (parentPort) {
parentPort.once('message', (message) => {
if (message === 'cancel') {
+ cancelled = true;
postMessage('cancelled');
}
});
}
(async () => {
try {
await permissions.init();
await settings.init();
+ if (cancelled) {
+ return;
+ }
await fn();
- postMessage('done');
+ if (!cancelled) {
+ postMessage('done');
+ }
} finally {
if (!parentPort) {
setTimeout(() => process.exit(0), 1000);
}
}
})();
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@ghost/core/core/server/services/notifications/feeds/run-worker.ts` around
lines 14 - 27, The current worker listens for parentPort.once('message') and
posts 'cancelled' on a 'cancel' message, but the async bootstrap still runs
permissions.init(), settings.init(), and fn() and then posts 'done', causing
both 'cancelled' and 'done' to be emitted and work to continue after
cancellation; fix by introducing a cancellation flag (e.g. let cancelled =
false) set to true inside the message handler for message === 'cancel' and check
that flag before running the init/ fn sequence (or abort early) and before
postMessage('done') so that if cancelled is true you skip calling fn() and do
not post 'done' (ensure the listener remains parentPort.once('message') and the
checks occur immediately before permissions.init()/fn() and before posting
'done').
63dad01 to
c113035
Compare
Notifications carrying a template name now render via the mail content generator with their variables, producing both HTML and plaintext, while plain-message notifications keep the existing behaviour. This enables upcoming critical-update alerts to use a proper email template instead of inlining HTML in the notification message.
ref https://linear.app/tryghost/issue/BER-3651 Polls the GitHub Security Advisories API daily and surfaces published high/critical advisories that affect the running Ghost version as admin notifications. Critical advisories also send a templated alert email to administrators, while high-severity advisories show a dismissible banner only. The check honours updateCheck:enabled and is gated on a configurable advisoriesUrl so it can be disabled or pointed at a different source.
eddff05 to
02096a1
Compare
Problem
Ghost operators have no automated way to learn about security advisories affecting their installed version. Critical vulnerabilities can sit undeployed for days or weeks because admins only find out through external channels (mailing lists, GitHub watches, security bulletins).
Solution
Add a daily background job that polls GitHub's repository security advisories API for the Ghost package. Advisories matching the running version surface as in-admin banners; critical-severity advisories also trigger a templated email to all admin users.
Gated by the same
updateCheck.enabledflag as the existing update checker, so disabling telemetry disables advisory polling too. The feed lives inside the notifications domain as a downstream dependency, and a smallrunWorkerhelper handles the Bree worker bootstrap so future feeds can collapse to a one-line worker entry.Test plan
fetchAdvisories()against the live GitHub endpoint and confirm schema parses