@n8n/n8n-nodes-langchain
Version:

177 lines • 4.17 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createSecretKeysCheckFn = exports.secretKeysCheck = void 0;
const COMMON_KEY_PREFIXES = [
'key-',
'sk-',
'sk_',
'pk_',
'pk-',
'ghp_',
'AKIA',
'xox',
'SG.',
'hf_',
'api-',
'apikey-',
'token-',
'secret-',
'SHA:',
'Bearer ',
];
const ALLOWED_EXTENSIONS = [
'.py',
'.js',
'.html',
'.css',
'.json',
'.md',
'.txt',
'.csv',
'.xml',
'.yaml',
'.yml',
'.ini',
'.conf',
'.config',
'.log',
'.sql',
'.sh',
'.bat',
'.dll',
'.so',
'.dylib',
'.jar',
'.war',
'.php',
'.rb',
'.go',
'.rs',
'.ts',
'.jsx',
'.vue',
'.cpp',
'.c',
'.h',
'.cs',
'.fs',
'.vb',
'.doc',
'.docx',
'.xls',
'.xlsx',
'.ppt',
'.pptx',
'.pdf',
'.jpg',
'.jpeg',
'.png',
];
const CONFIGS = {
strict: {
min_length: 10,
min_entropy: 3.0,
min_diversity: 2,
strict_mode: true,
},
balanced: {
min_length: 10,
min_entropy: 3.8,
min_diversity: 3,
strict_mode: false,
},
permissive: {
min_length: 30,
min_entropy: 4.0,
min_diversity: 2,
strict_mode: false,
},
};
function entropy(s) {
if (s.length === 0)
return 0;
const counts = {};
for (const c of s) {
counts[c] = (counts[c] || 0) + 1;
}
let entropy = 0;
for (const count of Object.values(counts)) {
const probability = count / s.length;
entropy -= probability * Math.log2(probability);
}
return entropy;
}
function charDiversity(s) {
return [
s
.split('')
.some((c) => c === c.toLowerCase() && c !== c.toUpperCase()),
s
.split('')
.some((c) => c === c.toUpperCase() && c !== c.toLowerCase()),
s
.split('')
.some((c) => /\d/.test(c)),
s
.split('')
.some((c) => !/\w/.test(c)),
].filter(Boolean).length;
}
function containsAllowedPattern(text) {
const urlPattern = /^https?:\/\/[a-zA-Z0-9.-]+\/?[a-zA-Z0-9.\/_-]*$/i;
if (urlPattern.test(text)) {
if (COMMON_KEY_PREFIXES.some((prefix) => text.includes(prefix))) {
return false;
}
return true;
}
const extPattern = new RegExp(`^[^\\s]*(${ALLOWED_EXTENSIONS.map((ext) => ext.replace('.', '\\.')).join('|')})$`, 'i');
return extPattern.test(text);
}
function isSecretCandidate(s, cfg, customRegex) {
if (customRegex) {
for (const pattern of customRegex) {
try {
const regex = new RegExp(pattern);
if (regex.test(s)) {
return true;
}
}
catch {
continue;
}
}
}
if (!cfg.strict_mode && containsAllowedPattern(s)) {
return false;
}
const longEnough = s.length >= cfg.min_length;
const diverse = charDiversity(s) >= cfg.min_diversity;
if (COMMON_KEY_PREFIXES.some((prefix) => s.startsWith(prefix))) {
return true;
}
if (!(longEnough && diverse)) {
return false;
}
return entropy(s) >= cfg.min_entropy;
}
function detectSecretKeys(text, cfg, config) {
const words = text.split(/\s+/).map((w) => w.replace(/[*#]/g, ''));
const secrets = words.filter((w) => isSecretCandidate(w, cfg, config.customRegex));
return {
guardrailName: 'secretKeys',
tripwireTriggered: secrets.length > 0,
info: {
maskEntities: { SECRET: secrets },
detectedSecrets: secrets,
},
};
}
const secretKeysCheck = (data, config) => {
const cfg = CONFIGS[config.threshold];
return detectSecretKeys(data, cfg, config);
};
exports.secretKeysCheck = secretKeysCheck;
const createSecretKeysCheckFn = (config) => (input) => (0, exports.secretKeysCheck)(input, config);
exports.createSecretKeysCheckFn = createSecretKeysCheckFn;
//# sourceMappingURL=secretKeys.js.map