From 11b59994cffb91c91ecfedeec4f5d2159bab3207 Mon Sep 17 00:00:00 2001 From: larabr <7375870+larabr@users.noreply.github.com> Date: Mon, 28 Aug 2023 16:43:42 +0200 Subject: [PATCH] Reject cleartext messages with extraneous data preceeding hash header Parsing of such messages will fail, as the data in the header is not verified, and allowing it opens up the possibility of signature spoofing. --- src/cleartext.js | 2 +- test/general/signature.js | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/cleartext.js b/src/cleartext.js index bccdf162c..a99155e38 100644 --- a/src/cleartext.js +++ b/src/cleartext.js @@ -174,7 +174,7 @@ function verifyHeaders(headers, packetlist) { let oneHeader = null; let hashAlgos = []; headers.forEach(function(header) { - oneHeader = header.match(/Hash: (.+)/); // get header value + oneHeader = header.match(/^Hash: (.+)$/); // get header value if (oneHeader) { oneHeader = oneHeader[1].replace(/\s/g, ''); // remove whitespace oneHeader = oneHeader.split(','); diff --git a/test/general/signature.js b/test/general/signature.js index cbe1f0c24..914a13e3a 100644 --- a/test/general/signature.js +++ b/test/general/signature.js @@ -999,6 +999,32 @@ eSvSZutLuKKbidSYMLhWROPlwKc2GU2ws6PrLZAyCAel/lU= expect(await sigInfo.verified).to.be.true; }); + it('Reject cleartext message with arbitrary text added around hash headers (spoofed cleartext message)', async function() { + await expect(openpgp.readCleartextMessage({ cleartextMessage: `-----BEGIN PGP SIGNED MESSAGE----- +This is not signed but you might think it is Hash: SHA512 + +This is signed +-----BEGIN PGP SIGNATURE----- + +wnUEARYKACcFgmTsqxgJkEhlqJkkhIfRFiEEUA/OS4xZ3EwNC5l8SGWomSSE +h9EAALyPAQDDR0IYwq/5XMVSYPWojBamM4NhcP5arA656ALIq9cJYAEAlw0H +Fk7EflUZzngwY4lBzYAfnNBjEjc30xD/ddo+rwE= +=O7mt +-----END PGP SIGNATURE-----` })).to.be.rejectedWith(/Only "Hash" header allowed/); + + await expect(openpgp.readCleartextMessage({ cleartextMessage: `-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512\vThis is not signed but you might think it is + +This is signed +-----BEGIN PGP SIGNATURE----- + +wnUEARYKACcFgmTsqxgJkEhlqJkkhIfRFiEEUA/OS4xZ3EwNC5l8SGWomSSE +h9EAALyPAQDDR0IYwq/5XMVSYPWojBamM4NhcP5arA656ALIq9cJYAEAlw0H +Fk7EflUZzngwY4lBzYAfnNBjEjc30xD/ddo+rwE= +=O7mt +-----END PGP SIGNATURE-----` })).to.be.rejectedWith(/Unknown hash algorithm in armor header/); + }); + it('Supports non-human-readable notations', async function() { const { packets: [signature] } = await openpgp.readSignature({ armoredSignature: signature_with_non_human_readable_notations }); // There are no human-readable notations so `notations` property does not