Hacked Ghost CMS: What to Check

By · Updated · 4 min read

Ghost is a comparatively lean platform with no plugin ecosystem in the WordPress sense, which removes the single largest source of compromise on most sites. That makes a Ghost compromise less likely and also easier to diagnose, because the list of things that can have gone wrong is genuinely short.

The smaller attack surface

There is no third-party plugin directory, which eliminates the vulnerability class responsible for most WordPress compromises. The application is a Node process rather than PHP files served directly, so the classic uploaded-shell attack does not apply in the same way. Ghost also updates cleanly, which means running current is less painful than on most platforms.

What remains: the version you are running, your admin credentials, your theme, the code injection fields, integrations and API keys, and the server itself if you self-host. That is the whole list, and you can work through it in an afternoon.

Version and self-hosting

If you are on Ghost Pro, the hosted service, the platform and server are managed for you and the realistic attack surface narrows to your account and your content. If you self-host, you own the version, the Node runtime, the database and the server, and an outdated install is the most likely technical cause of a compromise.

Check your version against current, and check whether the server underneath has been maintained — a Ghost site on a server nobody has patched in three years has a problem that is not really about Ghost. My guide on compromised Node applications covers the runtime side.

Code injection fields and themes

Ghost provides site-wide header and footer code injection fields, plus per-post equivalents. They exist for legitimate reasons — analytics, fonts, widgets — and they are exactly where injected JavaScript would be placed by anyone with admin access, because it takes effect site-wide without touching a single file.

Check those fields first, at both site and post level. Then check your theme for scripts you did not add, comparing against a clean copy if you have one. My guide on injected JavaScript covers telling a malicious script from your legitimate analytics.

Staff accounts and integrations

Review your staff users and remove anyone who should not be there or no longer needs access. Check the roles assigned, since contributor and author roles are less dangerous than administrator and the distinction matters.

Then check your integrations and custom API keys. Those are independent credentials with programmatic access to your content, they survive a password change entirely, and they are the standard way an attacker retains access to a site that has otherwise been secured. Revoke anything you do not recognize and reissue what you need.

If you run memberships

Ghost's membership and subscription features mean the database may hold member email addresses and subscription details, with payment processing handled by your connected payment provider. If the database was reachable, treat member data as exposed.

Check your payment integration settings for changes, since redirected payouts are quiet and expensive. And work through whether this is a notifiable breach, which my guide on breach notification obligations covers.

Cleaning and hardening

Remove injected code from the injection fields and the theme, update Ghost to current, rotate your admin passwords, revoke and reissue API keys and integrations, and rotate database credentials if you self-host. Then check the server itself if it is yours, since a compromise there is a bigger problem than the application.

Going forward: two-factor authentication on staff accounts where available, minimal staff with administrator role, periodic review of integrations and API keys, and staying current on versions, which Ghost makes easier than most. If you would rather have it checked properly, that is work I take on — see the platforms I clean.

Common questions

Can Ghost be hacked?

Yes, though less easily than most platforms because there is no third-party plugin ecosystem to exploit. Realistic routes are an outdated self-hosted install, a compromised admin account, injected code in the code injection fields or theme, and a leaked API key or integration.

Where would injected JavaScript be hiding?

The code injection fields first — site-wide header and footer, plus per-post equivalents. They apply across the site without touching any file, which makes them the obvious place for anyone with admin access. Then the theme files, compared against a clean copy.

Do API keys need revoking after a compromise?

Yes. Integrations and custom API keys are independent credentials with programmatic access to your content, and they keep working perfectly after you change every password. Revoking and reissuing them is essential, and it is the step most often skipped.

Is Ghost Pro safer than self-hosting?

For most people, yes, because the platform, runtime and server are maintained for you, which removes the most likely technical cause of a compromise. It narrows your responsibility to your account, your theme, your injection fields and your integrations.

What about my members' data?

If you run memberships and the database was reachable, treat member email addresses and subscription details as exposed. Check your payment integration settings for changes too, since redirected payouts are quiet and costly, and assess whether you have a notifiable breach.