Кодировка тела Django против секрета slack-api - PullRequest
0 голосов
/ 14 февраля 2019

Я следую инструкциям на этой странице .Я создаю сервер обработки слабой косой черты и не могу перестроить подпись для проверки подлинности запроса косой черты.

Вот фрагмент кода из моего приложения django (представление использует django rest-framework APIView):

@property
def x_slack_req_ts(self):
    if self.xsrts is not None:
        return self.xsrts
    self.xsrts = str(self.request.META['HTTP_X_SLACK_REQUEST_TIMESTAMP'])
    return self.xsrts

@property
def x_slack_signature(self):
    if self.xss is not None:
        return self.xss
    self.xss = self.request.META['HTTP_X_SLACK_SIGNATURE']
    return self.xss

@property
def base_message(self):
    if self.bs is not None:
        return self.bs
    self.bs = ':'.join(["v0", self.x_slack_req_ts, self.raw.decode('utf-8')])
    return self.bs

@property
def encoded_secret(self):
    return self.app.signing_secret.encode('utf-8')

@property
def signed(self):
    if self.non_base is not None:
        return self.non_base
    hashed = hmac.new(self.encoded_secret, self.base_message.encode('utf-8'), hashlib.sha256)
    self.non_base = "v0=" + hashed.hexdigest()
    return self.non_base

Это класс, где self.raw = request.body запрос django и self.app.signing_secret - строка с соответствующей секретной строкой.Он не работает, так как self.non_base дает неточное значение.

Теперь, если я открою интерактивную программу Python Repl и сделаю следующее:

>>> import hmac
>>> import hashlib
>>> secret = "8f742231b10e8888abcd99yyyzzz85a5"
>>> ts = "1531420618"
>>> msg = "token=xyzz0WbapA4vBCDEFasx0q6G&team_id=T1DC2JH3J&team_domain=testteamnow&channel_id=G8PSS9T3V&channel_name=foobar&user_id=U2CERLKJA&user_name=roadrunner&command=%2Fwebhook-collect&text=&response_url=https%3A%2F%2Fhooks.slack.com%2Fcommands%2FT1DC2JH3J%2F397700885554%2F96rGlfmibIGlgcZRskXaIFfN&trigger_id=398738663015.47445629121.803a0bc887a14d10d2c447fce8b6703c"
>>> ref_signature = "v0=a2114d57b48eac39b9ad189dd8316235a7b4a8d21a10bd27519666489c69b503"
>>> base = ":".join(["v0", ts, msg])
>>> hashed = hmac.new(secret.encode(), base.encode(), hashlib.sha256)
>>> hashed.hexdigest()
>>> 'a2114d57b48eac39b9ad189dd8316235a7b4a8d21a10bd27519666489c69b503'

Вы узнаете пример ссылочной ссылки,Если я использую значения из моего приложения django с одним из моих примеров, он работает в реплее, но не в приложении django.

МОЙ ВОПРОС: Я полагаю, что это вызвано кодом self.raw.decode() кодировка не соответствует распечатке, которую я извлек для копирования / вставки в репле.Кто-нибудь сталкивался с этой проблемой и что за починка?Я попробовал несколько случайных вещей с библиотекой urllib.parse ... Как я могу убедиться, что кодировка request.body согласуется с примером из flask с get_data () (как предложено документом в ссылке)?

ОБНОВЛЕНИЕ: Я определил пользовательский анализатор:

class SlashParser(BaseParser):
"""
Parser for form data.
"""
media_type = 'application/x-www-form-urlencoded'

def parse(self, stream, media_type=None, parser_context=None):
    """
    Parses the incoming bytestream as a URL encoded form,
    and returns the resulting QueryDict.
    """
    parser_context = parser_context or {}
    request = parser_context.get('request')
    raw_data = stream.read()
    data = QueryDict(raw_data, encoding='utf-8')
    setattr(data, 'raw_body', raw_data) # setting a 'body' alike custom attr with raw POST content
    return data

Для проверки на основе этот вопрос и raw_body в пользовательском анализаторе генерирует точно такую ​​же хешированную сигнатуру, что и обычный "body ", но опять же, скопируйте вставку в repl для тестирования вне работы DRF.Уверен, что это проблема с кодировкой, но полностью потеряна ...

1 Ответ

0 голосов
/ 14 февраля 2019

Я нашел проблему, которая очень расстраивает.

Оказывается, что секрет подписи хранился в слишком коротком массиве str и отсутствовали завершающие символы, что, очевидно, приводило к плохому хешированию сообщения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...