📄 03-data-handling.md
⬇ Download Raw

Data Handling, File I/O, Privacy & Encryption Audit

Audit Date: 2026-04-28 Codebase: scorpiox/clang (C) Auditor: Security Audit Agent Scope: File I/O, PII, credential management, encryption, temporary files, logging, data retention

1. Executive Summary

The scorpiox codebase is a large C project (~100+ non-vendor source files) implementing an AI coding assistant with TUI, multiplexer, email server, DNS server, container runtime, and SDK components. The audit identified several critical findings around hardcoded credentials in the WASM embedded config, plaintext config files storing API keys and SSH passwords, and unsalted SHA256 password hashing in the email module. Traffic logging correctly redacts authorization headers in most providers, but the OpenAI provider logs request URLs without API key redaction when keys are passed via URL. Session data (conversations, traces, events) is stored unencrypted on the local filesystem.

Risk Rating: HIGH — Primarily due to hardcoded secrets in compiled binaries and weak password hashing.

2. Data Flow Summary

User Input → TUI (sx.c)

├→ Configuration (sx_config.c) ← scorpiox-env.txt (3 cascade levels)

├→ Provider (sx_provider_*.c) → HTTP/TLS → External API

│ ├→ Traffic Logs (.scorpiox/sessions/<id>/traffic/)

│ └→ API Keys from config / env vars / embedded config

├→ Session Manager (sx_session.c)

│ ├→ conversation.json (full history)

│ ├→ session.log (debug output)

│ ├→ events.jsonl (structured events)

│ ├→ trace.jsonl (data flow trace)

│ ├→ config-snapshot.txt (frozen config)

│ └→ meta.json (metadata)

