php – Bigcommerce – 无法验证加载回调

你好开发者,

我遇到了加载回调问题(以及扩展名的卸载回调).
我正在尝试按照文档中描述的算法验证请求的真实性. https://developer.bigcommerce.com/apps/load#signed-payload

我能够解码json字符串,数据是正确的,但签名永远不会匹配.我确保使用正确的客户端秘密并尝试了不同的编码/解码方案,没有运气.

另一个问题是它们在示例中(以及在其sample app中)提供的代码片段(PHP).它们似乎在签名匹配时返回null,而在它们不匹配时返回解码数据…(try secureCompare())
这意味着安全测试每次都会通过,因为在我的所有尝试中,签名都不匹配.

我在这里错过了什么吗?

编辑:这是doc中的示例.我不能真正给你样本数据,因为客户的秘密是保密…

function verify($signedRequest, $clientSecret)
{
    list($payload, $encodedSignature) = explode('.', $signedRequest, 2); 

    // decode the data
    $signature = base64_decode($encodedSignature);
    $data = json_decode(base64_decode($payload), true);

    // confirm the signature
    $expectedSignature = hash_hmac('sha256', $payload, $clientSecret, $raw = true);

    if (secureCompare($signature, $expectedSignature)) {
        error_log('Bad Signed JSON signature!');
        return null;
    }

    return $data;
}

function secureCompare($str1, $str2)
{
    $res = $str1 ^ $str2;
    $ret = strlen($str1) ^ strlen($str2); //not the same length, then fail ($ret != 0)
    for($i = strlen($res) - 1; $i >= 0; $i--) {
        $ret += ord($res[$i]);
    }
    return !$ret;
}

最佳答案 你没有遗漏任何东西,这不是时钟同步问题 – 提供的28行示例代码
here
here都有一些非常严重的缺陷:

>示例代码执行原始base64编码的JSON的hash_hmac,而不是base64解码的JSON. (BigCommerce API为您提供的哈希实际上是base64解码的JSON的哈希值).
>由于使用$raw = true调用hash_hmac,这意味着两个字符串将始终存在巨大差异:一个是原始二进制,另一个是十六进制.
>检查secureCompare逻辑是否错误. if(secureCompare …部分验证函数需要与secureCompare函数相反的行为.如果secureCompare函数在字符串匹配时返回true,为什么我们调用error_log?

将所有这三个问题放在一起,最终得到的代码看起来有效,但实际上是默默无效的.如果您使用示例代码,您可能会允许您的应用程序处理任何和所有“签名”请求!

这是我更正的验证函数实现:

<?php

function verifySignedRequest($signedRequest, $clientSecret)
{
    list($encodedData, $encodedSignature) = explode('.', $signedRequest, 2);

    // decode the data
    $signature = base64_decode($encodedSignature);
    $jsonStr = base64_decode($encodedData);
    $data = json_decode($jsonStr, true);

    // confirm the signature
    $expectedSignature = hash_hmac('sha256', $jsonStr, $clientSecret, $raw = false);
    if (!hash_equals($expectedSignature, $signature)) {
        error_log('Bad signed request from BigCommerce!');
        return null;
    }
    return $data;
}
点赞