Skip to content

Commit

Permalink
Fix transaction ID implementation and verify Event.body is indeed bas…
Browse files Browse the repository at this point in the history
…e64 when isBase64 is true. (#31)

* Add transaction ID for lambda responses

* Add tests

* Add more checks for falsy values

* double check if it is base64 even if aws event says it is base64 (#33)

* minor fixes

* fixed tests  for isBase64

* bump version

---------

Co-authored-by: Xingheng Wang <[email protected]>
Co-authored-by: xinghengwang <[email protected]>
  • Loading branch information
3 people authored Sep 19, 2024
1 parent d433fb1 commit 8eb907f
Show file tree
Hide file tree
Showing 9 changed files with 867 additions and 24 deletions.
32 changes: 31 additions & 1 deletion lib/dataUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,35 @@ function _getEventModelFromRequestandResponse(
return logData;
}

function isStrBase64(str) {
// Check if the string length is divisible by 4
if (!str) {
return false;
}
if (typeof str !== "string") {
return false;
}

if (str.length % 4 !== 0) {
return false;
}

// Check if the string contains only valid Base64 characters
const base64Regex = /^[A-Za-z0-9+/]+={0,2}$/;
if (!base64Regex.test(str)) {
return false;
}

try {
// Use Buffer for Node.js and atob for browsers
const decoded = Buffer.from(str, "base64").toString("utf-8");
console.log("" + decoded);
return true;
} catch (e) {
return false;
}
}

module.exports = {
getUrlFromRequestOptions: _getUrlFromRequestOptions,
getEventModelFromRequestandResponse: _getEventModelFromRequestandResponse,
Expand All @@ -237,5 +266,6 @@ module.exports = {
bodyToBase64: _bodyToBase64,
hashSensitive: _hashSensitive,
logMessage: logMessage,
ensureToString: ensureToString
ensureToString: ensureToString,
isStrBase64: isStrBase64
};
15 changes: 3 additions & 12 deletions lib/extractDataFromEventAndContext.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
var requestIp = require('request-ip');
var dataUtils = require('./dataUtils');
var url = require('url');
const { v4: uuid4 } = require('uuid');

var safeJsonParse = dataUtils.safeJsonParse;
var isStrBase64 = dataUtils.isStrBase64;

function getIpAddress(event, context, isV1) {
if (isV1) {
Expand Down Expand Up @@ -152,7 +152,8 @@ function constructBaseLogData(
logData.metadata = options.getMetadata(event, context);

if (options.logBody && event.body) {
if (event.isBase64Encoded) {
if (event.isBase64Encoded && isStrBase64(event.body)) {
// need to verify if body is actually base64.
logData.request.body = event.body;
logData.request.transferEncoding = "base64";
} else {
Expand All @@ -176,16 +177,6 @@ function constructBaseLogData(
logData.blockedBy = logData.response.headers['X-Moesif-Blocked-By'];
}

// Add transaction ID to request and response
let disableTransactionId = options.disableTransactionId
? options.disableTransactionId
: false;
if (!disableTransactionId) {
let transactionId = logData.request.headers['X-Moesif-Transaction-Id'] || uuid4();
logData.response.headers['X-Moesif-Transaction-Id'] = transactionId;
logData.request.headers['X-Moesif-Transaction-Id'] = transactionId;
}

if (options.logBody && safeRes.body) {
if (safeRes.isBase64Encoded) {
logData.response.body = safeRes.body;
Expand Down
27 changes: 21 additions & 6 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict'
const _ = require('lodash');
const { v4: uuid4 } = require('uuid');
const moesifapi = require('moesifapi');
const moesifConfigManager = require('./moesifConfigManager');
const governanceRulesManager = require('./governanceRulesManager');
Expand Down Expand Up @@ -69,7 +70,7 @@ module.exports = function (options, handler) {
// config moesifapi
var config = moesifapi.configuration;
config.ApplicationId = options.applicationId || options.ApplicationId || process.env.MOESIF_APPLICATION_ID;
config.UserAgent = 'moesif-aws-lambda-nodejs/' + '2.0.3';
config.UserAgent = 'moesif-aws-lambda-nodejs/' + '2.0.5';
config.BaseUri = options.baseUri || options.BaseUri || config.BaseUri;
var moesifController = moesifapi.ApiController;

Expand Down Expand Up @@ -157,16 +158,30 @@ module.exports = function (options, handler) {
var moesifMiddleware = function (event, context, callback) {
moesifConfigManager.tryGetConfig();

const transactionId = event.headers && event.headers['X-Moesif-Transaction-Id'];
const responseTransactionId = transactionId || uuid4();

let extraHeaders = {
'X-Moesif-Transaction-Id': responseTransactionId,
};

logMessage(options.debug, 'moesifMiddleware', 'start');

var next = function (err, result) {
logEvent(event, context, err, result, options, moesifController);
callback(err, result)
const modifiedResultObject = {
...result,
headers: {
...(result.headers || {}),
...extraHeaders,
}
}
logEvent(event, context, err, modifiedResultObject, options, moesifController);
callback(err, modifiedResultObject)
};

const isV1 = determineIsEventVersionV1(event);

let returnPromise;
let extraHeaders = {};
if (governanceRulesManager.hasRules()) {
var requestDataForGovernance = prepareRequestDataForGovernance(event, context, isV1);

Expand All @@ -183,15 +198,15 @@ module.exports = function (options, handler) {
);

if (governedResponseHolder.headers) {
extraHeaders = governedResponseHolder.headers;
extraHeaders = { ...extraHeaders, ...governedResponseHolder.headers };
}

if (governedResponseHolder.blocked_by) {
returnPromise = Promise.resolve({
isBase64Encoded: false,
statusCode: governedResponseHolder.status,
headers: {
...governedResponseHolder.headers,
...extraHeaders,
'X-Moesif-Blocked-By': governedResponseHolder.blocked_by
},
body: JSON.stringify(governedResponseHolder.body)
Expand Down
Loading

0 comments on commit 8eb907f

Please sign in to comment.