├→ Conversation Store (.scorpiox/conversations/*.json)

├→ Email Server (sxmail_*.c) → Maildir format

│ ├→ Auth accounts file (user:hash)

│ └→ TLS via mbedTLS

├→ Multiplexer (sxmux_*.c) → Unix domain sockets in /tmp/sxmux/

├→ Usage Tracking → POST to code.scorpiox.net/usage-send

└→ Session Emit → POST to code.scorpiox.net/sessions-send


3. File I/O Inventory

3.1 Configuration Files

FileOperationPurposeSensitivity
exe_dir/scorpiox-env.txtReadGlobal config (API keys, SSH creds, URLs)CRITICAL — contains plaintext secrets
~/.claude/scorpiox-env.txtReadUser-level config overrideCRITICAL — may contain API keys
CWD/.scorpiox/scorpiox-env.txtRead/WriteProject-level config overrideHIGH — may contain API keys
sx_config_embedded.cCompiled-inWASM binary embedded configCRITICAL — hardcoded secrets

3.2 Session & Conversation Files

FileOperationPurposeSensitivity
.scorpiox/sessions//conversation.jsonRead/WriteFull conversation historyHIGH — may contain user secrets shared in chat
.scorpiox/sessions//session.logAppendDebug/info/error loggingMEDIUM — may contain API error details
.scorpiox/sessions//events.jsonlAppendStructured event logMEDIUM
.scorpiox/sessions//trace.jsonlAppendData flow traceMEDIUM — tool inputs/outputs
.scorpiox/sessions//config-snapshot.txtWriteConfig dump at session startHIGH — may contain API keys
.scorpiox/sessions//meta.jsonWriteSession metadataLOW
.scorpiox/sessions//traffic/raw/*.txtWriteRaw HTTP request/responseHIGH — API payloads
.scorpiox/conversations/.jsonRead/WritePersistent conversation storageHIGH

3.3 Email Server Files

FileOperationPurposeSensitivity
Email accounts file (configurable)Readuser:sha256_hash pairsHIGH — password hashes
Maildir {cur,new,tmp}/Read/WriteEmail storage (Maildir format)HIGH — email contents
~/.scorpiox/server-email.logAppendEmail server daemon logMEDIUM
TLS cert/key files (configurable)ReadTLS certificates and private keysCRITICAL
DKIM private key (configurable)ReadDKIM signing keyCRITICAL

3.4 Multiplexer Files

FileOperationPurposeSensitivity
/tmp/sxmux/sxmux-.sockCreate/DeleteUnix domain socket for sessionLOW
/tmp/sxmux/sxmux-.pidRead/Write/DeletePID file for sessionLOW

3.5 WhatsApp Bridge Files

FileOperationPurposeSensitivity
.scorpiox/whatsapp/auth/creds.jsonRead/WriteWhatsApp auth credentialsCRITICAL
.scorpiox/whatsapp/inbox/WriteIncoming messagesHIGH — message contents

3.6 Other Files

FileOperationPurposeSensitivity
.scorpiox/sessions//required_skills.txtRead/WriteAgent skill requirementsLOW
/tmp/sx_emit__.txtWriteTemporary session emit filesMEDIUM — session data
/tmp/sx-edit-*.txtCreate/Read/DeleteTemporary editor filesMEDIUM — user input
.scorpiox/traffics//WriteTraffic capture outputHIGH
.gitignoreRead/AppendGit ignore managementLOW
/var/log/scorpiox-dns/AppendDNS audit logsMEDIUM — query data

4. PII Assessment

4.1 Data Collected and Transmitted

The usage tracking system (scorpiox-usage.c) sends the following to code.scorpiox.net/usage-send:

FieldTypePII Risk
hostnameMachine identifierMEDIUM — correlatable
usernameOS usernameHIGH — direct PII
os, arch, os_versionSystem infoLOW
session_idSession identifierLOW
provider, modelService infoLOW
project, branchDevelopment contextMEDIUM — business context
scorpiox_versionVersion stringLOW
input_tokens, output_tokensUsage metricsLOW
Mitigation: Usage tracking is configurable (USAGE_TRACKING=0 to disable, default: 0 in embedded). Session emit tracking is also opt-in (EMIT_SESSION_TRACKING, default: 0).

4.2 Email Server PII

The email server inherently handles PII:

4.3 Conversation Data

All user prompts and AI responses are stored in plaintext JSON files under .scorpiox/sessions/ and .scorpiox/conversations/. No encryption at rest is applied. Users may inadvertently share passwords, tokens, or other secrets in conversations, which are then persisted to disk.


5. Credential Management

5.1 CRITICAL: Hardcoded Secrets in Embedded Config

File: scorpiox/libsxutil/sx_config_embedded.c Severity: 🔴 CRITICAL

The WASM embedded config contains hardcoded API keys and SSH credentials compiled into the binary:

KeyValue (Redacted)Risk
ANTHROPIC_ANTIGRAVITY_KEYsk-6088a10... (full key)CRITICAL — hardcoded API key
ANTHROPIC_ZAI_KEY9c6fba5d...ue19jY48d9GmddqX (full key)CRITICAL — hardcoded API key
GEMINI_API_KEYAIzaSyDs...IQHVA8 (full key)CRITICAL — hardcoded API key
CLAUDE_CODE_SSH_PASSxboxoneCRITICAL — hardcoded SSH password
CLAUDE_CODE_SSH_HOST192.168.1.6HIGH — internal infrastructure
CLAUDE_CODE_SSH_PORT22223MEDIUM
CLAUDE_CODE_SSH_USERrootHIGH — root access
TCP_HOST20.53.240.54MEDIUM — infrastructure IP
TMUX_REMOTE_HOSTroot@192.168.1.3HIGH — internal infrastructure
TMUX_SMB_SHARE//192.168.1.3/GitHubMEDIUM — internal SMB share

These secrets are extractable from the compiled WASM binary by any user.

5.2 Config File Credential Storage

File: scorpiox/libsxutil/sx_config.c Severity: 🟠 HIGH

The scorpiox-env.txt config cascade stores credentials in plaintext:

ANTHROPIC_API_KEY=sk-...

CLAUDE_CODE_SSH_PASS=...

CODEX_SSH_PASS=...

SMTP_PASS=...

GEMINI_API_KEY=AIza...

OPENAI_API_KEY=sk-...

Issues:

5.3 Non-Embedded Defaults

The non-embedded config defaults (sx_config.c) are mostly empty for sensitive keys:

5.4 API Key Handling in Providers

ProviderKey SourceIn-Memory StorageHeader Redaction in Logs
Anthropic (sx_provider_anthropic.c)Config API_KEY / ANTHROPIC_API_KEYStack char api_key[512]N/A (no traffic logging)
Claude Code (sx_provider_claude_code.c)OAuth token via fetchtokenHeap char oauth_token[2048][REDACTED] in traffic logs
Gemini (scorpiox-gemini.c)Env GEMINI_API_KEYStack variablekey=[REDACTED] in traffic logs
OpenAI (scorpiox-openai.c)Env OPENAI_API_KEYStack via http_post() param⚠️ URL logged without key redaction

5.5 Token Fetch Mechanism

scorpiox-claudecode-fetchtoken.c fetches OAuth tokens via:
  • Raw TCP (no TLS) to proxy.scorpiox.net:9800HIGH RISK: tokens transmitted in cleartext
  • SSH tunnel to remote host
  • HTTP endpoint

  • 6. Encryption Usage

    6.1 TLS Implementation (Email Server)

    Library: mbedTLS (vendored) File: scorpiox/sxmail_tls.c

    6.2 DKIM Signing

    File: scorpiox/sxmail_dkim.c

    6.3 Password Hashing

    File: scorpiox/sxmail_auth.c Severity: 🟠 HIGH
    int sxmail_auth_hash_password(const char pass, char out, size_t out_sz) {
    

    unsigned char digest[32];

    mbedtls_sha256((const unsigned char *)pass, strlen(pass), digest, 0);

    // ... hex encode ...

    }

    Issues: Positive: sxmail_auth_free() properly zeroes sensitive data with memset() before free().

    6.4 Data at Rest Encryption


    7. Temporary File Security

    7.1 Editor Temp Files

    File: scorpiox/sx.c, line 612
    snprintf(tmpfile, sizeof(tmpfile), "%s%csx-edit-%d.txt", ...);
    

    FILE *f = fopen(tmpfile, "wb");

    7.2 Session Emit Temp Files

    File: scorpiox/sx.c, line 1285
    snprintf(tmp_file, sizeof(tmp_file), "/tmp/sx_emit_%s_%04d.txt", ...);
    

    7.3 Maildir Temp Files

    File: scorpiox/sxmail_maildir.c

    7.4 Multiplexer Socket/PID Files


    8. Logging Analysis

    8.1 Logging Framework

    Files: scorpiox/libsxutil/sx_log.c, sx_log.h

    8.2 Sensitive Data in Logs

    WhatWhereLogged?Risk
    API keysProvider initMasked ()✅ Safe
    OAuth tokensTraffic logs[REDACTED]✅ Safe
    Gemini API key in URLTraffic logskey=[REDACTED]✅ Safe
    Failed login usernamesEmail authFull username logged⚠️ MEDIUM
    SSH passwordsConfig loadingNot explicitly logged✅ Safe
    Config valuesDEBUG levelMay include sensitive values⚠️ MEDIUM if DEBUG enabled
    Usage payloadsDEBUG levelSX_DEBUG("usage: payload: %s", json) — includes hostname, username⚠️ MEDIUM
    Config snapshotSession fileFull config dump to file🟠 HIGH* — may include keys

    8.3 Config Snapshot Risk

    sx_session_write_config_snapshot() writes the full configuration to config-snapshot.txt in the session directory. If API keys are configured, they will be written to this file in plaintext.

    9. Environment Variable Usage

    9.1 Sensitive Environment Variables

    VariableUsed InSensitivity
    ANTHROPIC_API_KEYsx_provider_anthropic.cCRITICAL — API secret
    GEMINI_API_KEYscorpiox-gemini.cCRITICAL — API secret
    OPENAI_API_KEYscorpiox-openai.cCRITICAL — API secret
    AGENTS_PATscorpiox-agent.cCRITICAL — Git PAT token
    CLAUDE_CODE_SSH_PASSconfig systemHIGH — SSH password
    IMAGE_BASE_URLscorpiox-wsl.c, scorpiox-vm.cMEDIUM — download source
    UPDATE_URLscorpiox-wsl.cMEDIUM — update source

    9.2 All Environment Variables Read

    The codebase reads 59 unique environment variables via getenv(). Notable categories:

    9.3 PAT Masking

    File: scorpiox-unshare.c, line 2410–2424

    The --pat argument value is partially masked in log output (first 3 chars shown, rest replaced). ✅ Good practice, though incomplete (should mask entirely).


    10. Data Retention

    10.1 Session Cleanup

    10.2 Unmanaged Data Retention

    The following data has no automated cleanup:

    DataLocationConcern
    Conversation files.scorpiox/conversations/.jsonAccumulate indefinitely
    WhatsApp auth/inbox.scorpiox/whatsapp/Credentials persist until manual logout
    Traffic captures.scorpiox/traffics/Manual cleanup only (--clear flag)
    DNS audit logs/var/log/scorpiox-dns/No rotation configured
    Email server log~/.scorpiox/server-email.logGrows indefinitely (append mode)
    Maildir email storageConfigurable pathNo automatic purging
    Temp files in /tmp//tmp/sx_emit_, /tmp/sx-edit-*Rely on OS cleanup

    11. Risk Assessment

    Critical Findings

    #FindingSeverityLocationRecommendation
    1Hardcoded API keys and SSH passwords in embedded config🔴 CRITICALsx_config_embedded.cRemove all secrets from source code; use runtime-only configuration
    2Plaintext API keys in config files with 0755 directory permissions🟠 HIGHsx_config.cEncrypt sensitive values or use OS keychain; restrict permissions to 0600
    3Unsalted SHA256 password hashing for email auth🟠 HIGHsxmail_auth.cReplace with bcrypt/scrypt/Argon2 with per-user salt
    4Raw TCP token fetch without TLS🟠 HIGHscorpiox-claudecode-fetchtoken.cRequire TLS for all token transmission
    5Config snapshot may contain API keys🟠 HIGHsx_session.cRedact sensitive config keys before writing snapshot
    6Predictable temp file names in /tmp/🟡 MEDIUMsx.cUse mkstemp() for all temporary files
    7No encryption at rest for conversations, sessions, email🟡 MEDIUMMultipleConsider encrypted storage for sensitive data
    8OpenAI URL logged without key redaction🟡 MEDIUMscorpiox-openai.cAdd key redaction to URL logging
    9Failed login usernames logged🟡 MEDIUMsxmail_auth.cConsider rate-limiting log volume; don't log full usernames at WARN
    10Usage tracking sends hostname/username to remote server🟡 MEDIUMscorpiox-usage.cHash or anonymize before transmission

    Positive Findings

    #FindingLocation
    1✅ OAuth tokens properly redacted in Claude Code traffic logssx_provider_claude_code.c
    2✅ Gemini API key redacted in traffic logsscorpiox-gemini.c
    3✅ API keys masked as * in provider init loggingsx_provider_anthropic.c
    4✅ Auth entry memory zeroed before freesxmail_auth.c
    5✅ Multiplexer socket directory created with 0700 permissionssxmux_session.c
    6✅ Maildir uses atomic tmp→new rename patternsxmail_maildir.c
    7✅ TLS properly implemented via mbedTLSsxmail_tls.c
    8✅ DKIM signing uses standard RSA-SHA256sxmail_dkim.c
    9✅ Usage/session tracking is opt-in (disabled by default)sx_config.c
    10✅ Session retention with automated cleanupsx_session.c
    11✅ PAT argument partially masked in logsscorpiox-unshare.c

    12. Recommendations Summary

    Immediate (P0)

  • Remove all hardcoded secrets from sx_config_embedded.c — rotate all exposed keys immediately
  • Upgrade password hashing from SHA256 to Argon2id with per-user random salt
  • Add TLS to the TCP token fetch path
  • Short-term (P1)

  • Restrict config file permissions to 0600 (owner-only read/write)
  • Redact sensitive keys from config-snapshot.txt before writing
  • Use mkstemp() for all temporary file creation
  • Add key redaction to OpenAI traffic URL logging
  • Medium-term (P2)

  • Implement encrypted storage for config secrets (OS keychain integration or file encryption)
  • Add log rotation for email server and DNS audit logs
  • Add automated cleanup for conversation files and traffic captures
  • Anonymize telemetry data (hash hostname/username before sending)

  • End of Data Handling Audit Report