Просмотр исходного кода

Merge pull request #811 from anthropics/kenneth/chmod-env-files

Lock telegram/discord .env files to owner (chmod 600)
Kenneth Lien 5 месяцев назад
Родитель
Сommit
562a27feec

+ 3 - 1
external_plugins/discord/server.ts

@@ -25,7 +25,7 @@ import {
   type Attachment,
 } from 'discord.js'
 import { randomBytes } from 'crypto'
-import { readFileSync, writeFileSync, mkdirSync, readdirSync, rmSync, statSync, renameSync, realpathSync } from 'fs'
+import { readFileSync, writeFileSync, mkdirSync, readdirSync, rmSync, statSync, renameSync, realpathSync, chmodSync } from 'fs'
 import { homedir } from 'os'
 import { join, sep } from 'path'
 
@@ -37,6 +37,8 @@ const ENV_FILE = join(STATE_DIR, '.env')
 // Load ~/.claude/channels/discord/.env into process.env. Real env wins.
 // Plugin-spawned servers don't get an env block — this is where the token lives.
 try {
+  // Token is a credential — lock to owner. No-op on Windows (would need ACLs).
+  chmodSync(ENV_FILE, 0o600)
   for (const line of readFileSync(ENV_FILE, 'utf8').split('\n')) {
     const m = line.match(/^(\w+)=(.*)$/)
     if (m && process.env[m[1]] === undefined) process.env[m[1]] = m[2]

+ 2 - 1
external_plugins/discord/skills/configure/SKILL.md

@@ -80,7 +80,8 @@ as the correct long-term choice. Don't skip the lockdown offer.
 2. `mkdir -p ~/.claude/channels/discord`
 3. Read existing `.env` if present; update/add the `DISCORD_BOT_TOKEN=` line,
    preserve other keys. Write back, no quotes around the value.
-4. Confirm, then show the no-args status so the user sees where they stand.
+4. `chmod 600 ~/.claude/channels/discord/.env` — the token is a credential.
+5. Confirm, then show the no-args status so the user sees where they stand.
 
 ### `clear` — remove the token
 

+ 3 - 1
external_plugins/telegram/server.ts

@@ -18,7 +18,7 @@ import {
 import { Bot, InputFile, type Context } from 'grammy'
 import type { ReactionTypeEmoji } from 'grammy/types'
 import { randomBytes } from 'crypto'
-import { readFileSync, writeFileSync, mkdirSync, readdirSync, rmSync, statSync, renameSync, realpathSync } from 'fs'
+import { readFileSync, writeFileSync, mkdirSync, readdirSync, rmSync, statSync, renameSync, realpathSync, chmodSync } from 'fs'
 import { homedir } from 'os'
 import { join, extname, sep } from 'path'
 
@@ -30,6 +30,8 @@ const ENV_FILE = join(STATE_DIR, '.env')
 // Load ~/.claude/channels/telegram/.env into process.env. Real env wins.
 // Plugin-spawned servers don't get an env block — this is where the token lives.
 try {
+  // Token is a credential — lock to owner. No-op on Windows (would need ACLs).
+  chmodSync(ENV_FILE, 0o600)
   for (const line of readFileSync(ENV_FILE, 'utf8').split('\n')) {
     const m = line.match(/^(\w+)=(.*)$/)
     if (m && process.env[m[1]] === undefined) process.env[m[1]] = m[2]

+ 2 - 1
external_plugins/telegram/skills/configure/SKILL.md

@@ -77,7 +77,8 @@ offer.
 2. `mkdir -p ~/.claude/channels/telegram`
 3. Read existing `.env` if present; update/add the `TELEGRAM_BOT_TOKEN=` line,
    preserve other keys. Write back, no quotes around the value.
-4. Confirm, then show the no-args status so the user sees where they stand.
+4. `chmod 600 ~/.claude/channels/telegram/.env` — the token is a credential.
+5. Confirm, then show the no-args status so the user sees where they stand.
 
 ### `clear` — remove the token