-
Notifications
You must be signed in to change notification settings - Fork 35
fix: the application stores api keys in plaintext js... in cli.js #214
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -892,17 +892,25 @@ function writeCurrentModels(data) { | |
| fs.writeFileSync(CURRENT_MODELS_FILE, JSON.stringify(data, null, 2), 'utf-8'); | ||
| } | ||
|
|
||
| const _authKey = crypto.createHash('sha256').update(AUTH_FILE).digest(); | ||
| function encryptAuthValue(v) { const iv = crypto.randomBytes(16); const c = crypto.createCipheriv('aes-256-cbc', _authKey, iv); return 'enc:' + iv.toString('hex') + ':' + Buffer.concat([c.update(v, 'utf-8'), c.final()]).toString('hex'); } | ||
| function decryptAuthValue(v) { if (!v || !v.startsWith('enc:')) return v; try { const [, h, d] = v.split(':'); const dc = crypto.createDecipheriv('aes-256-cbc', _authKey, Buffer.from(h, 'hex')); return Buffer.concat([dc.update(Buffer.from(d, 'hex')), dc.final()]).toString('utf-8'); } catch (e) { return v; } } | ||
| function updateAuthJson(apiKey) { | ||
| assertToolConfigWriteAllowed('codex'); | ||
| let authData = {}; | ||
| if (fs.existsSync(AUTH_FILE)) { | ||
| try { | ||
| const content = fs.readFileSync(AUTH_FILE, 'utf-8'); | ||
| if (content.trim()) authData = JSON.parse(content); | ||
| if (content.trim()) { | ||
| const raw = JSON.parse(content); | ||
| for (const k of Object.keys(raw)) authData[k] = decryptAuthValue(raw[k]); | ||
| } | ||
| } catch (e) { } | ||
|
Comment on lines
+906
to
908
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win Fail closed instead of overwriting unreadable auth data. If parsing or decrypting any value fails—including a valid JSON value that is not a string—the empty catch leaves 🤖 Prompt for AI Agents |
||
| } | ||
| authData['OPENAI_API_KEY'] = apiKey; | ||
| fs.writeFileSync(AUTH_FILE, JSON.stringify(authData, null, 2), { encoding: 'utf-8', mode: 0o600 }); | ||
| const out = {}; | ||
| for (const k of Object.keys(authData)) out[k] = encryptAuthValue(authData[k]); | ||
| fs.writeFileSync(AUTH_FILE, JSON.stringify(out, null, 2), { encoding: 'utf-8', mode: 0o600 }); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win Enforce
🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| function isPlainObject(value) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🔴 Critical
🧩 Analysis chain
🏁 Script executed:
Repository: SakuraByteCore/codexmate
Length of output: 9346
Do not derive the encryption key from
AUTH_FILE.sha256(AUTH_FILE)is predictable; anyone who can read the known~/.codex/auth.jsonpath can derive the same key and decrypt the stored API key. Use a real secret/key store for this protection, or avoid encrypting credentials with path-derived material. Also prefer authenticated encryption (for example AES-GCM) and reject failed authentication tags rather than falling back to treating malformed ciphertext as plaintext.[high_effort_and_high_review]
🤖 Prompt for AI Agents