chrome-cookie-extractor
Version:
Extract and decrypt Chrome cookies with curl integration - includes auth-curl command for authenticated requests
163 lines • 6.97 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CookieDecryptor = void 0;
const crypto = __importStar(require("crypto"));
const os = __importStar(require("os"));
const child_process_1 = require("child_process");
class CookieDecryptor {
/**
* Decrypt a cookie value that may be a Buffer, Uint8Array, or ArrayBuffer.
*/
static decryptValue(encryptedValue) {
// Ensure we have a Buffer to work with
const buffer = Buffer.isBuffer(encryptedValue)
? encryptedValue
: Buffer.from(encryptedValue);
if (os.platform() !== 'darwin') {
// Non-macOS platforms - return as is (might not be encrypted)
return buffer.toString('utf8');
}
try {
// Check for Chrome v80+ encryption prefix
if (buffer.subarray(0, 3).toString() === 'v10' ||
buffer.subarray(0, 3).toString() === 'v11') {
// Get Chrome Safe Storage password from Keychain
const password = this.getChromeSafeStoragePassword();
if (!password) {
return '[ENCRYPTED]';
}
// Derive AES key using PBKDF2
const salt = Buffer.from('saltysalt');
const iterations = 1003;
const keyLength = 16;
const key = crypto.pbkdf2Sync(password, salt, iterations, keyLength, 'sha1');
// Extract the encrypted data after removing v10/v11 prefix
const encryptedData = buffer.subarray(3); // Remove v10/v11 prefix
// Use AES-CBC decryption based on pycookiecheat implementation
try {
// Chrome uses AES-CBC with fixed IV of 16 space characters
const iv = Buffer.alloc(16, ' '); // 16 bytes of space character as IV
const decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
decipher.setAutoPadding(false); // Handle padding manually
let decrypted = Buffer.concat([
decipher.update(encryptedData),
decipher.final()
]);
// Remove PKCS7 padding manually
const paddingLength = decrypted[decrypted.length - 1];
if (paddingLength && paddingLength <= 16) {
decrypted = decrypted.subarray(0, decrypted.length - paddingLength);
}
const result = decrypted.toString('utf8');
if (result && result.length > 0 && result.length < 10000 && !result.includes('\0')) {
return result;
}
}
catch (e) {
// Silent fail - decryption not possible
}
return '[ENCRYPTED]';
}
else {
// Older encryption format or unencrypted
const result = buffer.toString('utf8');
// Check if it looks like valid cookie data (no null bytes)
if (result && result.length > 0 && !result.includes('\0')) {
return result;
}
return '[ENCRYPTED]';
}
}
catch (error) {
console.error('Cookie decryption failed:', error);
return '[ENCRYPTED]';
}
}
static getChromeSafeStoragePassword() {
try {
// First try the simple approach that works
try {
const result = (0, child_process_1.execSync)('security find-generic-password -w -s "Chrome Safe Storage"', {
encoding: 'utf8',
stdio: ['pipe', 'pipe', 'pipe']
});
const password = result.trim();
if (password) {
return Buffer.from(password, 'base64');
}
}
catch (error) {
// Fall back to the comprehensive approach
}
// Try different service names and account names
const usernames = [
process.env.USER,
process.env.LOGNAME,
os.userInfo().username,
'al02628760' // Fallback
].filter(Boolean);
for (const service of this.CHROME_SAFE_STORAGE_SERVICES) {
for (const username of usernames) {
try {
const command = [
'security',
'find-generic-password',
'-w',
'-s', `"${service}"`,
'-a', `"${username}"`
];
const result = (0, child_process_1.execSync)(command.join(' '), {
encoding: 'utf8',
stdio: ['pipe', 'pipe', 'pipe']
});
const password = result.trim();
if (password) {
return Buffer.from(password, 'base64');
}
}
catch (error) {
// Continue trying other combinations
continue;
}
}
}
console.error('Could not find Chrome Safe Storage password in Keychain');
return null;
}
catch (error) {
console.error('Error accessing Keychain:', error);
return null;
}
}
}
exports.CookieDecryptor = CookieDecryptor;
CookieDecryptor.CHROME_SAFE_STORAGE_SERVICES = [
'Chrome Safe Storage',
'Chromium Safe Storage',
'Brave Safe Storage',
'Edge Safe Storage'
];
//# sourceMappingURL=decryptor.js.map