Coder Social home page Coder Social logo

webhooks-methods.js's Introduction

webhooks-methods.js

Methods to handle GitHub Webhook requests

@latest Build Status

Table of contents

usage

Browsers

🚧 @octokit/webhooks-methods is not meant to be used in browsers. The webhook secret is a sensitive credential that must not be exposed to users.

Load @octokit/webhooks-methods directly from esm.sh

<script type="module">
  import {
    sign,
    verify,
    verifyWithFallback,
  } from "https://esm.sh/@octokit/webhooks-methods";
</script>

Node

Install with npm install @octokit/core @octokit/webhooks-methods

import { sign, verify, verifyWithFallback } from "@octokit/webhooks-methods";
await sign("mysecret", eventPayloadString);
// resolves with a string like "sha256=4864d2759938a15468b5df9ade20bf161da9b4f737ea61794142f3484236bda3"

await sign({ secret: "mysecret", algorithm: "sha1" }, eventPayloadString);
// resolves with a string like "sha1=d03207e4b030cf234e3447bac4d93add4c6643d8"

await verify("mysecret", eventPayloadString, "sha256=486d27...");
// resolves with true or false

await verifyWithFallback("mysecret", eventPayloadString, "sha256=486d27...", ["oldsecret", ...]);
// resolves with true or false

Methods

sign()

await sign(secret, eventPayloadString);
await sign({ secret, algorithm }, eventPayloadString);
secret (String) Required. Secret as configured in GitHub Settings.
algorithm (String)

Algorithm to calculate signature. Can be set to sha1 or sha256. sha1 is supported for legacy reasons. GitHub Enterprise Server 2.22 and older do not send the X-Hub-Signature-256 header. Defaults to sha256.

Learn more at Validating payloads from GitHub

eventPayloadString (String) Required. Webhook request payload as received from GitHub.

If you have only access to an already parsed object, stringify it with JSON.stringify(payload)

Resolves with a signature string. Throws an error if an argument is missing.

verify()

await verify(secret, eventPayloadString, signature);
secret (String) Required. Secret as configured in GitHub Settings.
eventPayloadString (String) Required. Webhook request payload as received from GitHub.

If you have only access to an already parsed object, stringify it with JSON.stringify(payload)
signature (String) Required. Signature string as calculated by sign().

Resolves with true or false. Throws error if an argument is missing.

verifyWithFallback()

await verifyWithFallback(
  secret,
  eventPayloadString,
  signature,
  additionalSecrets,
);
secret (String) Required. Secret as configured in GitHub Settings.
eventPayloadString (String) Required. Webhook request payload as received from GitHub.

If you have only access to an already parsed object, stringify it with JSON.stringify(payload)
signature (String) Required. Signature string as calculated by sign().
additionalSecrets (Array of String) If given, each additional secret will be tried in turn.

This is a thin wrapper around verify() that is intended to ease callers' support for key rotation. Resolves with true or false. Throws error if a required argument is missing.

Contributing

See CONTRIBUTING.md

License

MIT

webhooks-methods.js's People

Contributors

aarondewes avatar bricker avatar bytemain avatar gr2m avatar kfcampbell avatar mfulton26 avatar nickfloyd avatar nwf-msr avatar octokitbot avatar oscard0m avatar pjungermann avatar renovate[bot] avatar wolfy1339 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

webhooks-methods.js's Issues

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Location: package.json
Error type: The renovate configuration file contains some invalid settings
Message: Invalid configuration option: @pika/pack, Invalid configuration option: author, Invalid configuration option: browser, Invalid configuration option: jest, Invalid configuration option: keywords, Invalid configuration option: license, Invalid configuration option: name, Invalid configuration option: packageRules[1].@gr2m/pika-plugin-build-web, Invalid configuration option: packageRules[1].@octokit/tsconfig, Invalid configuration option: packageRules[1].@pika/pack, Invalid configuration option: packageRules[1].@pika/plugin-build-node, Invalid configuration option: packageRules[1].@pika/plugin-ts-standard-pkg, Invalid configuration option: packageRules[1].@types/jest, Invalid configuration option: packageRules[1].@types/node, Invalid configuration option: packageRules[1].jest, Invalid configuration option: packageRules[1].prettier, Invalid configuration option: packageRules[1].puppeteer, Invalid configuration option: packageRules[1].semantic-release, Invalid configuration option: packageRules[1].semantic-release-plugin-update-version-in-files, Invalid configuration option: packageRules[1].ts-jest, Invalid configuration option: packageRules[1].typescript, Invalid configuration option: publishConfig, Invalid configuration option: release, Invalid configuration option: renovate, Invalid configuration option: scripts, Invalid configuration option: version

