compare auth token against SHA-1 HMAC of POST body

This commit is contained in:
Maciek Nowacki 2021-03-12 15:10:49 -07:00
parent 473fa4b662
commit 7ba8716917
2 changed files with 13 additions and 6 deletions

View File

@ -16,5 +16,5 @@ module.exports = {
algorithm: ['HS256'] algorithm: ['HS256']
}, },
messageTypes : ['broadcast', 'direct', 'changeChannel'], messageTypes : ['broadcast', 'direct', 'changeChannel'],
archimedesToken: process.env.ARCHIMEDES_INTEGRATION_TOKEN || 'sha1=da39a3ee5e6b4b0d3255bfef95601890afd80709' archimedesToken: process.env.ARCHIMEDES_INTEGRATION_TOKEN || 'testkeyformeasure'
}; };

View File

@ -11,7 +11,7 @@ const AUTH_TOKEN = app.archimedesToken;
const HTTP_PORT = app.port; const HTTP_PORT = app.port;
import { Server, IncomingMessage, ServerResponse } from 'http' import { Server, IncomingMessage, ServerResponse } from 'http'
import * as bodyParser from "body-parser";
interface ArchimedesMessage { interface ArchimedesMessage {
examId: string, examId: string,
reservation_no: string reservation_no: string
@ -25,8 +25,12 @@ class XhrListener {
this.#cm = cm; this.#cm = cm;
logger.debugLog.info("XhrListener running"); logger.debugLog.info("XhrListener running");
app.use(jsonParser); //app.use(jsonParser);
// turns out that we must compute HMAC based on the payload of the POST body, so:
app.use(bodyParser.json({
verify: ((req: any, res: any, buf: any) => { req.rawBody = buf })
}));
// TODO: try to pin down origin to reflect client rather than use wildcard // TODO: try to pin down origin to reflect client rather than use wildcard
app.options('*', cors()); app.options('*', cors());
@ -39,19 +43,22 @@ class XhrListener {
app.post('/event/pause', cors(), app.post('/event/pause', cors(),
(req: any, res: any, next: any) => this.eventFromArchimedes.bind(this)("pauseExam", req, res)); (req: any, res: any, next: any) => this.eventFromArchimedes.bind(this)("pauseExam", req, res));
server.on('request', app); server.on('request', app);
// note that this kicks off HTTP listen for the entire app - not just HTTP but WS as well! // note that this kicks off HTTP listen for the entire app - not just HTTP but WS as well!
server.listen(HTTP_PORT, () => logger.debugLog.info(`braid is now listening for HTTP and WS connections on port ${HTTP_PORT}`)); server.listen(HTTP_PORT, () => logger.debugLog.info(`braid is now listening for HTTP and WS connections on port ${HTTP_PORT}`));
} }
public authorized(authOffered: String): boolean { public authorized(authOffered: String, rawBody: Buffer): boolean {
return AUTH_TOKEN === authOffered; var hash = crypto.createHmac('sha1', AUTH_TOKEN).update(rawBody).digest("hex");
return authOffered.split("=").reverse()[0] === hash;
} }
public eventFromArchimedes(eventType: string, req: any, res: any) { public eventFromArchimedes(eventType: string, req: any, res: any) {
logger.debugLog.info(`eventFromArchimedes("${eventType}") called`); logger.debugLog.info(`eventFromArchimedes("${eventType}") called`);
let authorized: boolean = this.authorized(req.headers['x-proctoru-signature']); let authorized: boolean = this.authorized(req.headers['x-proctoru-signature'], req.rawBody);
if (!authorized) { if (!authorized) {
res.status(401); res.status(401);