The Autodidacts

Exploring the universe from the inside out

Ghost Private Draft URLs Leaked via Outlink Referrer Header

[Update September 9th 2022: I contacted the Ghost security team on August 22nd, before publishing this article. Yesterday, I received a response from Ghost's CTO & co-founder; her fix is in Ghost v5.14.0, released today.


Here I am writing a sensitive article in the safety of my blog’s admin panel. I throw in a link to dodgysite.com that I am ranting about. Reading through the preview, I click on the link to dodgysite.com to make sure I typed it right.

Dodgy site now has access to my draft post.

Here’s an example. Say the dodgy site I’m linking to is https://algebrarules.com.

I run algebrarules.com, and have access to the analytics dashboard. Analytics tell you what website referred people to your site. In this case, the friendly people over at The Autodidacts are talking about my website. Cool! I wonder what post they mentioned it in. Oh, there’s the URL:

Screenshot of the private draft "preview" link for this unpublished blogpost exposed in Algebra Rules analytics dashboard

Click on it, and boom! I’m reading The Autodidacts’ draft exposé blogpost on what incompetent, thumbsucking mathematical nincompoops the people at algebrarules.com are… which was not meant to be shared straight to the algebrarules.com analytics dashboard!

This issue affects all versions of Ghost I have tested between v0.11.11 and v5.11.0. But it likely isn’t unique to Ghost. Private preview URLs that do not require a password are very handy, and many apps use these types of links.

Mitigation

The easy fix: don’t click on outlinks in the preview of your draft post. (Unless you're using Firefox 87+.) You can safely click on outlinks when you're previewing it from the admin panel, which will expose your blog URL but not the draft link.

However, this means you can’t send draft blogposts around without potentially exposing the draft URL to the sites linked to. (Usually outlinks are to trustworthy sites you like and want to be friends with. But not always!)

For a more robust fix, use HTML links in your draft posts with the rel="noreferrer" attribute:

<a rel="noreferrer" href="https://algebrarules.com">algebra rules</a>

I have tested it, and it seems to work for preventing leakage of the draft post URL and the site URL. You will probably want to use search and replace to remove rel="noreferrer" before your publish your post.

Ghost and other platforms should add <meta content="same-origin" name="referrer"> to the <head> of pages with secret URLs.

Until then, drop back to HTML for all your links, and add rel=noreferrer manually — or, if that sounds too much like work, paste this snippet into your blog’s code injection:

<script>
window.onload = function(){
  if (/(.*)\/p\/(.*)/.test(this.location)) {
    var meta = document.createElement('meta');
    meta.content = "same-origin";
    meta.name = "referrer";
    document.getElementsByTagName('head')[0].appendChild(meta);
  }
}
</script>

Wait But Why once linked to this blog; a fact I discovered by looking at my analytics. Wait But Why has also had issues with their draft posts being publicly shared before they were ready, for street cred. I assure you I am innocent — but I think I can guess how their draft URL was discovered…