howdyai / botkit

Botkit is an open source developer tool for building chat bots, apps and custom integrations for major messaging platforms.
MIT License
11.49k stars 2.28k forks source link

Invalid signature on incoming request #1696

Closed mhjb closed 4 years ago

mhjb commented 5 years ago

Context:

I'm upgrading this bot from botkit 0.6.2 to 4.0.

When I follow the code examples in the docs, and start the bot, with each message from Messenger, I get this error:

Experienced an error inside the turn handler Error: Invalid signature on incoming request

My (working) 0.6.2 code looks like (forgive the coffeescript if you can), stripping out a bit of guff:

Botkit = require 'botkit'
controller = Botkit.facebookbot
  access_token: process.env.fb_page_token
  verify_token: process.env.fb_verify_token
  app_secret: process.env.fb_app_secret
  validate_requests: true
  receive_via_postback: true

port = process.env.PORT or 3000
controller.setupWebserver port, (err, webserver) ->
  controller.createWebhookEndpoints webserver, bot

My erroring new code looks like:

{ Botkit } = require 'botkit'
{ FacebookAdapter, FacebookEventTypeMiddleware } = require 'botbuilder-adapter-facebook'

adapter = new FacebookAdapter
    verify_token: process.env.fb_verify_token
    access_token: process.env.fb_page_token
    app_secret: process.env.fb_app_secret

adapter.use new FacebookEventTypeMiddleware()

controller = new Botkit
  webhook_uri: '/facebook/receive'
  adapter: adapter
batamar commented 5 years ago

@mhjb there should be req.rawBody available if you are using your own express server

app.use((req: any, _res, next) => {
  req.rawBody = '';

  req.on('data', chunk => {
    req.rawBody += chunk.toString().replace(/\//g, '/');
  });

  next();
});
mhjb commented 5 years ago

Thanks @batamar  — but I'm not using my own express server.

benbrown commented 5 years ago

@mhjb are you still experiencing this?

realnsleo commented 5 years ago

Hey @benbrown I am still experiencing this issue as of botkit 4.0.1. Any reason why this is happening?

PXMYH commented 5 years ago

I'm having the same issue, and not using my own express server either

mhjb commented 5 years ago

Sorry for the slow reply, @benbrown ; I'm not sure, actually; the project has moved along a bit.

I did see that one gets this error when app_secret is incorrect or missing.

PXMYH commented 5 years ago

This seems to be caused by verifySignature function in FacebookAdapter module, is there anyway to disable it for local development purpose? I've been reading https://github.com/howdyai/botkit-docs/blob/master/docs/readme-facebook.md#validate-requests---secure-your-webhook but that seems out dated and setting validate_requests to false doesn't do anything since that option doesn't exist in the adapter source code.

This issue still exists after moving to v4.5 release

benbrown commented 5 years ago

@PXMYH are you saying that, when correctly configured, this verifySignature function does not properly verify the incoming webhooks?

q00u commented 5 years ago

Any update on this? How do we test Facebook locally? Is it impossible?

q00u commented 5 years ago

I'm still getting this in a botbuilder bot when testing locally. app_secret is set correctly. I know this because the bot worked when running without the adapter in azure, but since that's going away on December 16th, I want to get it working in adapter form before then.

mhjb commented 5 years ago

In case it's helpful, here's an example of where I'm using it my code (sorry, Coffeescript – you can translate with http://js2.coffee/) — which works locally (with ngrok), and remotely.

benbrown commented 5 years ago

@mhjb did you mean to include some code there?

mhjb commented 5 years ago

Sorry + thanks + I've edited my comment now.

benbrown commented 5 years ago

@q00u can you paste example code where you are initializing your adapter?

q00u commented 5 years ago

I'm doing it exactly like it's shown in BotBuilder Basics (The token/secret values have been added to .env).

benbrown commented 5 years ago

@q00u Using the code below, I am not able to reproduce your issue. This is the same as BotBuilder basics, though it also includes the verification endpoint and the call to server.listen() that are not (yet) in the sample docs.

const { FacebookAdapter } = require('botbuilder-adapter-facebook');
const restify = require('restify');

const adapter = new FacebookAdapter({
     verify_token: process.env.FACEBOOK_VERIFY_TOKEN,
     app_secret: process.env.FACEBOOK_APP_SECRET,
     access_token: process.env.FACEBOOK_ACCESS_TOKEN
});
const server = restify.createServer();
server.use(restify.plugins.bodyParser());
server.use(restify.plugins.queryParser());

server.get('/api/messages', (req, res) => {
     if (req.query['hub.mode'] === 'subscribe') {
          if (req.query['hub.verify_token'] === process.env.FACEBOOK_VERIFY_TOKEN) {
               const val = req.query['hub.challenge'];
               res.sendRaw(200, val);
          } else {
               console.log('failed to verify endpoint');
               res.send('OK');
          }
     }
});

server.post('/api/messages', (req, res) => {
     adapter.processActivity(req, res, async(context) => {
         await context.sendActivity('I heard a message!');
     });
});

server.listen(process.env.port || process.env.PORT || 3000, () => {
     console.log(`\n${ server.name } listening to ${ server.url }`);
 });
benbrown commented 5 years ago

@q00u is there anything substantially different about your code?

q00u commented 5 years ago

Nothing substantially different other than the two things you mentioned not being in the sample docs yet. You can connect to this with the emulator and it works?

benbrown commented 5 years ago

@q00u Sorry for the confusion about this:

No, you cannot connect with the emulator to the bot using botbuilder-adapter-facebook.

This adapter speaks the Facebook messenger protocol, not the Bot Framework protocol. It works differently than the ABS channel service.

If you want to test with emulator, swap out the Bot Framework adapter for the Facebook one.

q00u commented 5 years ago

It's now passing the Edit Callback URL verification, and the bot is running successfully on Facebook. Is that because of the endpoint verification section? Was that all I needed?

benbrown commented 5 years ago

The callback URL verification endpoint is necessary to change the URL in Facebook's settings.

Previously I hadn't really considered that to be part of the necessary Adapter sample code, but I have since added it to the boilerplate example in the readme file.

benbrown commented 5 years ago

If you continue to experience this issue: