Skip to content

Commit d516858

Browse files
authored
repo sync
2 parents 9b140ba + d9a23d5 commit d516858

File tree

3 files changed

+27
-12
lines changed

3 files changed

+27
-12
lines changed

content/developers/webhooks-and-events/securing-your-webhooks.md

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,17 @@ $ export SECRET_TOKEN=<em>your_token</em>
3434

3535
### Validating payloads from GitHub
3636

37-
When your secret token is set, GitHub uses it to create a hash signature with each payload.
37+
When your secret token is set, {% data variables.product.product_name %} uses it to create a hash signature with each payload. This hash signature is included with the headers of each request as {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.22" or currentVersion == "private-instances@latest" %}`X-Hub-Signature-256`{% else if currentVersion ver_lt "enterprise-server@2.23" %}`X-Hub-Signature`{% endif %}.
3838

39-
This hash signature is passed along with each request in the headers as `X-Hub-Signature`. Suppose you have a basic server listening to webhooks that looks like this:
39+
{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.22" or currentVersion == "private-instances@latest" %}
40+
{% note %}
41+
42+
**Note:** For backward-compatibility, we also include the `X-Hub-Signature` header that is generated using the SHA-1 hash function. If possible, we recommend that you use the `X-Hub-Signature-256` header for improved security. The example below demonstrate using the `X-Hub-Signature-256` header.
43+
44+
{% endnote %}
45+
{% endif %}
46+
47+
For example, if you have a basic server that listens for webhooks, it might be configured similar to this:
4048

4149
``` ruby
4250
require 'sinatra'
@@ -48,7 +56,7 @@ post '/payload' do
4856
end
4957
```
5058

51-
The goal is to compute a hash using your `SECRET_TOKEN`, and ensure that the hash from GitHub matches. GitHub uses an HMAC hexdigest to compute the hash, so you could change your server to look a little like this:
59+
The intention is to calculate a hash using your `SECRET_TOKEN`, and ensure that the result matches the hash from {% data variables.product.product_name %}. {% data variables.product.product_name %} uses an HMAC hex digest to compute the hash, so you could reconfigure your server to look a little like this:
5260

5361
``` ruby
5462
post '/payload' do
@@ -59,16 +67,21 @@ post '/payload' do
5967
"I got some JSON: #{push.inspect}"
6068
end
6169

70+
{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.22" or currentVersion == "private-instances@latest" %}
71+
def verify_signature(payload_body)
72+
signature = 'sha256=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), ENV['SECRET_TOKEN'], payload_body)
73+
return halt 500, "Signatures didn't match!" unless Rack::Utils.secure_compare(signature, request.env['HTTP_X_HUB_SIGNATURE_2'])
74+
end{% else if currentVersion ver_lt "enterprise-server@2.23" %}
6275
def verify_signature(payload_body)
6376
signature = 'sha1=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), ENV['SECRET_TOKEN'], payload_body)
6477
return halt 500, "Signatures didn't match!" unless Rack::Utils.secure_compare(signature, request.env['HTTP_X_HUB_SIGNATURE'])
65-
end
78+
end{% endif %}
6679
```
6780
68-
Obviously, your language and server implementations may differ than this code. There are a couple of very important things to point out, however:
81+
Your language and server implementations may differ from this example code. However, there are a number of very important things to point out:
6982
70-
* No matter which implementation you use, the hash signature starts with `sha1=`, using the key of your secret token and your payload body.
83+
* No matter which implementation you use, the hash signature starts with {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.22" or "private-instances@latest" %}`sha256=`{% else if currentVersion ver_lt "enterprise-server@2.23" %}`sha1=`{% endif %}, using the key of your secret token and your payload body.
7184

72-
* Using a plain `==` operator is **not advised**. A method like [`secure_compare`][secure_compare] performs a "constant time" string comparison, which renders it safe from certain timing attacks against regular equality operators.
85+
* Using a plain `==` operator is **not advised**. A method like [`secure_compare`][secure_compare] performs a "constant time" string comparison, which helps mitigate certain timing attacks against regular equality operators.
7386

7487
[secure_compare]: http://rubydoc.info/github/rack/rack/master/Rack/Utils.secure_compare

content/developers/webhooks-and-events/webhook-events-and-payloads.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@ Header | Description
4949
`X-GitHub-Event`| Name of the event that triggered the delivery.
5050
`X-GitHub-Delivery`| A [GUID](http://en.wikipedia.org/wiki/Globally_unique_identifier) to identify the delivery.{% if currentVersion != "free-pro-team@latest" %}
5151
`X-GitHub-Enterprise-Version` | The version of the {% data variables.product.prodname_ghe_server %} instance that sent the HTTP POST payload.
52-
`X-GitHub-Enterprise-Host` | The hostname of the {% data variables.product.prodname_ghe_server %} instance that sent the HTTP POST payload.{% endif %}
53-
`X-Hub-Signature`| The HMAC hex digest of the response body. This header will be sent if the webhook is configured with a [`secret`](/v3/repos/hooks/#create-hook-config-params). The HMAC hex digest is generated using the `sha1` hash function and the `secret` as the HMAC `key`.
52+
`X-GitHub-Enterprise-Host` | The hostname of the {% data variables.product.prodname_ghe_server %} instance that sent the HTTP POST payload.{% endif %}{% if currentVersion != "private-instances@latest" %}
53+
`X-Hub-Signature`| This header is sent if the webhook is configured with a [`secret`](/v3/repos/hooks/#create-hook-config-params). This is the HMAC hex digest of the request body, and is generated using the SHA-1 hash function and the `secret` as the HMAC `key`.{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.22" %} `X-Hub-Signature` is provided for compatibility with existing integrations, and we recommend that you use the more secure `X-Hub-Signature-256` instead.{% endif %}{% endif %}{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.22" or currentVersion == "private-instances@latest" %}
54+
`X-Hub-Signature-256`| This header is sent if the webhook is configured with a [`secret`](/v3/repos/hooks/#create-hook-config-params). This is the HMAC hex digest of the request body, and is generated using the SHA-256 hash function and the `secret` as the HMAC `key`.{% endif %}
5455

5556
Also, the `User-Agent` for the requests will have the prefix `GitHub-Hookshot/`.
5657

@@ -62,8 +63,9 @@ Also, the `User-Agent` for the requests will have the prefix `GitHub-Hookshot/`.
6263
> Host: localhost:4567
6364
> X-GitHub-Delivery: 72d3162e-cc78-11e3-81ab-4c9367dc0958{% if currentVersion != "free-pro-team@latest" %}
6465
> X-GitHub-Enterprise-Version: 2.15.0
65-
> X-GitHub-Enterprise-Host: example.com{% endif %}
66-
> X-Hub-Signature: sha1=7d38cdd689735b008b3c702edd92eea23791c5f6
66+
> X-GitHub-Enterprise-Host: example.com{% endif %}{% if currentVersion != "private-instances@latest" %}
67+
> X-Hub-Signature: sha1=7d38cdd689735b008b3c702edd92eea23791c5f6{% endif %}{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.22" or currentVersion == "private-instances@latest" %}
68+
> X-Hub-Signature-256: sha256=d57c68ca6f92289e6987922ff26938930f6e66a2d161ef06abdf1859230aa23c{% endif %}
6769
> User-Agent: GitHub-Hookshot/044aadd
6870
> Content-Type: application/json
6971
> Content-Length: 6615

data/reusables/webhooks/secret.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Setting a webhook secret allows you to ensure that `POST` requests sent to the payload URL are from GitHub. When you set a secret, you'll receive the `X-Hub-Signature` header in the webhook `POST` request. For more details on how to use the secret and the `X-Hub-Signature` header to secure your webhook payloads, see "[Securing your webhooks](/webhooks/securing/)."
1+
Setting a webhook secret allows you to ensure that `POST` requests sent to the payload URL are from {% data variables.product.product_name %}. When you set a secret, you'll receive the {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.22" %}`X-Hub-Signature` and `X-Hub-Signature-256` headers{% else if currentVersion ver_lt "enterprise-server@2.23" %}`X-Hub-Signature` header{% else if currentVersion == "private-instances@latest" %}`X-Hub-Signature-256` header{% endif %} in the webhook `POST` request. For more information on how to use a secret with a signature header to secure your webhook payloads, see "[Securing your webhooks](/webhooks/securing/)."

0 commit comments

Comments
 (0)