الملفات
ghaymah-v2-audits/Binary_Hardening_Compliance_Report.md

7.9 KiB

🛡️ Ghaymah CLI v2 — Attacker-Accessible Surface & Binary Hardening Audit

Target Artifact: gy-linux-amd64 (Production Release Candidate)
Source: https://cliv2.ghaymah.systems/gy-linux-amd64
Auditor: DevSecOps QA & Threat Modeling Assessment
Date: September 20, 2026
Focus: 100% Verifiable, Extracted Artifacts Available to an External Attacker


📊 Executive Summary Checklist

Hardening Directive Compiler/Tool Flag Required State Actual State Attacker Accessibility Status
Symbol Stripping -ldflags="-s" No .symtab / .strtab Absent Inaccessible (Symbols removed) PASS
Debug Info Stripping -ldflags="-w" No DWARF .debug_* sections Absent Inaccessible (DWARF removed) PASS
Path Obfuscation -trimpath Zero developer machine paths Zero leaks Inaccessible (No /home/ or C:\Users\) PASS
Binary Compression upx --best --lzma Packed (UPX0, UPX1, UPX!) Uncompressed (11.69 MB) 🔴 EXPOSED (Plaintext strings in .rodata) FAIL
Token Storage Local Encryption AES-GCM Encrypted Plaintext JSON 🔴 EXPOSED (Accessible via config.json) FAIL
TLS Pinset Integrity Hardcoded SHA-256 4 Valid Base64 Hashes 4 Hashes in binary 🟡 VISIBLE (Extracted via strings) PASS

🏗️ Reconstructed Attack Topology (Extracted via Static Analysis)

Using only data extracted from the uncompressed gy-linux-amd64 binary and local filesystem artifacts, an attacker can reconstruct the complete backend microservice topology without access to source code:

graph TD
    subgraph "Attacker-Controlled Local Host"
        ATTACKER["Attacker / Local Process"]
        BINARY["gy-linux-amd64<br>(11.69 MB Unpacked ELF)"]
        CONF["~/.config/ghaymah/cli/nhost/config.json<br>🔴 Plaintext Tokens Stored Here"]
    end

    subgraph "Exposed Backend Endpoints (Extracted from .rodata)"
        AUTH["auth.ghaymah.systems<br>(Nhost Authentication API)"]
        GQL["graphql.ghaymah.systems<br>(Hasura GraphQL API)"]
        S3["s3-nhost-proxy-83e02743fd61.hosted.ghaymah.systems<br>🔴 Exposed Object Storage Proxy"]
        LOGS["logs.ghaymah.systems<br>(Log Streaming Server)"]
        GENAI["genai.ghaymah.systems<br>(LiteLLM AI Service)"]
        REG["registry.ghaymah.systems<br>(Container Registry)"]
        CLI_SRV["cli.ghaymah.systems / cliv2.ghaymah.systems<br>(Update & Distribution Host)"]
    end

    ATTACKER -- "1. Read plaintext refreshToken" --> CONF
    ATTACKER -- "2. Extract strings & endpoints" --> BINARY
    ATTACKER -- "3. Direct API calls using stolen token" --> AUTH
    ATTACKER -- "4. Direct GraphQL queries/mutations" --> GQL
    ATTACKER -- "5. Direct artifact upload / probing" --> S3
    ATTACKER -- "6. Inspect container images" --> REG

🕵️‍♂️ Extracted Artifacts & Attacker-Accessible Surface

The data below represents only what an attacker can directly extract from the binary and local configuration using standard analysis tools (strings, grep, cat):

1. Extracted Backend Endpoints & Domains (.rodata)

These URLs were extracted directly from the uncompressed data segments of gy-linux-amd64:

auth.ghaymah.systems
graphql.ghaymah.systems
logs.ghaymah.systems
genai.ghaymah.systems
registry.ghaymah.systems
cli.ghaymah.systems
s3-nhost-proxy-83e02743fd61.hosted.ghaymah.systems
foundhosted.ghaymah.systems

Caution

Attacker Advantage: The specific S3 proxy subdomain (s3-nhost-proxy-83e02743fd61.hosted.ghaymah.systems) reveals the exact storage gateway used for project build context uploads, allowing an attacker to probe the storage service directly without using the CLI.


2. Extracted Internal Go Packages & Architecture (.gopclntab)

Even with -s -w applied, Go's runtime program counter line table retains package import paths. An attacker extracts:

