I have a function which loops over the keys of an object and looks for sensitive keys like email, key, password, apiKey, secrets, secret and userKey.
If it finds any that have a value, it redacts the value.
However, its failing sometimes with an error like:
"RangeError: Maximum call stack size exceeded"
Whats causing the endless recursion??
const deepObjectRedactor = obj => {
const sensitiveKeys = [
'email',
'key',
'password',
'apiKey',
'secrets',
'secret',
'userKey'
];
Object.keys(obj).forEach(key => {
if (
sensitiveKeys.map(e => e.toLowerCase()).includes(key.toLowerCase()) &&
obj[key]
) {
obj[key] = '**********';
return;
}
if (obj[key] && typeof obj[key] === 'object') {
deepObjectRedactor(obj[key]);
}
});
};
// function invoking the redactor
const customRedactorFormat = info => {
if (info.message && typeof info.message === 'object') {
deepObjectRedactor(info.message);
}
return info;
});
asked May 21, 2021 at 7:09
nishkaush
1,5481 gold badge14 silver badges22 bronze badges
1 Answer 1
You can write a generic map that works for objects and arrays. And then write redact as a specialization of map -
function map (t, f)
{ switch (t?.constructor)
{ case Array:
return t.map((v, k) => f(k, map(v, f)))
case Object:
return Object.fromEntries(
Object.entries(t).map(([k, v]) => [k, f(k, map(v, f))])
)
default:
return t
}
}
const redact = (t, keys = new Set) =>
map(t, (k, v) => keys.has(k) ? "*****" : v)
const data =
[ { user: 1, cc: 1234, password: "foo" }
, { nested: [ { a: 1, pin: 999 }, { b: 2, pin: 333 } ] }
, { deeply: [ { nested: [ { user: 2, password: "here" } ] } ] }
]
console.log(redact(data, new Set(["cc", "password", "pin"])))
[
{
"user": 1,
"cc": "*****",
"password": "*****"
},
{
"nested": [
{
"a": 1,
"pin": "*****"
},
{
"b": 2,
"pin": "*****"
}
]
},
{
"deeply": [
{
"nested": [
{
"user": 2,
"password": "*****"
}
]
}
]
}
]
answered May 22, 2021 at 19:26
Mulan
136k35 gold badges240 silver badges276 bronze badges
Sign up to request clarification or add additional context in comments.
1 Comment
Freeman Lambda
Code is much cleaner than OP's, but OP's code has the exact same result on your sample
data object. Im fairly certain their issue lies in the Object they are trying to recurse over (likely a circular reference). jsfiddle.net/o6fhbLxr lang-js
sensitiveKeys.findinstead ofsensitiveKeys.mapmight be one of the problem.sensitiveKeys.includes(key.toLowerCase());?sensitiveKeysis a constant in your function. If you want them to be all lower case, define them as all lower case. Instead of lower casing them over and over and over.object