fix(patches): preserve raw body bytes for Fedify HTTP Signature verification
The inbox View-skip patch buffers the request stream but was not saving the original bytes as req._rawBody. Without them, fromExpressRequest falls back to JSON.stringify(req.body) which can alter byte layout, breaking the Digest check in Fedify's HTTP Signature verification. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -42,9 +42,49 @@ const patchSpecs = [
|
|||||||
body = JSON.stringify(req.body);
|
body = JSON.stringify(req.body);
|
||||||
} else if (ct.includes("application/x-www-form-urlencoded")) {`,
|
} else if (ct.includes("application/x-www-form-urlencoded")) {`,
|
||||||
newSnippet: ` // PeerTube activity+json body fix
|
newSnippet: ` // PeerTube activity+json body fix
|
||||||
|
if (ct.includes("application/json") || ct.includes("activity+json") || ct.includes("ld+json")) {
|
||||||
|
// Use original raw bytes when available (set by createFedifyMiddleware buffer guard).
|
||||||
|
// JSON.stringify() changes byte layout, breaking Fedify's HTTP Signature Digest check.
|
||||||
|
body = req._rawBody || JSON.stringify(req.body); // raw body digest fix
|
||||||
|
} else if (ct.includes("application/x-www-form-urlencoded")) {`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// --- Patch 1b: upgrade fromExpressRequest to use _rawBody (fixes Digest verification) ---
|
||||||
|
// Handles files where Patch 1 was already applied but without the _rawBody fix.
|
||||||
|
{
|
||||||
|
name: "from-express-request-raw-body-fix",
|
||||||
|
marker: "req._rawBody || JSON.stringify",
|
||||||
|
oldSnippet: ` // PeerTube activity+json body fix
|
||||||
if (ct.includes("application/json") || ct.includes("activity+json") || ct.includes("ld+json")) {
|
if (ct.includes("application/json") || ct.includes("activity+json") || ct.includes("ld+json")) {
|
||||||
body = JSON.stringify(req.body);
|
body = JSON.stringify(req.body);
|
||||||
} else if (ct.includes("application/x-www-form-urlencoded")) {`,
|
} else if (ct.includes("application/x-www-form-urlencoded")) {`,
|
||||||
|
newSnippet: ` // PeerTube activity+json body fix
|
||||||
|
if (ct.includes("application/json") || ct.includes("activity+json") || ct.includes("ld+json")) {
|
||||||
|
// Use original raw bytes when available (set by createFedifyMiddleware buffer guard).
|
||||||
|
// JSON.stringify() changes byte layout, breaking Fedify's HTTP Signature Digest check.
|
||||||
|
body = req._rawBody || JSON.stringify(req.body); // raw body digest fix
|
||||||
|
} else if (ct.includes("application/x-www-form-urlencoded")) {`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// --- Patch 1c: upgrade middleware buffer guard to set _rawBody (fixes Digest verification) ---
|
||||||
|
// Handles files where Patch 2 was already applied but without the _rawBody fix.
|
||||||
|
{
|
||||||
|
name: "inbox-buffer-raw-body-fix",
|
||||||
|
marker: "req._rawBody = _raw",
|
||||||
|
oldSnippet: ` const _chunks = [];
|
||||||
|
for await (const _chunk of req) {
|
||||||
|
_chunks.push(Buffer.isBuffer(_chunk) ? _chunk : Buffer.from(_chunk));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
req.body = JSON.parse(Buffer.concat(_chunks).toString("utf8"));`,
|
||||||
|
newSnippet: ` const _chunks = [];
|
||||||
|
for await (const _chunk of req) {
|
||||||
|
_chunks.push(Buffer.isBuffer(_chunk) ? _chunk : Buffer.from(_chunk));
|
||||||
|
}
|
||||||
|
const _raw = Buffer.concat(_chunks); // raw body digest fix
|
||||||
|
req._rawBody = _raw; // Preserve original bytes for Fedify HTTP Signature Digest verification
|
||||||
|
try {
|
||||||
|
req.body = JSON.parse(_raw.toString("utf8"));`,
|
||||||
},
|
},
|
||||||
|
|
||||||
// --- Patch 2a: replace the old (broken) v1 guard with the buffering v2 guard ---
|
// --- Patch 2a: replace the old (broken) v1 guard with the buffering v2 guard ---
|
||||||
@@ -78,8 +118,10 @@ const patchSpecs = [
|
|||||||
for await (const _chunk of req) {
|
for await (const _chunk of req) {
|
||||||
_chunks.push(Buffer.isBuffer(_chunk) ? _chunk : Buffer.from(_chunk));
|
_chunks.push(Buffer.isBuffer(_chunk) ? _chunk : Buffer.from(_chunk));
|
||||||
}
|
}
|
||||||
|
const _raw = Buffer.concat(_chunks); // raw body digest fix
|
||||||
|
req._rawBody = _raw; // Preserve original bytes for Fedify HTTP Signature Digest verification
|
||||||
try {
|
try {
|
||||||
req.body = JSON.parse(Buffer.concat(_chunks).toString("utf8"));
|
req.body = JSON.parse(_raw.toString("utf8"));
|
||||||
} catch {
|
} catch {
|
||||||
req.body = {};
|
req.body = {};
|
||||||
}
|
}
|
||||||
@@ -117,8 +159,10 @@ const patchSpecs = [
|
|||||||
for await (const _chunk of req) {
|
for await (const _chunk of req) {
|
||||||
_chunks.push(Buffer.isBuffer(_chunk) ? _chunk : Buffer.from(_chunk));
|
_chunks.push(Buffer.isBuffer(_chunk) ? _chunk : Buffer.from(_chunk));
|
||||||
}
|
}
|
||||||
|
const _raw = Buffer.concat(_chunks); // raw body digest fix
|
||||||
|
req._rawBody = _raw; // Preserve original bytes for Fedify HTTP Signature Digest verification
|
||||||
try {
|
try {
|
||||||
req.body = JSON.parse(Buffer.concat(_chunks).toString("utf8"));
|
req.body = JSON.parse(_raw.toString("utf8"));
|
||||||
} catch {
|
} catch {
|
||||||
req.body = {};
|
req.body = {};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user