Skip to content

Commit

Permalink
Merge pull request #66 from ItzNotABug/65-fix-signature-checks
Browse files Browse the repository at this point in the history
Fix Ghost `5.87.1` Signature Checks
  • Loading branch information
ItzNotABug authored Jul 6, 2024
2 parents 106d6ba + e8118fa commit 4da6302
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 8 deletions.
53 changes: 46 additions & 7 deletions utils/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -292,11 +292,11 @@ export default class Miscellaneous {
*/
static async isPostSecure(request) {
const payload = JSON.stringify(request.body);
const ghostConfigs = await ProjectConfigs.ghost();
const ghostSecretSignature = (await ProjectConfigs.ghost()).secret;
const signatureWithDateHeader = request.headers['x-ghost-signature'];

// Secret set on Ghosler but not recd. in the request headers.
if (ghostConfigs.secret && !signatureWithDateHeader) {
if (ghostSecretSignature && !signatureWithDateHeader) {
logError(
logTags.Express,
"The 'X-Ghost-Signature' header not found in the request. Did you setup the Secret Key correctly?",
Expand Down Expand Up @@ -326,12 +326,36 @@ export default class Miscellaneous {
return false;
}

const expectedSignature = crypto
.createHmac('sha256', ghostConfigs.secret)
.update(payload)
.digest('hex');
/**
* Build signature for versions below `Ghost:5.87.1`.
*/
const expectedOldSignature = this.#createHmac(
ghostSecretSignature,
payload,
);

return signature === expectedSignature;
/**
* Build signature with new logic for `Ghost:5.87.1` & above.
* @see https://github.com/TryGhost/Ghost/pull/20500
*/
const expectedNewSignature = this.#createHmac(
ghostSecretSignature,
`${payload}${timeStamp}`,
);

// Check if either of the signatures match
if (
signature === expectedOldSignature ||
signature === expectedNewSignature
) {
return true;
} else {
logError(
logTags.Express,
"The signature in the 'X-Ghost-Signature' header is not valid.",
);
return false;
}
}

/**
Expand All @@ -352,4 +376,19 @@ export default class Miscellaneous {
audience,
});
}

/**
* Creates a signature based on given inputs.
*
* @param {string} secret - The ghost secret key.
* @param {string} payload - The payload to create the hash for.
*
* @returns {string} The generated HMAC hex digest.
*/
static #createHmac(secret, payload) {
return crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
}
}
2 changes: 1 addition & 1 deletion views/newsletter.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -1329,7 +1329,7 @@
<tr>
<td align="center" class="footer"
style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; vertical-align: top; color: #738a94; margin-top: 20px; text-align: center; font-size: 13px; padding: 10px 30px;line-height: 1.5em;"
valign="top"><%= site.title %> &#xA9; 2023 &#x2013; <a
valign="top"><%= site.title %> &#xA9; <%= new Date().getFullYear() %> &#x2013; <a
href="<%= newsletter.unsubscribeLink; %>"
style="overflow-wrap: anywhere; color: #738a94; text-decoration: underline;"
target="_blank">Unsubscribe </a>
Expand Down

0 comments on commit 4da6302

Please sign in to comment.