保护您的facebook chatbot webhook的最佳做法是什么?

时间:2016-04-14 10:48:50

标签: facebook-chatbot

我在facebook messenger平台上开发聊天机器人。我查看了Facebook文档,无法找到如何保护webhook免受随机通话的影响。

例如,如果用户可以使用我的机器人购买东西,那么知道某人的userId的攻击者可以通过拨打我的webhook来开始下载未经授权的订单。

我有几个关于如何保护这个的想法。

  

1)将我的api白名单只用于来自facebook的电话   2)创造一些东西   就像带回发电话的CSRF令牌一样。

有什么想法吗?

2 个答案:

答案 0 :(得分:6)

Facebook当然已经实施了一种机制,您可以通过该机制检查对您的回调网址发出的请求是否真实(其他一切都只是疏忽) - 请参阅https://developers.facebook.com/docs/graph-api/webhooks#receiveupdates

  

HTTP请求将包含X-Hub-Signature标头,其中包含请求负载的SHA1签名,使用app secret作为密钥,并以sha1=为前缀。您的回调端点可以验证此签名以验证有效负载的完整性和来源

     

请注意,计算是在有效负载的转义的unicode 版本上进行的,并使用小写十六进制数字。如果您只是根据解码的字节进行计算,最终会得到不同的签名。例如,字符串äöå应转义为\u00e4\u00f6\u00e5

答案 1 :(得分:0)

除了CBroe的答案外,下面的代码片段还表示将签名验证实现为NestJS保护。

// src/common/guards/signature-verification.guard.ts
@Injectable()
export class SignatureVerificationGuard implements CanActivate {
  constructor(private readonly configService: ConfigService) {}

  canActivate(context: ExecutionContext): boolean {
    const {
      rawBody,
      headers: { 'x-hub-signature': signature },
    } = context.switchToHttp().getRequest();
    const { sha1 } = parse(signature);
    if (!sha1) return false;

    const appSecret = this.configService.get('MESSENGER_APP_SECRET');
    const digest = createHmac('sha1', appSecret).update(rawBody).digest('hex');
    const hashBufferFromBody = Buffer.from(`sha1=${digest}`, 'utf-8');
    const bufferFromSignature = Buffer.from(signature, 'utf-8');

    if (hashBufferFromBody.length !== bufferFromSignature.length)
      return false;

    return timingSafeEqual(hashBufferFromBody, bufferFromSignature);
  }
}
// src/modules/webhook/webhook.controller.ts
@UseGuards(SignatureVerificationGuard)
@Post()
@HttpCode(HttpStatus.OK)
handleWebhook(@Body() data) {
  // ...
}