Deno support is undocumented

How should we use this on Deno?

I've imported it without problems using the URL https://cdn.skypack.dev/@octokit/webhooks-methods?dts.

I'm using the verify method this way:

await verify(secret, payload, "X-Hub-Signature-256");

But it's returning false every time.

Here's my full code:

import { Application } from "https://deno.land/x/oak/mod.ts";
import { verify } from "https://cdn.skypack.dev/@octokit/webhooks-methods?dts";

const app = new Application();

app.use(async (ctx, next) => {
  try {
    await next();
  } catch (_err) {
    ctx.response.status = 500;
  }
});

const secret = "...";

app.use(async (ctx) => {
  const signature = ctx.request.headers.get("X-Hub-Signature-256");
  if (signature) {
    const payload = await ctx.request.body({ type: "text" }).value;
    const result = await verify(secret, payload, signature);
    console.log(result);
  }
  ctx.response.status = 200;
});

"module" entry points to web bundle

What happened?

I'm bundling my node.js code with webpack for serverless.
With bundled @octokit/webhooks-methods, my code doesn't run and throws an error: Exception: ReferenceError: crypto is not defined.

What did you expect to happen?

Code generated by webpack to run.

What the problem might be

@octokit/webhooks-methods defines these entries in package.json:

  "main": "dist-node/index.js",
  "module": "dist-web/index.js",
  "source": "dist-src/index.js",
  "types": "dist-types/index.d.ts",

Webpack favours module (see webpack/webpack#5756 ) because it helps with e.g. better tree shaking, but the module entry here points to the dist-web/index.js file which doesn't include crypto and buffer imports.

IMO the module entry should be renamed to browser.

[BUG]: docs for how to stringify parsed objects/payloads does not work

What happened?

The documentation for sign and verify mention at eventPayloadString:

If you have only access to an already parsed object, stringify it with JSON.stringify(payload, null, 2) + '\n'

When trying this approach, we realized that we need to use JSON.stringify(payload) instead.

Not sure which is the intended version. The easiest resolution might be an update to the docs.

Context:
backstage/backstage#14689

Versions

"@octokit/webhooks-methods@npm:^3.0.0":
  version: 3.0.0
  resolution: "@octokit/webhooks-methods@npm:3.0.0"
  checksum: 3d1fdd051acb1e185160e138794b52b168a94dbd0fb05b1267914bfada199ccd615bc62828453b08edc5037557810319198c2684cfe5eba6267686952a9b644d
  languageName: node
  linkType: hard

Relevant log output

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

verify: does not gracefully handle invalid signatures

What happened?

An invalid signature was sent in a request and my server returned a 500, Internal Server Error, due to verify rejecting with a TypeError:

script.ts
import { verify } from "https://cdn.skypack.dev/@octokit/[email protected]?dts";

await verify("secret", "eventPayload", "signature");
run command
NO_COLOR=true deno run script.ts |& pbcopy
stderr
error: Uncaught TypeError: Cannot read properties of null (reading 'map')
  const integers = pairs.map(function(s) {
                         ^
    at hexToUInt8Array (https://cdn.skypack.dev/-/@octokit/[email protected]/dist=es2019,mode=imports/optimized/@octokit/webhooks-methods.js:11:26)
    at verify (https://cdn.skypack.dev/-/@octokit/[email protected]/dist=es2019,mode=imports/optimized/@octokit/webhooks-methods.js:7:70)
    at async file:///path/to/script.ts:3:1

What did you expect to happen?

For verify to resolve to false.

What the problem might be

verify does not validate the format of the signature before attempting to iterate over character pairs (e.g. /^[\dA-F]{64}$/i)

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

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.