gitlab.com/ghaymah/go-utils
gitlab.com/ghaymah/go-utils/config
gitlab.com/ghaymah/go-utils/nhost
gitlab.com/ghaymah/go-utils/graphql

Note

This reveals that Ghaymah CLI v2 is architected around go-utils with dedicated Nhost auth and Hasura GraphQL client modules.


3. Extracted TLS Public Key Pinset Hashes

The 4 SHA-256 certificate public key hashes are visible in cleartext in the binary:

deRrEjh64wYgxRJ15ayqnD8aBMGHkjGDhegIOZzN3iw=
Jmmi4aU72CahnGAT6ZT6yvWeSv1g1lhahkiK5RDipn8=
T/t6LfgixGVf2RPIMpusT0c7memko1cGuHVTMRRyTqY=
zSJTbrWU36arxt/HzAm7GrMc5op3vsJkUlBDxj4jLHI=

4. Extracted Security Rules & Error Messages

By analyzing string literals, an attacker can reverse-engineer input validation and scanner logic without reading source code:

# Input Validation Rule Leakage:
"invalid app name '%s' — use only letters, numbers, and hyphens (no spaces or slashes)"

# Proxy Detection Leakage:
"Security Warning: A system proxy (%s) was detected. It will be ignored for authentication to prevent credential interception."

# Pre-Deploy Scanner Leakage:
"Wildcard COPY/ADD Detected — Sensitive File Leakage Risk"
"Container Runs as Root User"
"Lines [%s] use wildcard copy instructions (COPY . / or ADD . /) which will include ALL files"
"TLS Pinning failed: public key mismatch. Got %s, which is not in the trusted pinset"

5. Extracted Plaintext Credentials (CWE-312)

Directly extracted from ~/.config/ghaymah/cli/nhost/config.json on the local machine:

{
  "token": {
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODk5NDk4NzQsImh0dHBzOi8vaGFzdXJhLmlvL2p3dC9jbGFpbXMiOnsieC1oYXN1cmEtYWxsb3dlZC1yb2xlcyI6WyJtZSIsInVzZXIiXSwieC1oYXN1cmEtZGVmYXVsdC1yb2xlIjoidXNlciIsIngtaGFzdXJhLXVzZXItaWQiOiJkNjJmOTg4Ni1mY2VkLTRjZjItOThlNC01YjYyMDAwZDRmMDMiLCJ4LWhhc3VyYS11c2VyLWlzLWFub255bW91cyI6ImZhbHNlIn0sImlhdCI6MTc4OTg1OTg3NCwiaXNzIjoiaGFzdXJhLWF1dGgiLCJzdWIiOiJkNjJmOTg4Ni1mY2VkLTRjZjItOThlNC01YjYyMDAwZDRmMDMifQ...",
    "refreshToken": "11a90303-237e-467b-b324-54d6ef6e5cf5",
    "expiresAt": "2026-09-21T00:17:53.875260112Z",
    "userId": "d62f9886-fced-4cf2-98e4-5b62000d4f03"
  }
}

Caution

Critical Finding: An attacker who accesses this file gains full, perpetual access to the user's Ghaymah cloud account via the refreshToken, completely bypassing the CLI.


🛡️ What the Attacker CANNOT Access (Verified Defenses)

Despite the string leaks, the following security barriers were successfully verified:

  1. No Developer Machine Paths: Searching for C:\Users\, /home/, or /Users/ yielded 0 matches. The -trimpath flag completely stripped build environment paths.
  2. No High-Level Source Code / Comments: Symbol stripping (-s -w) removed all .symtab, .strtab, and DWARF debugging data. The attacker cannot reconstruct the original Go source code or variable names.
  3. No Credential Interception via Proxy: Setting HTTP_PROXY or HTTPS_PROXY fails to capture traffic because the binary explicitly ignores proxies for authentication.
  4. No Direct Injection via CLI Flags: Attempts to pass SQLi, XSS, or Path Traversal in --name or --id are blocked locally by regex before any network request is sent.

📋 Remediation Priority Checklist

Priority Issue Threat Vector Fix Action
🔴 P0 Plaintext Tokens (CWE-312) Local account takeover via config.json Encrypt config.json with AES-256-GCM using Machine ID salt.
🟡 P1 Uncompressed Binary (CWE-200) Trivial endpoint & architecture extraction Apply upx --best --lzma to scramble string data and reduce size by ~70%.
🟢 P2 Internal Package Names Reconnaissance via .gopclntab Use Go build obfuscators (e.g., garble) if full symbol obfuscation is required.