Упражнение. Защита полезных данных веб-перехватчика с помощью секрета

Завершено

В этом упражнении вы защитите полезные данные веб-перехватчика с помощью секрета и узнаете, как проверить, что полезные данные фактически находятся из GitHub с помощью функции Azure.

Получение ключа для функции Azure

  1. На портале Azure перейдите в приложение-функцию, созданное ранее.

  2. На панели "Приложение-функция" выберите приложение-функцию в разделе "Функции " в центральной области.

  3. Выберите созданный httpTrigger1 . Панель HtttpTrigger1 откроется для вашей функции.

  4. В области меню слева в разделе "Разработчик" выберите "Код и тест". Область "Код и тест " отображается для функции.

  5. В index.js файле JavaScript функции добавьте ссылку на библиотеку crypto-js в начале файла выше инструкции module.exports .

    const Crypto = require('crypto');
    
  6. В верхней строке меню нажмите кнопку "Сохранить". Область журналов отображается в нижней части области.

  7. В области меню слева в разделе "Разработчик" выберите "Ключи функций". Откроется область "Ключи функций " для функции.

  8. В столбце "Значение" выберите ссылку "Показать значение ".

  9. Выберите значок копирования в буфер обмена и сохраните этот ключ для использования на следующем шаге.

  10. В области меню слева в разделе "Разработчик" выберите "Код и тест". Область "Код и тест " отображается для функции.

  11. Добавьте следующий код в блок кода после инструкции context.log. Замените <ключ по умолчанию ключом> по умолчанию, скопированным в буфер обмена:

    const hmac = Crypto.createHmac("sha1", "<default key>");
    const signature = hmac.update(JSON.stringify(req.body)).digest('hex');
    

    Этот код вычисляет хэш ключа с помощью того же механизма, что и GitHub.

  12. Добавьте еще const перед sha1= в начало ключа, чтобы он соответствовал формату x-hub-signature в заголовке запроса. Добавьте в функцию следующий код.

    const shaSignature = `sha1=${signature}`;
    
  13. Добавьте следующий код для получения подписи GitHub из заголовка запроса:

    const gitHubSignature = req.headers['x-hub-signature'];
    
  14. Сравните эти две строки. Если они совпадают, обработайте запрос следующим образом:

    if (!shaSignature.localeCompare(gitHubSignature)) {
        // Existing code
        if (req.body.pages[0].title) {
            ...
        }
        else {
            ...
        }
    }
    
  15. Если строки не совпадают, возвратите ответ HTTP 401 (не санкционировано) в сообщении отправителю о том, что подписи не совпадают.

    if (!shaSignature.localeCompare(gitHubSignature))
    {
        ...
    }
    else {
        context.res = {
            status: 401,
            body: "Signatures don't match"
        };
    }
    
    

    Готовая функция будет выглядеть так:

    const Crypto = require('crypto');
    
    module.exports = async function (context, req) {
        context.log('JavaScript HTTP trigger function processed a request.');
    
        const hmac = Crypto.createHmac("sha1", "<default key>");
        const signature = hmac.update(JSON.stringify(req.body)).digest('hex');
        const shaSignature =  `sha1=${signature}`;
        const gitHubSignature = req.headers['x-hub-signature'];
    
        if (!shaSignature.localeCompare(gitHubSignature)) {
            if (req.body.pages[0].title) {
                context.res = {
                    body: "Page is " + req.body.pages[0].title + ", Action is " + req.body.pages[0].action + ", Event Type is " + req.headers['x-github-event']
                };
            }
            else {
                context.res = {
                    status: 400,
                    body: ("Invalid payload for Wiki event")
                }
            }
        }
        else {
            context.res = {
                status: 401,
                body: "Signatures don't match"
            };
        }
    };
    
  16. В верхней строке меню нажмите кнопку "Сохранить". Область журналов отображается с сообщением Подключено!

Обновление секрета веб-перехватчика

  1. Перейдите к учетной записи GitHub на портале GitHub.

  2. Выберите репозиторий.

  3. В верхней строке меню выберите "Параметры". Откроется область параметров .

  4. На боковой панели выберите вебхуки. Откроется область Вебхуков.

  5. Нажмите Изменить рядом с вашим webhook.

  6. В текстовом поле "Секрет" введите ключ по умолчанию из функции, которую вы ранее сохранили в этом упражнении.

  7. Прокрутите вниз до нижней части страницы и выберите Обновить вебхук. Откроется панель Webhooks/Manage webhooks.

Тестирование веб-перехватчика и функции Azure

  1. Перейдите на вкладку "Последние поставки ".

  2. Выберите последнюю (верхнюю) запись доставки, нажав кнопку с многоточием (...).

  3. Выберите Redeliver. В появившемся диалоговом окне "Повторно отправить полезную нагрузку?" выберите "Да, повторно отправить эту полезную нагрузку".

    Это действие имитирует редактирование вики-страницы еще раз.

  4. Выберите последнюю (верхнюю) запись доставки, нажав кнопку с многоточием (...).

  5. В разделе "Заголовки" вы увидите x-hub-signature. Вы также увидите, что код ответа — 200, что указывает на то, что запрос обработан успешно.

    Request URL: https://testwh123456.azurewebsites.net/api/HttpTrigger1?code=aUjXIpqdJ0ZHPQuB0SzFegxGJu0nAXmsQBnmkCpJ6RYxleRaoxJ8cQ%3D%3D
    Request method: POST
    content-type: application/json
    Expect:
    User-Agent: GitHub-Hookshot/16496cb
    X-GitHub-Delivery: ce122460-6aae-11e9-99d4-de6a298a424a
    X-GitHub-Event: gollum
    X-Hub-Signature: sha1=<hash of default key>
    

Тестирование недопустимой подписи

  1. На портале GitHub на странице вебхуков нажмите кнопку "Изменить" для вашего вебхука.

  2. В поле "Секрет" выберите "Изменить секрет".

  3. Введите случайную строку, прокрутите вниз и выберите «Обновить вебхук».

    Ключ, используемый веб-перехватчиком, больше не должен совпадать с ключом, ожидаемым функцией Azure.

  4. Перейдите на вкладку "Последние поставки ".

  5. Выберите последнюю (верхнюю) запись доставки, нажав кнопку с многоточием (...).

  6. Выберите Redeliver, и в появившемся диалоговом окне Redeliver полезной нагрузки выберите Да, повторно доставить эту полезную нагрузку.

  7. На этот раз вы увидите, что код ответа — 401. Это указывает на то, что запрос не авторизован.

  8. Выберите последнюю (верхнюю) запись доставки (redelivery), нажав кнопку с многоточием (...).

  9. Перейдите на вкладку "Ответ " и в разделе "Текст " убедитесь, что появится сообщение "Подписи не совпадают".