
Outdated Ghost CMS websites that have fallen become compromised from CVE-2026-26980 can suffer from spam code injection to pages. Use this to mass clear and edit code injection fields.
Removes all per-post and per-page code injection from a Ghost CMS site via the Admin API.
Site-wide code injection (Ghost Admin → Settings → Code injection) is never touched.
pip install requests PyJWT
6478abc123def456:8f9e0d1c2b3a4567890abcdef1234567890abcdef1234567890abcdef12345678
Create a file called ghost_cleaner_config.json in the same directory as the script:
{
"ghost_url": "https://yourdomain.com",
"admin_api_key": "YOUR_KEY_ID:YOUR_KEY_SECRET"
}
If you skip this step, the script will create an example config file for you on first run and exit — just fill it in and re-run.
Always run this first to see exactly what would be cleared before touching anything:
python3 ghost_injection_cleaner.py
Example output:
Ghost Injection Remover
Mode : DRY-RUN (read-only)
Target: https://yourdomain.com
NOTE: /ghost/api/admin/settings/ (site-wide injection) is
never read or written by this script.
============================================================
POSTS
============================================================
47 posts fetched.
✦ 'My First Post'
HEAD: '<script>(function(){var _x="...obfuscated..."</script>'
🔍 DRY-RUN — would be cleared.
============================================================
PAGES
============================================================
6 pages fetched.
============================================================
SUMMARY
============================================================
Would clear : 1 posts/pages
Already clean: 52 posts/pages
Re-run with --apply to commit these changes.
Once you're happy with the dry-run output, run with --apply. You'll be prompted to confirm:
python3 ghost_injection_cleaner.py --apply
Type YES to confirm changes to posts and pages: YES
...
✅ Cleared.
python3 ghost_injection_cleaner.py --config /path/to/my_config.json
For every post and page, it sets both of these fields to null:
| Field | Location in Ghost editor |
|---|---|
codeinjection_head | Post/page settings → Code injection → Header |
codeinjection_foot | Post/page settings → Code injection → Footer |
Posts and pages that have no injection are silently skipped.
Missing dependencies
Run pip install requests PyJWT and try again.
admin_api_key must be in 'id:secret' format
Make sure your key has a colon in the middle. It should look like two hex strings separated by :. Copy it directly from Ghost Admin without adding spaces.
401 Unauthorized
Your Admin API key may be wrong or the integration may have been deleted. Go back to Ghost Admin → Settings → Integrations and verify.
ConnectionError or timeout
Check that ghost_url in your config is correct and the site is reachable from the machine you're running the script on.
The script hangs on a large site Each page of 50 posts generates a fresh JWT and waits for the API. This is normal — give it a minute.