javascriptnode.jsexpresscryptographywebsub

Verify pubsubhubbub content signature in Node/Express


I'm new to Express, and I'm muddling through implementing a middleware to handle a X-Hub-Signature as described here: https://pubsubhubbub.googlecode.com/git/pubsubhubbub-core-0.4.html#authednotify

I'd like to add a middleware that handles this, before passing the request onto the standard express.json() middleware to actually decode the body.

var sigVerifier = function(req, res, next) {

    var buf = '';
    // Need to accumulate all the bytes... <--- HOW TO DO THIS?

    // then calculate HMAC-SHA1 on the content.
    var hmac = crypto.createHmac('sha1', app.get('client_secret'));
    hmac.update(buf);
    var providedSignature = req.headers['X-Hub-Signature'];
    var calculatedSignature = 'sha1=' + hmac.digest(encoding='hex');
    if (providedSignature != calculatedSignature) {
        console.log(providedSignature);
        console.log(calculatedSignature);
        res.send("ERROR");
        return;
    }
    next();
};

app.use(sigVerifier);
app.use(express.json());

Solution

  • Express uses connect's middleware for json. You can pass an options object to the json body parser to verify the content before it continues parsing.

    function verifyHmac(req, res, buf) {
      // then calculate HMAC-SHA1 on the content.
      var hmac = crypto.createHmac('sha1', app.get('client_secret'));
      hmac.update(buf);
      var providedSignature = req.headers['X-Hub-Signature'];
      var calculatedSignature = 'sha1=' + hmac.digest(encoding='hex');
      if (providedSignature != calculatedSignature) {
        console.log(
          "Wrong signature - providedSignature: %s, calculatedSignature: %s",
          providedSignature,
          calculatedSignature);
        var error = { status: 400, body: "Wrong signature" };
        throw error;
      }
    }
    
    app.use(express.json({verify: verifyHmac}));