If you own a ghost blog, your ghost blog posts are publicly accessible. It doesn't matter if your post or page is in draft or a private status.
I discovered this issue accidentally when I was looking into my Google analytics, and found a weird access to https://www.amarjanica.com/p/<uuid>.
Of course, I emailed Ghost support that I discovered a security leak.
But the reply was, that is by design:
Post previews generate a unique shareable URL that can be viewed by anyone you choose to send it to.
Or just anyone?
Someone also reported the "issue" here.
Theoretically, your uuids are guessable, but there are like insane number of uuid combinations. Uuid is a 128 bit number, but guessing chance is less than 1 in 2^128. In practice, chance is little lower. No one uses values like 00000000-0000-0000-0000-000000000000. UUIDv4 is used, which picks random values across the whole space.
Since I'm precautious, and I don't want my golden drafted posts to be leaked,
I blocked public access from the preview pages. Except to my own ip address.
I self host a Ghost blog and I use nginx for reverse proxy. This is the config that I added to limit preview links to allowed ips:
location ^~ /p/ {
allow x.x.x.x/24;
allow x.x.x.x;
deny all;
proxy_pass http://blog;
proxy_cache off;
}
Replace x.x.x.x with your IP or your IP range. Replace blog with your local upstream name or IP.
If you're using Cloudflare, there's one more step. This rule won’t work properly unless nginx sees your real IP. So you have to forward Cloudflare’s IP:
real_ip_header CF-Connecting-IP;
# Cloudflare IP ranges (must be kept updated)
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
You can put this in the nginx.conf block, and always check the ip ranges at official url.
Bottom line: Ghost treats preview URLs as shareable links, not secure links. If that doesn't sit right with you, lock them down at the server level.
Btw, at the time of writing this article, my ghost version is 6.13.2.
Youtube: https://youtu.be/u2D_mto2zaE
