Webhook-Verifizierung von Github.com
Mit Webhooks können Sie Integrationen erstellen oder einrichten, die bestimmte Ereignisse auf GitHub.com abonnieren. Wenn eines dieser Ereignisse ausgelöst wird, sendet GitHub eine HTTP-POST-Payload an die konfigurierte URL des Webhooks. Aus Sicherheitsgründen ist es jedoch wichtig zu überprüfen, ob die eingehende Webhook-Anfrage tatsächlich von GitHub stammt und nicht aus einer böswilligen Quelle. In diesem Tutorial werden Sie durch die Schritte geführt, die zum Überprüfen einer Webhook-Anfrage von GitHub.com in einer Aktion der Adobe-App-Entwicklung mit einem gemeinsam genutzten geheimen Schlüssel durchgeführt werden.
Einrichten des GitHub-Geheimnisses in der App-Entwicklung
-
Fügen Sie ein Geheimnis zur
.env-Datei hinzu:Fügen Sie in der
.env-Datei des App-Entwicklungs-Projekts einen benutzerdefinierten Schlüssel für das Webhook-Geheimnis von GitHub.com hinzu:code language-env # Specify your secrets here # This file must not be committed to source control ... GITHUB_SECRET=my-github-webhook-secret-1234! -
Aktualisieren Sie die Datei
ext.config.yaml:Die Datei
ext.config.yamlmuss aktualisiert werden, um die Webhook-Anfrage bei GitHub.com zu verifizieren.- Legen Sie die AppBuilder-Aktionskonfiguration
webaufrawfest, um den rohen Anfragetext von GitHub.com zu erhalten. - Fügen Sie unter
inputsin der AppBuilder-Aktionskonfiguration den SchlüsselGITHUB_SECREThinzu und ordnen Sie ihn dem Feld.envzu, das das Geheimnis enthält. Der Wert dieses Schlüssels ist der Feldname.envmit dem Präfix$. - Legen Sie die Anmerkung
require-adobe-authin der AppBuilder-Aktionskonfiguration auffalsefest, damit die Aktion ohne eine Adobe-Authentifizierung aufgerufen werden kann.
Die sich daraus ergebende Datei
ext.config.yamlsollte in etwa so aussehen:code language-yaml operations: view: - type: web impl: index.html actions: actions web: web-src runtimeManifest: packages: dx-excshell-1: license: Apache-2.0 actions: github-to-jira: function: actions/generic/index.js web: 'raw' runtime: nodejs:20 inputs: LOG_LEVEL: debug GITHUB_SECRET: $GITHUB_SECRET annotations: require-adobe-auth: false final: true - Legen Sie die AppBuilder-Aktionskonfiguration
Hinzufügen von Verifizierungs-Code zur AppBuilder-Aktion
Als nächstes fügen Sie den unten angegebenen JavaScript-Code (kopiert aus der Dokumentation von GitHub.com) zu Ihrer AppBuilder-Aktion hinzu. Achten Sie darauf, die Funktion verifySignature zu exportieren.
// src/dx-excshell-1/actions/generic/github-webhook-verification.js
let encoder = new TextEncoder();
async function verifySignature(secret, header, payload) {
let parts = header.split("=");
let sigHex = parts[1];
let algorithm = { name: "HMAC", hash: { name: 'SHA-256' } };
let keyBytes = encoder.encode(secret);
let extractable = false;
let key = await crypto.subtle.importKey(
"raw",
keyBytes,
algorithm,
extractable,
[ "sign", "verify" ],
);
let sigBytes = hexToBytes(sigHex);
let dataBytes = encoder.encode(payload);
let equal = await crypto.subtle.verify(
algorithm.name,
key,
sigBytes,
dataBytes,
);
return equal;
}
function hexToBytes(hex) {
let len = hex.length / 2;
let bytes = new Uint8Array(len);
let index = 0;
for (let i = 0; i < hex.length; i += 2) {
let c = hex.slice(i, i + 2);
let b = parseInt(c, 16);
bytes[index] = b;
index += 1;
}
return bytes;
}
module.exports = { verifySignature };
Implementieren der Verifizierung in der AppBuilder-Aktion
Vergewissern Sie sich anschließend, ob die Anfrage von GitHub kommt, indem Sie die Signatur im Anfrage-Header mit der von der Funktion verifySignature generierten Signatur vergleichen.
Fügen Sie in der index.js der AppBuilder-Aktion den folgenden Code zur Funktion main hinzu:
// src/dx-excshell-1/actions/generic/index.js
const { verifySignature } = require("./github-webhook-verification");
...
// Main function that will be executed by Adobe I/O Runtime
async function main(params) {
// Create a Logger
const logger = Core.Logger("main", { level: params?.LOG_LEVEL || "info" });
try {
// Log parameters if LOG_LEVEL is 'debug'
logger.debug(stringParameters(params));
// Define required parameters and headers
const requiredParams = [
// Verifies the GITHUB_SECRET is present in the action's configuration; add other parameters here as needed.
"GITHUB_SECRET"
];
const requiredHeaders = [
// Require the x-hub-signature-256 header, which GitHub.com populates with a sha256 hash of the payload
"x-hub-signature-256"
];
// Check for missing required parameters and headers
const errorMessage = checkMissingRequestInputs(params, requiredParams, requiredHeaders);
if (errorMessage) {
// Return and log client errors
return errorResponse(400, errorMessage, logger);
}
// Decode the request body (which is base64 encoded) to a string
const body = Buffer.from(params.__ow_body, 'base64').toString('utf-8');
// Verify the GitHub webhook signature
const isSignatureValid = await verifySignature(
params.GITHUB_SECRET,
params.__ow_headers["x-hub-signature-256"],
body
);
if (!isSignatureValid) {
// GitHub signature verification failed
return errorResponse(401, "Unauthorized", logger);
} else {
logger.debug("Signature verified");
}
// Parse the request body as JSON so its data is useful in the action
const githubParams = JSON.parse(body) || {};
// Optionally, merge the GitHub webhook request parameters with the action parameters
const mergedParams = {
...params,
...githubParams
};
// Do work based on the GitHub webhook request
doWork(mergedParams);
return {
statusCode: 200,
body: { message: "GitHub webhook received and processed!" }
};
} catch (error) {
// Log any server errors
logger.error(error);
// Return with 500 status code
return errorResponse(500, "Server error", logger);
}
}
Konfigurieren des Webhooks in GitHub
Geben Sie in GitHub.com bei der Erstellung des Webhooks denselben geheimen Wert für GitHub.com ein. Verwenden Sie den geheimen Wert, der im Schlüssel GITHUB_SECRET Ihrer Datei .env angegeben ist.
Wechseln Sie in GitHub.com zu den Repository-Einstellungen und bearbeiten Sie den Webhook. Geben Sie in den Webhook-Einstellungen den geheimen Wert in das Feld Secret ein. Klicken Sie unten auf Webhook aktualisieren, um die Änderungen zu speichern.
Mit diesen Schritten stellen Sie sicher, dass Ihre App Builder-Aktion zuverlässig überprüfen kann, ob eingehende Webhook-Anfragen tatsächlich von Ihrem GitHub.com-Webhook stammen.