Skip to content

Commit

Permalink
feat: remove SHA1 support
Browse files Browse the repository at this point in the history
BREAKING CHANGE: remove SHA1 support
  • Loading branch information
wolfy1339 committed Feb 23, 2024
1 parent 815352d commit 30b2044
Show file tree
Hide file tree
Showing 7 changed files with 6 additions and 65 deletions.
2 changes: 1 addition & 1 deletion src/node/sign.ts
Expand Up @@ -31,7 +31,7 @@ export async function sign(

if (!Object.values(Algorithm).includes(algorithm as Algorithm)) {
throw new TypeError(
`[@octokit/webhooks] Algorithm ${algorithm} is not supported. Must be 'sha1' or 'sha256'`,
`[@octokit/webhooks] Algorithm ${algorithm} is not supported. Must be 'sha256'`,
);
}

Expand Down
3 changes: 1 addition & 2 deletions src/node/verify.ts
Expand Up @@ -3,7 +3,6 @@ import { Buffer } from "node:buffer";

import { sign } from "./sign.js";
import { VERSION } from "../version.js";
import { getAlgorithm } from "../utils.js";

export async function verify(
secret: string,
Expand All @@ -23,7 +22,7 @@ export async function verify(
}

const signatureBuffer = Buffer.from(signature);
const algorithm = getAlgorithm(signature);
const algorithm = "sha256";

const verificationBuffer = Buffer.from(
await sign({ secret, algorithm }, eventPayload),
Expand Down
3 changes: 1 addition & 2 deletions src/types.ts
@@ -1,9 +1,8 @@
export enum Algorithm {
SHA1 = "sha1",
SHA256 = "sha256",
}

export type AlgorithmLike = Algorithm | "sha1" | "sha256";
export type AlgorithmLike = Algorithm | "sha256";

export type SignOptions = {
secret: string;
Expand Down
3 changes: 0 additions & 3 deletions src/utils.ts

This file was deleted.

6 changes: 2 additions & 4 deletions src/web.ts
@@ -1,5 +1,4 @@
import { Algorithm, type AlgorithmLike, type SignOptions } from "./types.js";
import { getAlgorithm } from "./utils.js";

const enc = new TextEncoder();

Expand All @@ -24,7 +23,6 @@ function UInt8ArrayToHex(signature: ArrayBuffer) {
function getHMACHashName(algorithm: AlgorithmLike) {
return (
{
[Algorithm.SHA1]: "SHA-1",
[Algorithm.SHA256]: "SHA-256",
} as { [key in Algorithm]: string }
)[algorithm];
Expand Down Expand Up @@ -71,7 +69,7 @@ export async function sign(options: SignOptions | string, payload: string) {

if (!Object.values(Algorithm).includes(algorithm as Algorithm)) {
throw new TypeError(
`[@octokit/webhooks] Algorithm ${algorithm} is not supported. Must be 'sha1' or 'sha256'`,
`[@octokit/webhooks] Algorithm ${algorithm} is not supported. Must be 'sha256'`,
);
}

Expand Down Expand Up @@ -101,7 +99,7 @@ export async function verify(
);
}

const algorithm = getAlgorithm(signature);
const algorithm = "sha256";
return await crypto.subtle.verify(
"HMAC",
await importKey(secret, algorithm),
Expand Down
10 changes: 1 addition & 9 deletions test/sign.test.ts
Expand Up @@ -40,7 +40,7 @@ describe("sign", () => {
// @ts-expect-error
sign({ secret, algorithm: "sha2" }, JSON.stringify(eventPayload)),
).rejects.toThrow(
"[@octokit/webhooks] Algorithm sha2 is not supported. Must be 'sha1' or 'sha256'",
"[@octokit/webhooks] Algorithm sha2 is not supported. Must be 'sha256'",
);
});

Expand All @@ -59,14 +59,6 @@ describe("sign", () => {
"sha256=4864d2759938a15468b5df9ade20bf161da9b4f737ea61794142f3484236bda3",
);
});

test("sign({secret, algorithm: 'sha1'}, eventPayload)", async () => {
const signature = await sign(
{ secret, algorithm: "sha1" },
JSON.stringify(eventPayload),
);
expect(signature).toBe("sha1=d03207e4b030cf234e3447bac4d93add4c6643d8");
});
});

describe("returns expected sha256 signature", () => {
Expand Down
44 changes: 0 additions & 44 deletions test/verify.test.ts
Expand Up @@ -11,7 +11,6 @@ function toNormalizedJsonString(payload: object) {
const JSONeventPayload = { foo: "bar" };
const eventPayload = toNormalizedJsonString(JSONeventPayload);
const secret = "mysecret";
const signatureSHA1 = "sha1=640c0ea7402a3f74e1767338fa2dba243b1f2d9c";
const signatureSHA256 =
"sha256=e3eccac34c43c7dc1cbb905488b1b81347fcc700a7b025697a9d07862256023f";

Expand Down Expand Up @@ -52,49 +51,6 @@ describe("verify", () => {
);
});

test("verify(secret, eventPayload, signatureSHA1) returns true for correct signature", async () => {
const signatureMatches = await verify(secret, eventPayload, signatureSHA1);
expect(signatureMatches).toBe(true);
});

test("verify(secret, eventPayload, signatureSHA1) returns false for incorrect signature", async () => {
const signatureMatches = await verify(secret, eventPayload, "foo");
expect(signatureMatches).toBe(false);
});

test("verify(secret, eventPayload, signatureSHA1) returns false for correct secret", async () => {
const signatureMatches = await verify("foo", eventPayload, signatureSHA1);
expect(signatureMatches).toBe(false);
});

test("verify(secret, eventPayload, signatureSHA1) returns true if eventPayload contains special characters (#71)", async () => {
// https://github.com/octokit/webhooks.js/issues/71
const signatureMatchesLowerCaseSequence = await verify(
"development",
toNormalizedJsonString({
foo: "Foo\n\u001b[34mbar: ♥♥♥♥♥♥♥♥\nthis-is-lost\u001b[0m\u001b[2K",
}),
"sha1=82a91c5aacc9cdc2eea893bc828bd03d218df79c",
);
expect(signatureMatchesLowerCaseSequence).toBe(true);
const signatureMatchesUpperCaseSequence = await verify(
"development",
toNormalizedJsonString({
foo: "Foo\n\u001B[34mbar: ♥♥♥♥♥♥♥♥\nthis-is-lost\u001B[0m\u001B[2K",
}),
"sha1=82a91c5aacc9cdc2eea893bc828bd03d218df79c",
);
expect(signatureMatchesUpperCaseSequence).toBe(true);
const signatureMatchesEscapedSequence = await verify(
"development",
toNormalizedJsonString({
foo: "\\u001b",
}),
"sha1=bdae4705bdd827d026bb227817ca025b5b3a6756",
);
expect(signatureMatchesEscapedSequence).toBe(true);
});

test("verify(secret, eventPayload, signatureSHA256) returns true for correct signature", async () => {
const signatureMatches = await verify(
secret,
Expand Down

0 comments on commit 30b2044

Please sign in to comment.