From 99aefec16e070026f9f72ac13ce417ba65111f2f Mon Sep 17 00:00:00 2001 From: Mahmoud20301 Date: Fri, 21 Aug 2026 12:18:04 +0300 Subject: [PATCH] updated --- Readme.md | 206 +++++++++++++++++- test-projects/arg-secret-test/.gy.json | 13 ++ test-projects/arg-secret-test/Dockerfile | 4 + test-projects/empty-deploy-test/.gy.json | 13 ++ test-projects/empty-deploy-test/Dockerfile | 10 + test-projects/pem-inclusion-test/.gy.json | 13 ++ test-projects/pem-inclusion-test/Dockerfile | 4 + test-projects/pem-inclusion-test/fake_key.pem | 3 + test-projects/pem-inclusion-test/secrets.json | 1 + 9 files changed, 261 insertions(+), 6 deletions(-) create mode 100644 test-projects/arg-secret-test/.gy.json create mode 100644 test-projects/arg-secret-test/Dockerfile create mode 100644 test-projects/empty-deploy-test/.gy.json create mode 100644 test-projects/empty-deploy-test/Dockerfile create mode 100644 test-projects/pem-inclusion-test/.gy.json create mode 100644 test-projects/pem-inclusion-test/Dockerfile create mode 100644 test-projects/pem-inclusion-test/fake_key.pem create mode 100644 test-projects/pem-inclusion-test/secrets.json diff --git a/Readme.md b/Readme.md index c9bee64..27f082d 100644 --- a/Readme.md +++ b/Readme.md @@ -32,8 +32,17 @@ - [Git Metadata Exposure](#git-metadata-exposure) - [Dockerfile Hardcoded Secret Detection](#dockerfile-hardcoded-secret-detection) - [AI-Assisted Secret Detection](#ai-assisted-secret-detection) -8. [Known Issues & Bugs](#known-issues--bugs) -9. [Verdict Summary Table](#verdict-summary-table) +8. [Additional Tests — Edge & Error Cases](#additional-tests--edge--error-cases) + - [Login with Wrong Credentials](#1-login-with-wrong-credentials) + - [Delete Non-Existent Project](#2-delete-non-existent-project) + - [gy logs — Existing App](#3-gy-logs--existing-app) + - [gy logs — Non-Existent App](#4-gy-logs--non-existent-app) + - [gy logs — Duplicate App Name](#5-gy-logs--duplicate-app-name) + - [Deploy Empty Directory](#6-deploy-empty-directory) + - [PEM & secrets.json File Inclusion](#7-pem--secretsjson-file-inclusion) + - [Dockerfile ARG Secret Detection](#8-dockerfile-arg-secret-detection) +9. [Known Issues & Bugs](#known-issues--bugs) +10. [Verdict Summary Table](#verdict-summary-table) --- @@ -52,7 +61,8 @@ This document reports the results of manual functional and security testing perf | Tunneling | 1 | 0 | 0 | 1 | | Delete Operations | 2 | 1 | 1 | 0 | | Security Tests | 5 | 2 | 0 | 3 | -| **Total** | **20** | **12** | **2** | **5** | +| Edge & Error Cases | 8 | 5 | 1 | 2 | +| **Total** | **28** | **17** | **3** | **7** | --- @@ -526,6 +536,182 @@ Application started --- +## Additional Tests — Edge & Error Cases + +### 1. Login with Wrong Credentials + +| Field | Details | +|---|---| +| **Command** | `gy login` | +| **Input** | Invalid email + short password (`wrongpassword` → length < 3 test) | +| **Result** | ✅ Pass — proper error returned | + +**Output:** +``` +Error: login failed: sign in request failed: request failed with status 400: +"minimum string length is 3" (at /password) +``` + +The CLI surfaces a clear, actionable error. Exit code is `1`. + +> **Note:** The raw OpenAPI schema validation error is exposed directly to the user. A more user-friendly message such as `"Invalid email or password"` would improve UX. + +--- + +### 2. Delete Non-Existent Project + +| Field | Details | +|---|---| +| **Command** | `gy delete project this-project-does-not-exist` | +| **Result** | ✅ Pass — clear error, no crash | + +**Output:** +``` +Error: project 'this-project-does-not-exist' not found — create it with 'gy deploy' or check the name +``` + +The CLI handles the not-found case gracefully with a helpful suggestion. + +--- + +### 3. gy logs — Existing App + +| Field | Details | +|---|---| +| **Command** | `gy logs --no-follow` | +| **Result** | ✅ Pass | + +**Output:** +``` +ℹ️ Streaming logs for app ... +───────────────────────────────── +2026-08-21T09:07:02Z Ready! Add a CMD to your Dockerfile +``` + +The command correctly streams logs and respects the `--no-follow` flag to exit after printing. + +--- + +### 4. gy logs — Non-Existent App + +| Field | Details | +|---|---| +| **Command** | `gy logs this-app-does-not-exist` | +| **Result** | ✅ Pass — clear error | + +**Output:** +``` +Error: app 'this-app-does-not-exist' not found — deploy it first with 'gy deploy' +``` + +Not-found case is handled correctly with a clear, actionable error message. + +--- + +### 5. gy logs — Duplicate App Name + +| Field | Details | +|---|---| +| **Command** | `gy logs pem-inclusion-test --no-follow` | +| **Result** | ❌ Fail — ambiguous target | + +**Output:** +``` +Error: multiple apps named 'pem-inclusion-test' — use 'gy list apps' to see them all +``` + +The **duplicate names bug** (previously documented for `gy delete app`) also affects `gy logs`. Any command that resolves apps by friendly name is impacted. Running `gy logs` **from within the project directory** (without specifying a name) correctly resolves the app and works as expected. + +--- + +### 6. Deploy Empty Directory + +| Field | Details | +|---|---| +| **Command** | `gy deploy` (from empty directory) | +| **Result** | ⚠️ Partial — deploys successfully but produces no useful app | + +**Steps:** +1. Created a completely empty directory with no files. +2. Ran `gy deploy` — the CLI auto-detected the project type as `Unknown`, auto-generated a Dockerfile, and deployed successfully. +3. Checked logs: the container started but had no CMD to execute. + +**Output (deploy):** +``` +ℹ️ Detected: Unknown +ℹ️ Auto-generated: Dockerfile +⚠️ WARNING: We auto-generated a Dockerfile for you... +✅ Deploy complete! + URL: https://empty-deploy-test-72d66f287027.hosted.ghaymah.systems +``` + +**Output (logs):** +``` +Ready! Add a CMD to your Dockerfile +``` + +> **Bug:** The CLI should warn or refuse to deploy an empty directory, not silently deploy a broken container. An empty deployment wastes resources and may confuse users who expect a valid running application. + +--- + +### 7. PEM & secrets.json File Inclusion + +| Field | Details | +|---|---| +| **Command** | `gy deploy --debug` | +| **Test** | Verified whether `.pem` private key and `secrets.json` are included in the deployed container | +| **Result** | ❌ Fail — both files appear in container | + +**Steps:** +1. Created a project containing `fake_key.pem` (RSA private key format) and `secrets.json` (fake DB password). +2. Deployed without a `.dockerignore`. +3. Inspected container via `gy logs --no-follow`. + +**Output (logs):** +``` +=== FILE LIST === +-rw-rw-r-- Dockerfile +-rw-rw-r-- fake_key.pem +-rw-rw-r-- secrets.json +=== PEM CHECK === +-----BEGIN RSA PRIVATE KEY----- +FAKEFAKEFAKEFAKEFAKEFAKE +-----END RSA PRIVATE KEY----- +=== SECRETS CHECK === +FAKE_DB_PASSWORD=supersecret123 +``` + +> **Security Issue:** This confirms that the sensitive file inclusion problem is not limited to `.env` files. **Any file** — including private keys (`.pem`, `id_rsa`) and JSON secrets — is included in the deployed container if no `.dockerignore` is configured. The CLI provides no warning about sensitive files. + +--- + +### 8. Dockerfile ARG Secret Detection + +| Field | Details | +|---|---| +| **Command** | `gy deploy --debug` | +| **Test** | Verified whether CLI detects hardcoded secrets in `ARG` instructions | +| **Result** | ✅ Pass (with note) — `ARG` value not exposed at runtime | + +**Dockerfile used:** +```dockerfile +FROM alpine +ARG BUILD_SECRET="FAKE_ARG_SECRET_99999" +RUN echo "Build done" +CMD ["sh", "-c", "echo BUILD_SECRET=${BUILD_SECRET}; sleep 30"] +``` + +**Output (logs):** +``` +BUILD_SECRET= +``` + +The `ARG` value is **empty at runtime** because Docker `ARG` variables are scoped to the build stage and are not inherited by the running container unless explicitly promoted to `ENV`. + +> **Note:** While `ARG` secrets are not exposed at container runtime, they **can appear in the Docker build history** (`docker history --no-trunc`). The CLI still produced no warning about the `ARG` instruction containing a secret-like value. + +--- + ## Verdict Summary Table | Test | Command | Status | Notes | @@ -543,10 +729,18 @@ Application started | Go Web Deploy | `gy deploy --port=8000` | ✅ Pass | Auto-detected + deployed | | FastAPI Deploy | `gy deploy --port=8000` | ⚠️ Partial | Wrong CMD in generated Dockerfile | | Tunnel | `gy tunnel start` | ❌ Fail | Wrong port + empty URL + false live status | -| Delete Project | `gy delete project` | ✅ Pass | Confirmation prompt works | +| Delete Project (existing) | `gy delete project` | ✅ Pass | Confirmation prompt works | | Delete App | `gy delete app` | ⚠️ Partial | Fails on duplicate names | | Secret in CLI Output | `gy deploy --debug` | ✅ Pass | No leakage in output | -| Sensitive File Inclusion | `gy deploy --debug` | ❌ Fail | `.env` included without `.dockerignore` | +| Sensitive File Inclusion (.env) | `gy deploy --debug` | ❌ Fail | `.env` included without `.dockerignore` | | Git Metadata Exposure | `gy deploy --debug` | ✅ Pass | `.git` excluded | -| Dockerfile Secret Detection | `gy deploy --debug` | ❌ Fail | No warning for `ENV` secrets | +| Dockerfile `ENV` Secret | `gy deploy --debug` | ❌ Fail | No warning for `ENV` secrets | | AI Secret Detection | `gy deploy --debug --ai-key` | ❌ Fail | Feature non-functional | +| Login — Wrong Credentials | `gy login` | ✅ Pass | Returns 400 error; raw schema message exposed | +| Delete Non-Existent Project | `gy delete project` | ✅ Pass | Clear not-found error | +| `gy logs` — Existing App | `gy logs --no-follow` | ✅ Pass | Streams and exits correctly | +| `gy logs` — Non-Existent App | `gy logs ` | ✅ Pass | Clear not-found error | +| `gy logs` — Duplicate Name | `gy logs ` | ❌ Fail | Ambiguous — same bug as delete | +| Deploy Empty Directory | `gy deploy` | ⚠️ Partial | Deploys but produces broken container | +| PEM & secrets.json Inclusion | `gy deploy --debug` | ❌ Fail | Private key + secrets exposed in container | +| Dockerfile `ARG` Secret | `gy deploy --debug` | ✅ Pass (note) | `ARG` not exposed at runtime; no CLI warning | diff --git a/test-projects/arg-secret-test/.gy.json b/test-projects/arg-secret-test/.gy.json new file mode 100644 index 0000000..20aa404 --- /dev/null +++ b/test-projects/arg-secret-test/.gy.json @@ -0,0 +1,13 @@ +{ + "app": "arg-secret-test", + "project": "arg-secret-test", + "_app_id": "9cbe843b-0437-4074-8694-3f73a8e87928", + "_project_id": "43ec4e5c-3b35-45c1-96b5-308005e8897b", + "port": 8080, + "publicAccess": { + "enabled": true, + "domain": "arg-secret-test-2e72f0879187.hosted.ghaymah.systems" + }, + "resourceTier": "t1", + "_detected": "dockerfile" +} \ No newline at end of file diff --git a/test-projects/arg-secret-test/Dockerfile b/test-projects/arg-secret-test/Dockerfile new file mode 100644 index 0000000..4134548 --- /dev/null +++ b/test-projects/arg-secret-test/Dockerfile @@ -0,0 +1,4 @@ +FROM alpine +ARG BUILD_SECRET="FAKE_ARG_SECRET_99999" +RUN echo "Build done" +CMD ["sh", "-c", "echo BUILD_SECRET=${BUILD_SECRET}; sleep 30"] diff --git a/test-projects/empty-deploy-test/.gy.json b/test-projects/empty-deploy-test/.gy.json new file mode 100644 index 0000000..9e779fe --- /dev/null +++ b/test-projects/empty-deploy-test/.gy.json @@ -0,0 +1,13 @@ +{ + "app": "empty-deploy-test", + "project": "empty-deploy-test", + "_app_id": "72d725fe-77bd-42cb-b8c4-51c3f3033643", + "_project_id": "30b9f4e9-ca9f-4fcf-9b1f-50d7eaf00063", + "port": 8080, + "publicAccess": { + "enabled": true, + "domain": "empty-deploy-test-72d66f287027.hosted.ghaymah.systems" + }, + "resourceTier": "t1", + "_detected": "unknown" +} \ No newline at end of file diff --git a/test-projects/empty-deploy-test/Dockerfile b/test-projects/empty-deploy-test/Dockerfile new file mode 100644 index 0000000..dd2ad64 --- /dev/null +++ b/test-projects/empty-deploy-test/Dockerfile @@ -0,0 +1,10 @@ +# ⚡ Auto-generated Generic Dockerfile +# Ghaymah couldn't auto-detect your project type. +# This Dockerfile assumes your project has a start command. +# Edit this file or create your own Dockerfile for better results. + +FROM alpine:3.19 +WORKDIR /app +COPY . . +EXPOSE 80 +CMD ["sh", "-c", "echo 'Ready! Add a CMD to your Dockerfile' && sleep infinity"] diff --git a/test-projects/pem-inclusion-test/.gy.json b/test-projects/pem-inclusion-test/.gy.json new file mode 100644 index 0000000..f912cdf --- /dev/null +++ b/test-projects/pem-inclusion-test/.gy.json @@ -0,0 +1,13 @@ +{ + "app": "pem-inclusion-test", + "project": "pem-inclusion-test", + "_app_id": "428cfb0b-d60d-4dd5-8abf-ab92f314fa27", + "_project_id": "be05dda0-adfc-4dc7-8f5c-eecddba60691", + "port": 8080, + "publicAccess": { + "enabled": true, + "domain": "pem-inclusion-test-253be56f2386.hosted.ghaymah.systems" + }, + "resourceTier": "t1", + "_detected": "dockerfile" +} \ No newline at end of file diff --git a/test-projects/pem-inclusion-test/Dockerfile b/test-projects/pem-inclusion-test/Dockerfile new file mode 100644 index 0000000..e16ffc5 --- /dev/null +++ b/test-projects/pem-inclusion-test/Dockerfile @@ -0,0 +1,4 @@ +FROM alpine +COPY . /app +WORKDIR /app +CMD ["sh", "-c", "echo '=== FILE LIST ==='; ls -la /app; echo '=== PEM CHECK ==='; cat /app/fake_key.pem 2>/dev/null || echo 'no pem'; echo '=== SECRETS CHECK ==='; cat /app/secrets.json 2>/dev/null || echo 'no secrets.json'"] diff --git a/test-projects/pem-inclusion-test/fake_key.pem b/test-projects/pem-inclusion-test/fake_key.pem new file mode 100644 index 0000000..c50df10 --- /dev/null +++ b/test-projects/pem-inclusion-test/fake_key.pem @@ -0,0 +1,3 @@ +-----BEGIN RSA PRIVATE KEY----- +FAKEFAKEFAKEFAKEFAKEFAKE +-----END RSA PRIVATE KEY----- diff --git a/test-projects/pem-inclusion-test/secrets.json b/test-projects/pem-inclusion-test/secrets.json new file mode 100644 index 0000000..078c209 --- /dev/null +++ b/test-projects/pem-inclusion-test/secrets.json @@ -0,0 +1 @@ +FAKE_DB_PASSWORD=supersecret123