#109 MCP Logging — Fully operational. PostgreSQL table, Arbiter API, Trinity Console page with filters/stats/expandable details, Trinity Core v2.3.0 POSTs logs after every command. #111 Trinity Core Web MCP — Completed by Chronicler #77. Claude.ai native connector working since Apr 11. #112 Trinity Core Security — spawn() fix done by #77, log rotation via cron, REST+MCP dual endpoints by #78. Chronicler #78 | firefrost-operations-manual
4.7 KiB
task_number, title, status, priority, is_blocker, owner, tags, estimated_hours
| task_number | title | status | priority | is_blocker | owner | tags | estimated_hours | |||
|---|---|---|---|---|---|---|---|---|---|---|
| 112 | Trinity Core Security Hardening | Complete | P1-High | true | Michael |
|
3 |
Trinity Core Security Hardening
Address security concerns identified by Gemini before deploying web MCP upgrade.
Why This is a Blocker
Trinity Core provides root SSH access to 7 production servers. Before enabling multi-user access (Holly, Meg) or native Claude.ai integration, we must address these vulnerabilities.
Issue 1: Command Injection (CRITICAL)
The Problem: Current code:
const sshCmd = `ssh -o ConnectTimeout=10 ${target.user}@${target.host} "${command.replace(/"/g, '\\"')}"`;
exec(sshCmd, ...);
This only escapes double quotes. Subshells $(...), backticks `...`, and environment variables $VAR are NOT escaped. A prompt injection attack could execute arbitrary commands.
Example Attack:
Command: echo $(cat /etc/shadow)
Result: Dumps password hashes
The Fix:
Use child_process.spawn with array arguments instead of exec with string interpolation:
import { spawn } from 'child_process';
function executeCommand(server, command) {
return new Promise((resolve, reject) => {
const target = SERVERS[server];
// spawn prevents shell interpretation
const ssh = spawn('ssh', [
'-o', 'ConnectTimeout=10',
`${target.user}@${target.host}`,
command // passed as single argument, not interpolated into shell
]);
let stdout = '';
let stderr = '';
ssh.stdout.on('data', (data) => stdout += data);
ssh.stderr.on('data', (data) => stderr += data);
ssh.on('close', (code) => {
resolve({
success: code === 0,
stdout: stdout.trim(),
stderr: stderr.trim(),
code
});
});
ssh.on('error', reject);
});
}
Status: ❌ Not implemented — MUST FIX before web MCP deployment
Issue 2: AI Concurrency / Race Conditions (MEDIUM)
The Problem: If Chronicler and Catalyst both run commands on the same server simultaneously:
- Catalyst restarts Docker
- Chronicler deploys container
- Chronicler's command fails or corrupts deployment
The Fix: Add server locking to Arbiter:
CREATE TABLE server_locks (
server VARCHAR(50) PRIMARY KEY,
locked_by VARCHAR(50),
locked_at TIMESTAMP,
expires_at TIMESTAMP
);
Before executing, check lock. If locked, return: "tx1-dallas is currently locked by The Catalyst. Please try again in a moment."
Status: ⏳ Future enhancement — not critical for initial deployment
Issue 3: SD Card Wear & Log Exhaustion (HIGH)
The Problem:
- Pi SD cards have finite write cycles
fs.appendFileSyncon every command wears the card- No log rotation = disk fills up
The Fix (Implemented): Added cron job to rotate logs daily:
0 0 * * * truncate -s 0 /home/claude_executor/mcp-server/command.log && echo "[$(date -Iseconds)] Log rotated" >> /home/claude_executor/mcp-server/command.log
Better Long-term Fix: Send logs to Arbiter's PostgreSQL instead of local disk (Task #109 already covers this).
Status: ✅ Mitigated with cron rotation
Issue 4: Cloudflare Access Layer (MEDIUM)
The Problem:
mcp.firefrostgaming.com is public. Malicious requests hit the Pi even if rejected by auth.
The Fix: Enable Cloudflare Access (Zero Trust) for the subdomain:
- Only allow requests from Anthropic IP ranges
- Or require Cloudflare Service Token header
- Drops malicious traffic at edge before reaching Pi
Status: ⏳ Future enhancement — token auth is sufficient for now
Issue 5: System Prompt Alignment (LOW)
The Problem: AI partners won't know how to use Trinity Core unless told.
The Fix: Update system prompts / project instructions for:
- Chronicler: Already has Trinity Core context in project instructions
- Catalyst: Add Trinity Core section to Catalyst project
- The Orb: Add Trinity Core section to Orb project
Include:
- Available servers
- How to run commands
- What requires approval
- What to do on timeout
Status: ⏳ Document when Catalyst/Orb projects are created
Implementation Checklist
Before Web MCP Deployment (Task #111):
- Fix command injection with
spawninstead ofexec - Verify log rotation is working
After Initial Deployment:
- Consider Cloudflare Access
- Consider server locking for concurrency
- Update Catalyst/Orb system prompts when created
Related Tasks
- Task #109: MCP Logging in Trinity Console (moves logs off Pi)
- Task #111: Trinity Core Web MCP Connector (main implementation)
Fire + Frost + Foundation = Where Love Builds Legacy 💙🔥❄️