nhsuk / betahealth

Rendering application for beta symptom and condition pages
https://beta.nhs.uk
MIT License
2 stars 8 forks source link

Replace all unsafe chars in preview signatures #247

Closed marcofucci closed 7 years ago

marcofucci commented 7 years ago

The code only replaced the first occurrence of unsafe chars meaning that the resulting signature did not match the backend one.

I wrote a test nodejs script that generates random signatures and calls an equivalent python one to check that they match.

nodejs script

const crypto = require('crypto');
const spawn = require('child_process').spawn;

const PREVIEW_SIGNATURE_KEY = 'mxwtt97p8[)89+Qm8xwMWTXK](Qc&MhdT=dW72bfhL/du4({sR';

function generateSignature(pageId, revisionId) {
  const message = `${pageId}/${revisionId}/`;
  const hmacSha1 = crypto.createHmac('sha1', PREVIEW_SIGNATURE_KEY).update(message).digest('base64');
  return hmacSha1.replace(/\+/g, '-').replace(/\//g, '_');
}

for (let i = 0; i <= 100; i++) {
  const pageId = Math.random();
  const revisionId = Math.random();
  const process = spawn('python3', ['test_preview.py', pageId, revisionId]);

  process.stdout.on('data', (chunk) => {
    const pythonSignature = chunk.toString('utf8').trim();
    const jsSignature = generateSignature(pageId, revisionId);

    if (jsSignature !== pythonSignature) {
      console.log(pythonSignature);
      console.log(jsSignature);
    }
  });
}

python script

import base64
import hashlib
import hmac
import sys

KEY = 'mxwtt97p8[)89+Qm8xwMWTXK](Qc&MhdT=dW72bfhL/du4({sR'.encode()

def generate_signature(page_id, revision_id):
    url = '{}/{}/'.format(page_id, revision_id)
    return base64.urlsafe_b64encode(
        hmac.new(KEY, url.encode(), hashlib.sha1).digest()
    ).decode('utf-8')

print(generate_signature(sys.argv[1], sys.argv[2]))
sys.stdout.flush()