Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

‘verify’ should not detect the algorithm from the unverified signature #39

Closed
andersk opened this issue Sep 14, 2021 · 2 comments · Fixed by #236
Closed

‘verify’ should not detect the algorithm from the unverified signature #39

andersk opened this issue Sep 14, 2021 · 2 comments · Fixed by #236
Labels
Status: Up for grabs Issues that are ready to be worked on by anyone Type: Bug Something isn't working as documented
Projects

Comments

@andersk
Copy link

andersk commented Sep 14, 2021

Although HMAC-SHA1 is still believed to be secure at this time, if the point of GitHub’s migration from HMAC-SHA1 to HMAC-SHA256 was to guard against potential future weaknesses in HMAC-SHA1, that point is entirely negated when an attacker can force a signature to be treated as HMAC-SHA1 simply by starting it with sha1=.

const getAlgorithm = (signature: string) => {
return signature.startsWith("sha256=") ? "sha256" : "sha1";
};

To fix this, the verify API needs to be changed to take the expected algorithm as a parameter, rather than detecting it from the unverified signature string.

@andersk andersk added the Type: Bug Something isn't working as documented label Sep 14, 2021
@ghost ghost added this to Bugs in JS Sep 14, 2021
@karfau
Copy link

karfau commented Aug 24, 2023

Sadly this has not been addressed yet.
According to this answer which seems to be updated it is advised to "walk away but not run". So I assume there is still no rush...

By the way: The code recommended on the GitHub documentation page that the OP linked, already no longer considers the sha from the signature and assumes sha256, looks like it works in all current runtimes and browsers and is short enough to copy paste it, so you can own it, instead of importing a library for it that you have to trust passing your secret to.

Anyways, at least here is an idea how to provide a way to control the required algorithm from the outside it in a non breaking way:
change verify from this

export async function verify(
secret: string,
eventPayload: string,
signature: string,
) {
if (!secret || !eventPayload || !signature) {
throw new TypeError(
"[@octokit/webhooks-methods] secret, eventPayload & signature required",
);
}
const algorithm = getAlgorithm(signature);

to

 export async function verify( 
   secret: string, 
   eventPayload: string, 
   signature: string,
   algorithm = getAlgorithm(signature || ''),
 ) { 
   if (!secret || !eventPayload || !signature) { 
     throw new TypeError( 
       "[@octokit/webhooks-methods] secret, eventPayload & signature required", 
     ); 
   }

This way the option to control it becomes visible in the signature and existing code will not break, since it still falls back to sha1.

If you don't fear the breaking change you could already flip the default by dropping the getAlgorithm method from verify while still allowing users to opt in to sha1 when needed:

 export async function verify( 
   secret: string, 
   eventPayload: string, 
   signature: string,
   algorithm: 'sha256' | 'sha1' = 'sha256',
 ) { 
   if (!secret || !eventPayload || !signature) { 
     throw new TypeError( 
       "[@octokit/webhooks-methods] secret, eventPayload & signature required", 
     ); 
   }

@gr2m
Copy link
Contributor

gr2m commented Aug 24, 2023

The reason we kept support for sha1 was to not break existing GitHub Enterprise versions. I'm sure all the one currently supported send out the sha256 header now, so we should remove support for sha1. Pull request welcome!

@gr2m gr2m added the Status: Up for grabs Issues that are ready to be worked on by anyone label Aug 24, 2023
@wolfy1339 wolfy1339 linked a pull request Feb 23, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Up for grabs Issues that are ready to be worked on by anyone Type: Bug Something isn't working as documented
Projects
No open projects
JS
  
Bugs
Development

Successfully merging a pull request may close this issue.

3 participants