security-helpers.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /**
  2. * Security helper functions for decrypting database credentials
  3. */
  4. const crypto = require('crypto');
  5. require('dotenv').config();
  6. // Get the secret key from environment variables
  7. const SECRET_KEY = process.env.SECRET_KEY;
  8. // Get encrypted values from environment variables
  9. const encryptedValues = {
  10. dbHost: process.env.ENCRYPTED_DB_HOST,
  11. dbName: process.env.ENCRYPTED_DB_NAME,
  12. dbTable: process.env.ENCRYPTED_DB_TABLE,
  13. dbUsername: process.env.ENCRYPTED_DB_USERNAME,
  14. dbPassword: process.env.ENCRYPTED_DB_PASSWORD
  15. };
  16. /**
  17. * Decrypt an encrypted string
  18. */
  19. function decryptValue(encryptedText) {
  20. try {
  21. const parts = encryptedText.split(':');
  22. if (parts.length !== 3) return null; // Not our encrypted format
  23. const iv = Buffer.from(parts[0], 'hex');
  24. const authTag = Buffer.from(parts[1], 'hex');
  25. const encryptedData = parts[2];
  26. const decipher = crypto.createDecipheriv('aes-256-gcm', Buffer.from(SECRET_KEY, 'hex'), iv);
  27. decipher.setAuthTag(authTag);
  28. let decrypted = decipher.update(encryptedData, 'hex', 'utf8');
  29. decrypted += decipher.final('utf8');
  30. return decrypted;
  31. } catch (error) {
  32. // If decryption fails, it's probably not our encrypted value
  33. return null;
  34. }
  35. }
  36. /**
  37. * Process function body to replace encrypted credentials with decrypted values
  38. */
  39. function processEncryptedCredentials(functionBody) {
  40. if (!functionBody) return functionBody;
  41. let processedBody = functionBody;
  42. // Check for dynamic pattern matches first (hex:hex:hex)
  43. const encryptionPattern = /['"]([0-9a-f]+:[0-9a-f]+:[0-9a-f]+)['"]/g;
  44. let match;
  45. while ((match = encryptionPattern.exec(functionBody)) !== null) {
  46. const potentialEncrypted = match[1];
  47. const decrypted = decryptValue(potentialEncrypted);
  48. if (decrypted) {
  49. // Replace in the function body, keeping the quotes that surrounded it
  50. const fullMatch = match[0];
  51. const replacement = fullMatch[0] + decrypted + fullMatch[fullMatch.length - 1];
  52. processedBody = processedBody.replace(fullMatch, replacement);
  53. }
  54. }
  55. // Also check for known encrypted values
  56. Object.entries(encryptedValues).forEach(([key, encryptedValue]) => {
  57. if (processedBody.includes(encryptedValue)) {
  58. const decrypted = decryptValue(encryptedValue);
  59. if (decrypted) {
  60. processedBody = processedBody.replace(
  61. new RegExp(`['"]${encryptedValue}['"]`, 'g'),
  62. `"${decrypted}"`
  63. );
  64. }
  65. }
  66. });
  67. return processedBody;
  68. }
  69. /**
  70. * NEW: Process and decrypt arguments array
  71. * Specifically designed to handle encrypted credentials passed as function arguments
  72. */
  73. function processEncryptedArguments(args) {
  74. if (!Array.isArray(args)) return args;
  75. return args.map(arg => {
  76. // Check if this looks like an encrypted credential
  77. if (typeof arg === 'string' && arg.includes(':') && arg.length > 40) {
  78. const decrypted = decryptValue(arg);
  79. if (decrypted) {
  80. console.log(`[SECURITY-HELPERS] Successfully decrypted argument: ${arg.substring(0, 20)}...`);
  81. return decrypted;
  82. } else {
  83. console.log(`[SECURITY-HELPERS] Failed to decrypt argument: ${arg.substring(0, 20)}...`);
  84. }
  85. }
  86. return arg;
  87. });
  88. }
  89. /**
  90. * NEW: All-in-one function to process both function body and arguments
  91. */
  92. function processAllEncryptedData(functionBody, args = []) {
  93. const processedBody = processEncryptedCredentials(functionBody);
  94. const processedArgs = processEncryptedArguments(args);
  95. return {
  96. processedBody,
  97. processedArgs
  98. };
  99. }
  100. module.exports = {
  101. decryptValue,
  102. processEncryptedCredentials,
  103. processEncryptedArguments, // NEW
  104. processAllEncryptedData, // NEW
  105. encryptedValues
  106. };