diff --git a/PROJEKT_ANALYSE.md b/PROJEKT_ANALYSE.md new file mode 100644 index 0000000..b22c565 --- /dev/null +++ b/PROJEKT_ANALYSE.md @@ -0,0 +1,486 @@ +# Security Assessment Report + +| Field | Value | +|-------|-------| +| **Report ID** | ZYROX-SEC-2026-001 | +| **Target** | ZyroX CV2 AIO Discord Bot with Dashboard | +| **Repository** | `ZyroX-CV2-AIO-With-Dashboard-main` | +| **Assessment Date** | 2026-07-21 | +| **Report Version** | 1.0 | +| **Classification** | Internal — Distribution Restricted | +| **Assessment Type** | Static source-code review, configuration analysis, threat modeling | +| **Assessor** | Independent security review (automated + manual verification) | + +--- + +## Document Control + +| Version | Date | Author | Changes | +|---------|------|--------|---------| +| 1.0 | 2026-07-21 | Security Review | Initial assessment | + +**Scope:** Full repository including `bot/` (Python/discord.py), `bot/api/` (FastAPI), and `dashboard/` (Next.js). Out of scope: runtime penetration testing, infrastructure review, third-party Lavalink/OpenAI endpoints. + +**Methodology:** +1. Recursive static analysis of source tree (~200+ Python/TypeScript files) +2. Configuration default and `.env.example` review +3. Identification of trust boundaries (Discord ↔ Bot ↔ API ↔ Dashboard ↔ Internet) +4. Mapping findings to [CWE](https://cwe.mitre.org/) where applicable +5. Severity assignment per internal scale (Critical → Informational) + +**Limitations:** This assessment reflects the codebase state at review time. No dynamic exploitation was performed against a live deployment. Residual risk may exist in unreviewed dependencies. + +--- + +## 1. Executive Summary + +A security review of the ZyroX CV2 AIO Discord bot (originally published by CodeX Devs) was conducted to determine whether the repository contains malicious code and to identify exploitable misconfigurations. + +### 1.1 Malware Classification + +| Indicator | Result | +|-----------|--------| +| Known malware signatures (trojan, RAT, cryptominer, token stealer) | Not observed | +| Obfuscated or packed payloads | Not observed | +| Committed binary artifacts (`.exe`, `.dll`, `.sh`) | None | +| Covert C2 / unknown outbound endpoints | Not observed | +| Intentional third-party control primitives | **Confirmed** (see Findings) | + +**Verdict:** The codebase does **not** exhibit characteristics of traditional malware. However, **default configuration and hardcoded identifiers create effective pre-positioned access** for third parties if an operator deploys without modification. This pattern is classified as **latent supply-chain / configuration backdoor risk**, not as a self-propagating trojan. + +### 1.2 Risk Overview + +| Severity | Count | Representative Issues | +|----------|-------|---------------------| +| Critical | 3 | Hardcoded owner fallback, Jishaku RCE, command telemetry webhook | +| High | 3 | Hardcoded log channels, exposed API surface, client-side API key | +| Medium | 3 | `eval()` usage, runtime package/binary fetch, deceptive commands | +| Low | 1 | Developer branding / optional telemetry hooks | +| **Total** | **10** | | + +**Operational impact if deployed with defaults:** A third-party Discord account retains bot owner privileges; command metadata and guild join events may be exfiltrated to external Discord channels/webhooks; owner-level Jishaku access enables host-level code execution. + +--- + +## 2. System Overview & Attack Surface + +### 2.1 Architecture + +``` + ┌─────────────────────────────────────┐ + │ Trust Boundary │ + Discord Users ───►│ discord.py Gateway (bot/CodeX.py) │ + │ │ │ │ + │ ▼ ▼ │ + │ SQLite (bot/db/) FastAPI :8000 │ + │ │ │ + Web Users ───────►│ Next.js Dashboard :3000 ◄┘ │ + │ │ │ + │ ▼ (optional) │ + │ Cloudflare Tunnel → Internet │ + └─────────────────────────────────────┘ +``` + +### 2.2 Trust Boundaries + +| Boundary | Authentication | Authorization Gap (pre-remediation) | +|----------|----------------|-------------------------------------| +| Discord → Bot | Discord token, owner ID list | Owner list defaulted to third party | +| Bot → External webhooks/channels | None (hardcoded destinations) | Unauthenticated telemetry sink | +| Dashboard → Bot API | Bearer `DASHBOARD_API_KEY` | No Discord permission binding | +| Browser → Dashboard API | OAuth session (partial) | API key embedded in client bundle | +| Internet → FastAPI | API key only when tunnel enabled | Binds `0.0.0.0` by default | + +### 2.3 Expanded Attack Surface + +Beyond a typical Discord bot, this project includes: + +| Component | Path | Notes | +|-----------|------|-------| +| Web dashboard | `dashboard/` | OAuth, guild configuration UI | +| REST API | `bot/api/` | Full guild config CRUD | +| Cloudflare tunnel | `bot/utils/tunnel.py` | Optional public exposure | +| Lavalink integration | `bot/cogs/commands/music.py` | External dependency | +| AI modules | `bot/cogs/commands/ai.py` | External API calls | +| Embedded games/utilities | `bot/games/`, various cogs | Expanded code surface | + +These components are **in scope for the product design** but increase exposure relative to a minimal bot. + +--- + +## 3. Detailed Findings + +Findings are indexed as `ZYROX-2026-NNN`. Severity uses: **Critical**, **High**, **Medium**, **Low**, **Informational**. + +--- + +### ZYROX-2026-001 — Hardcoded Owner ID Fallback + +| Attribute | Value | +|-----------|-------| +| **Severity** | Critical | +| **CWE** | [CWE-1188](https://cwe.mitre.org/data/definitions/1188.html) — Insecure Default Initialization of Resource | +| **CVSS 3.1 (est.)** | 9.1 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H) | +| **Status at review** | Open → Remediated in `SECURITY_FIXES.md` (#1) | + +**Affected component:** `bot/utils/config.py` + +**Description:** When `OWNER_IDS` is absent from environment configuration, the bot falls back to a hardcoded Discord snowflake belonging to the original maintainer. + +```python +OWNER_IDS: list[int] = _parse_ids("OWNER_IDS", [870179991462236170]) +``` + +**Impact:** Unconfigured deployments grant **full bot owner privileges** to UID `870179991462236170`, including process restart (`reload`), cross-guild moderation, global blacklist, invite generation, and access to Jishaku (Finding 002). + +**Evidence:** `bot/utils/config.py`; additional third-party IDs present in `bot/.env.example`. + +**Owner-capable commands (non-exhaustive):** `reload`, `leaveguild`, `makeinvite`, `GB`, `global kick`, `global timeout`, `blacklist user/guild`. + +**Remediation:** +- Remove hardcoded fallback; fail closed or warn when `OWNER_IDS` is empty +- Replace example IDs with placeholders +- Operator must set `OWNER_IDS=` + +--- + +### ZYROX-2026-002 — Jishaku Extension Enabled by Default + +| Attribute | Value | +|-----------|-------| +| **Severity** | Critical | +| **CWE** | [CWE-78](https://cwe.mitre.org/data/definitions/78.html) / [CWE-94](https://cwe.mitre.org/data/definitions/94.html) | +| **CVSS 3.1 (est.)** | 9.8 (AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H) | +| **Status at review** | Open → Remediated (#2) | + +**Affected component:** `bot/CodeX.py` (~L345) + +```python +await client.load_extension("jishaku") +``` + +**Description:** [Jishaku](https://github.com/Gorialis/jishaku) provides an in-Discord Python REPL restricted to bot owners. Any principal in `OWNER_IDS` can execute arbitrary Python on the host process. + +**Impact:** Full host compromise under owner account compromise or misconfigured `OWNER_IDS` (chained with Finding 001). + +**Remediation:** Load Jishaku only when `JISHAKU_ENABLED=true`; default `false`. Never enable in production. + +--- + +### ZYROX-2026-003 — Command Telemetry via Discord Webhook + +| Attribute | Value | +|-----------|-------| +| **Severity** | Critical | +| **CWE** | [CWE-359](https://cwe.mitre.org/data/definitions/359.html) — Exposure of Private Personal Information | +| **CVSS 3.1 (est.)** | 7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N) | +| **Status at review** | Open → Remediated (#3) | + +**Affected component:** `bot/CodeX.py` → `on_command_completion` + +**Description:** Non-owner command invocations are POSTed to `CMD_WEBHOOK_URL` with command text, user ID, guild name/ID, and channel ID. Owner commands are explicitly excluded from logging. + +**Impact:** Webhook controller receives **cross-guild activity intelligence**. Privacy violation; potential GDPR relevance depending on jurisdiction. + +**Remediation:** Disable by default; validate URL before enabling; use operator-controlled webhook only. + +--- + +### ZYROX-2026-004 — Hardcoded Discord Channel IDs for Telemetry + +| Attribute | Value | +|-----------|-------| +| **Severity** | High | +| **CWE** | [CWE-798](https://cwe.mitre.org/data/definitions/798.html) — Use of Hard-coded Credentials (analogous) | +| **Status at review** | Open → Remediated (#4) | + +**Affected components:** + +| File | Channel ID | Function | +|------|------------|----------| +| `bot/CodeX.py` | `1396794297386532978` | Guild join notifications | +| `bot/CodeX.py` | `1419729255977189467` | Server count display | +| `bot/CodeX.py` | `1419729283861184632` | Member count display | +| `bot/cogs/events/on_guild.py` | `1396794297386532978` | Join/leave detail logs | +| `bot/cogs/commands/np.py` | `1396794297386532978` | No-prefix command audit | + +**Impact:** Guild metadata (name, owner, member count, invite links) transmitted to channels controlled by the original developer. + +**Remediation:** Externalize to `LOG_CHANNEL_ID`, `SERVER_COUNT_CHANNEL_ID`, `USER_COUNT_CHANNEL_ID`; no logging when unset. + +--- + +### ZYROX-2026-005 — Over-Exposed FastAPI with Optional Public Tunnel + +| Attribute | Value | +|-----------|-------| +| **Severity** | High | +| **CWE** | [CWE-284](https://cwe.mitre.org/data/definitions/284.html) — Improper Access Control | +| **Status at review** | Open → Partially remediated (#5, #10) | + +**Affected components:** `bot/api/server.py`, `bot/utils/tunnel.py`, `bot/CodeX.py` + +**Description:** API listens on `0.0.0.0:8000` by default. Cloudflare tunnel can expose localhost to the public internet. Authentication is a single shared bearer token without per-guild Discord authorization (pre-fix). + +**Sensitive endpoints (sample):** +- `PATCH /api/v1/guilds/{id}/automod` +- `PATCH /api/v1/guilds/{id}/antinuke` +- `PATCH /api/v1/guilds/{id}/verification` +- `PATCH /api/v1/admin/config` + +**Impact:** API key compromise → full configuration manipulation across all guilds. + +**Remediation:** Default `API_ENABLED=false`, `API_HOST=127.0.0.1`, `TUNNEL_ENABLED=false`; bind Discord OAuth token + guild admin checks (Fix #10). + +--- + +### ZYROX-2026-006 — API Key Embedded in Client Bundle + +| Attribute | Value | +|-----------|-------| +| **Severity** | High | +| **CWE** | [CWE-522](https://cwe.mitre.org/data/definitions/522.html) — Insufficiently Protected Credentials | +| **Status at review** | Open → Remediated (#6) | + +**Affected component:** `dashboard/lib/api.ts` + +```typescript +const API_KEY = process.env.NEXT_PUBLIC_DASHBOARD_API_KEY; +``` + +**Description:** Next.js inlines `NEXT_PUBLIC_*` variables into client JavaScript. Any dashboard visitor can extract the bearer token. + +**Impact:** Unauthenticated API access if combined with reachable bot API (Finding 005). + +**Remediation:** Server-side proxy route; `DASHBOARD_API_KEY` server-only; remove `NEXT_PUBLIC_DASHBOARD_API_KEY`. + +--- + +### ZYROX-2026-007 — Unsafe Dynamic Code Evaluation (`eval`) + +| Attribute | Value | +|-----------|-------| +| **Severity** | Medium | +| **CWE** | [CWE-95](https://cwe.mitre.org/data/definitions/95.html) — Improper Neutralization of Directives in Eval | +| **Status at review** | Open → Remediated (#7) | + +**Affected components:** + +| File | Line(s) | Context | +|------|---------|---------| +| `bot/cogs/commands/calc.py` | 92 | User-supplied expression | +| `bot/cogs/commands/autorole.py` | 235, 268, 306, 339 | DB-persisted list parsing | + +**Impact:** Local RCE if an attacker can write SQLite records or abuse calculator input validation gaps. + +**Remediation:** AST-limited math evaluator; JSON/`ast.literal_eval` for structured data. + +--- + +### ZYROX-2026-008 — Runtime Dependency Installation & Binary Fetch + +| Attribute | Value | +|-----------|-------| +| **Severity** | Medium | +| **CWE** | [CWE-829](https://cwe.mitre.org/data/definitions/829.html) — Inclusion of Functionality from Untrusted Control Sphere | +| **Status at review** | Open → Remediated (#8) | + +**Affected components:** `bot/utils/tunnel.py`, `bot/utils/paginators.py` + +**Description:** Application invokes `pip install` via `os.system` and downloads `cloudflared` from GitHub at runtime. + +**Impact:** Supply-chain compromise if upstream artifact is tampered; violates principle of immutable deployments. + +**Remediation:** Declare dependencies in `requirements.txt`; opt-in binary download via `TUNNEL_ALLOW_BINARY_DOWNLOAD=true`. + +--- + +### ZYROX-2026-009 — Deceptive User-Facing Commands + +| Attribute | Value | +|-----------|-------| +| **Severity** | Medium (Social Engineering) | +| **CWE** | [CWE-451](https://cwe.mitre.org/data/definitions/451.html) — User Interface (UI) Misrepresentation of Critical Information | +| **Status at review** | Open → Remediated (#9) | + +**Affected component:** `bot/cogs/commands/general.py` + +| Command | Behavior | Actual harm | +|---------|----------|-------------| +| `hack @user` | Fabricated credentials | None | +| `token @user` | Random 59-char string | None | +| `wizz` | Simulated destruction UI | None | + +**Impact:** No technical exploitation; reputational and social-engineering risk. + +**Remediation:** Remove or clearly label as parody commands. + +--- + +### ZYROX-2026-010 — Developer Branding & Dormant Telemetry Hooks + +| Attribute | Value | +|-----------|-------| +| **Severity** | Low / Informational | +| **Status at review** | Acknowledged — no code change required | + +**Description:** >100 files contain CodeX branding headers (`discord.gg/codexdev`). Commented `autoblacklist` cog references external support channel. Help footers link to developer Discord. + +**Impact:** No direct exploitation path; increases fingerprinting and social-trust surface. + +--- + +## 4. Finding Summary Matrix + +| ID | Title | Severity | Exploitability | Data Impact | Remediation Priority | +|----|-------|----------|----------------|-------------|---------------------| +| ZYROX-2026-001 | Hardcoded owner fallback | Critical | Trivial (default deploy) | Full bot control | P0 | +| ZYROX-2026-002 | Jishaku RCE | Critical | Requires owner access | Host compromise | P0 | +| ZYROX-2026-003 | Command webhook telemetry | Critical | Passive (default URL) | User/guild metadata | P0 | +| ZYROX-2026-004 | Hardcoded log channels | High | Passive | Guild intelligence | P1 | +| ZYROX-2026-005 | Exposed FastAPI + tunnel | High | Requires key/network | Config takeover | P1 | +| ZYROX-2026-006 | Client-exposed API key | High | Trivial (view source) | Config takeover | P1 | +| ZYROX-2026-007 | eval() injection | Medium | Conditional | Local RCE | P2 | +| ZYROX-2026-008 | Runtime pip/binary fetch | Medium | Supply-chain | Integrity | P2 | +| ZYROX-2026-009 | Deceptive commands | Medium | Social | None (technical) | P2 | +| ZYROX-2026-010 | Branding / telemetry hooks | Low | N/A | N/A | P3 | + +--- + +## 5. Pre-Deployment Checklist (Operator) + +### P0 — Before first production start + +- [ ] Set `OWNER_IDS` to operator-controlled Discord account(s) +- [ ] Verify no third-party IDs in `.env` or `.env.example` +- [ ] Confirm `JISHAKU_ENABLED` is unset or `false` +- [ ] Leave `CMD_WEBHOOK_URL` empty unless operator-owned +- [ ] Replace or unset all hardcoded log channel IDs + +### P1 — Before exposing dashboard/API + +- [ ] Generate cryptographically strong `DASHBOARD_API_KEY` (≥32 bytes entropy) +- [ ] Set `API_HOST=127.0.0.1`; enable tunnel only if required +- [ ] Confirm API key is **not** prefixed with `NEXT_PUBLIC_` +- [ ] Validate Discord OAuth permission checks on guild routes + +### P2 — Hardening + +- [ ] Audit SQLite file permissions on `bot/db/` +- [ ] Review `eval()` replacements in calculator/autorole modules +- [ ] Pin dependencies; disable runtime installs +- [ ] Remove or relabel parody moderation commands + +--- + +## Appendix A — Repository Structure + +### A.1 Root + +| Path | Description | +|------|-------------| +| `bot/` | Python Discord bot, FastAPI, SQLite persistence | +| `dashboard/` | Next.js 14+ dashboard with NextAuth | +| `PROJEKT_ANALYSE.md` | This report | +| `SECURITY_FIXES.md` | Remediation advisory | + +### A.2 Bot Core (`bot/`) + +| Component | Role | +|-----------|------| +| `CodeX.py` | Process entry: bot, API thread, optional tunnel | +| `core/zyrox.py` | `AutoShardedBot` subclass, prefix resolution | +| `utils/config.py` | Centralized environment configuration | +| `api/` | FastAPI REST layer for dashboard | +| `cogs/` | Feature modules (~80+ extensions) | +| `db/` | Per-module SQLite databases | + +### A.3 Bot API Routes (`bot/api/`) + +| Route group | Capability | +|-------------|------------| +| `/api/v1/guilds/*` | Guild-scoped configuration CRUD | +| `/api/v1/admin/*` | Global stats, maintenance mode | +| `/api/v1/bot/*` | Bot status | + +**Authentication (post-remediation):** Bearer `DASHBOARD_API_KEY` + `X-Discord-Access-Token` with guild permission validation. + +### A.4 Dashboard (`dashboard/`) + +OAuth via NextAuth → guild list intersection (bot present ∧ user has Manage Guild) → proxied API calls to bot backend. + +Key paths: `app/dashboard/guild/[guildId]/*`, `app/api/proxy/[...path]/route.ts`, `lib/api.ts`. + +--- + +## Appendix B — Persistence Layer + +| Database | Contents | +|----------|----------| +| `prefix.db` | Per-guild command prefixes | +| `automod.db` | Automod rule configuration | +| `block.db` | Global user/guild denylist | +| `leveling.db` | XP and rank data | +| `tickets.db`, `welcome.db`, `antinuke.db`, `verification.db` | Module configs | +| `admin_config.db` | Maintenance mode flag | + +All databases are local SQLite files under `bot/db/`. No encryption at rest observed. + +--- + +## Appendix C — Environment Variables + +### Bot (`.env`) + +| Variable | Required | Security note | +|----------|----------|---------------| +| `TOKEN` | Yes | Discord bot secret — never commit | +| `OWNER_IDS` | Yes | Must be operator-controlled | +| `DASHBOARD_API_KEY` | If API enabled | Shared secret; rotate on compromise | +| `CMD_WEBHOOK_URL` | No | Disable unless operator-owned | +| `API_ENABLED` / `API_HOST` / `TUNNEL_ENABLED` | No | Secure defaults: off / 127.0.0.1 / off | +| `JISHAKU_ENABLED` | No | Default: false | + +### Dashboard (`.env`) + +| Variable | Required | Security note | +|----------|----------|---------------| +| `DISCORD_CLIENT_SECRET` | Yes | Server-side only | +| `DASHBOARD_API_KEY` | Yes | Server-side only — **not** `NEXT_PUBLIC_*` | +| `NEXTAUTH_SECRET` | Yes | Session integrity | + +--- + +## Appendix D — Startup Sequence + +``` +python bot/CodeX.py + ├─ load_dotenv() + ├─ FastAPI thread (if API_ENABLED) + ├─ Cloudflare tunnel (if TUNNEL_ENABLED) + ├─ discord.py client.start(TOKEN) + │ ├─ load cogs (~80+) + │ ├─ load jishaku (if JISHAKU_ENABLED) + │ └─ sync slash commands + └─ on_ready → background tasks + +npm run dev (dashboard/) + ├─ Next.js :3000 + └─ /api/proxy/* → Bot FastAPI (server-side key) +``` + +--- + +## 6. Conclusion + +ZyroX CV2 AIO is a feature-rich Discord bot platform, not a self-propagating malware sample. The primary security concern is **deployment-time trust delegation**: unchanged defaults effectively assign operational control and observability to the original publisher. + +Operators treating this as production software must treat initial configuration as a **security-critical step**, equivalent to key ceremony for any SaaS deployment. + +Remediation details and verification results are documented in **`SECURITY_FIXES.md`** (Advisory ZYROX-SEC-2026-REM). + +--- + +**End of Report** + +*For remediation status and patch verification, see `SECURITY_FIXES.md`.* diff --git a/PR_DESCRIPTION.md b/PR_DESCRIPTION.md new file mode 100644 index 0000000..334af37 --- /dev/null +++ b/PR_DESCRIPTION.md @@ -0,0 +1,80 @@ +# Security: Remove backdoors, enforce secure defaults, and harden API + +## Summary + +Security audit and hardening of the ZyroX CV2 AIO Discord bot with dashboard. The analysis found **no classic malware**, but several **backdoor-like mechanisms** in the original CodeX configuration (foreign owner IDs, external logging, exposed API, API key leak in the frontend). + +This PR addresses **10 security issues** and introduces **secure defaults**: without a proper `.env` configuration, no foreign user retains owner rights, no external logging occurs, and the API is not publicly exposed. + +### Fixed Risks + +| # | Issue | Fix | +|---|-------|-----| +| 1 | Hardcoded foreign `OWNER_IDS` | No fallback — without `.env`, no one has owner rights | +| 2 | Jishaku (Python REPL) always enabled | Opt-in only via `JISHAKU_ENABLED=true` | +| 3 | Command logging to external webhooks | Only with a valid, complete `CMD_WEBHOOK_URL` | +| 4 | Hardcoded Discord channel IDs | Configurable via `LOG_CHANNEL_ID`, etc. | +| 5 | API bound to `0.0.0.0`, tunnel enabled by default | `API_ENABLED=false`, `API_HOST=127.0.0.1`, `TUNNEL_ENABLED=false` | +| 6 | API key exposed in browser (`NEXT_PUBLIC_*`) | Server-side proxy in Next.js, key stays server-only | +| 7 | `eval()` in calculator/autorole | New `safe_parse.py` with AST-based eval and JSON | +| 8 | Auto `pip install` / binary download | Manual installation, download opt-in only | +| 9 | Fake commands `hack`/`token`/`wizz` | Removed | +| 10 | Bot API without Discord permission checks | `discord_auth.py` + token/admin validation | + +### Additional Hardening (Follow-up Audit) + +- API proxy requires login + guild/admin permission checks +- Guild list filtered to manageable servers only +- Fixed crash when `command is None` in `on_command_completion` +- Server-only `ADMIN_IDS` support added + +--- + +## Breaking Changes / Migration + +**Bot (`bot/.env`):** + +```env +TOKEN=... +OWNER_IDS=YOUR_DISCORD_USER_ID +DASHBOARD_API_KEY=strong_secret +``` + +**Dashboard (`dashboard/.env`):** + +```env +DASHBOARD_API_URL=http://127.0.0.1:8000/api/v1 +DASHBOARD_API_KEY=same_value_as_bot +``` + +Remove `NEXT_PUBLIC_DASHBOARD_API_KEY` if still set. + +Optional for dashboard/API: + +```env +API_ENABLED=true +LOG_CHANNEL_ID=... +``` + +--- + +## Test Plan + +- [ ] Bot starts without `OWNER_IDS` and shows a warning; owner commands do not work +- [ ] With `OWNER_IDS` set, owner commands work as expected +- [ ] Jishaku loads only when `JISHAKU_ENABLED=true` +- [ ] No webhook logging without a valid `CMD_WEBHOOK_URL` +- [ ] No join/leave logging without `LOG_CHANNEL_ID` +- [ ] API disabled by default; when enabled, binds to `127.0.0.1` only +- [ ] Dashboard API calls go through `/api/proxy` — key not visible in browser +- [ ] Unauthenticated proxy access is rejected +- [ ] Guild API requires Discord token + Manage Server/Admin on target guild +- [ ] Calculator: safe expressions work, injection attempts rejected +- [ ] `hack`/`token`/`wizz` commands no longer exist +- [ ] README and `.env.example` (bot + dashboard) updated + +--- + +## Context + +Based on the full security analysis in `PROJEKT_ANALYSE.md` and the applied fixes documented in `SECURITY_FIXES.md`. diff --git a/SECURITY_FIXES.md b/SECURITY_FIXES.md new file mode 100644 index 0000000..d1ae530 --- /dev/null +++ b/SECURITY_FIXES.md @@ -0,0 +1,307 @@ +# Security Remediation Advisory + +| Field | Value | +|-------|-------| +| **Advisory ID** | ZYROX-SEC-2026-REM | +| **Related Report** | [PROJEKT_ANALYSE.md](PROJEKT_ANALYSE.md) (ZYROX-SEC-2026-001) | +| **Publication Date** | 2026-07-21 | +| **Status** | Patches applied — operator action required | +| **Classification** | Internal — Distribution Restricted | +| **Affected Product** | ZyroX CV2 AIO Discord Bot with Dashboard | + +--- + +## 1. Advisory Summary + +This document tracks remediation of findings identified during static security assessment **ZYROX-SEC-2026-001**. Ten primary findings (ZYROX-2026-001 through ZYROX-2026-010) were addressed through configuration hardening, access-control improvements, and code changes. A follow-up review on the same date identified six additional issues in the remediation itself; all were resolved prior to closing this advisory. + +**Operator action is still required** post-update: environment files must be created or migrated per Section 6. + +--- + +## 2. Remediation Index + +| Fix | Finding ID | Title | Severity | Status | +|-----|------------|-------|----------|--------| +| #1 | ZYROX-2026-001 | Hardcoded owner fallback | Critical | ✅ Applied | +| #2 | ZYROX-2026-002 | Jishaku enabled by default | Critical | ✅ Applied | +| #3 | ZYROX-2026-003 | Command webhook telemetry | Critical | ✅ Applied | +| #4 | ZYROX-2026-004 | Hardcoded log channel IDs | High | ✅ Applied | +| #5 | ZYROX-2026-005 | Over-exposed API defaults | High | ✅ Applied | +| #6 | ZYROX-2026-006 | Client-exposed API key | High | ✅ Applied | +| #7 | ZYROX-2026-007 | Unsafe eval() usage | Medium | ✅ Applied | +| #8 | ZYROX-2026-008 | Runtime pip/binary fetch | Medium | ✅ Applied | +| #9 | ZYROX-2026-009 | Deceptive commands | Medium | ✅ Applied | +| #10 | ZYROX-2026-005 (ext.) | Missing Discord auth on API | High | ✅ Applied | + +--- + +## 3. Patch Details + +### Fix #1 — Remove Hardcoded Owner Fallback + +**Finding:** ZYROX-2026-001 +**Root cause:** `_parse_ids()` supplied third-party Discord UID `870179991462236170` when `OWNER_IDS` unset. + +| File | Change | +|------|--------| +| `bot/utils/config.py` | `_parse_ids()` returns empty list on missing env var | +| `bot/CodeX.py` | Startup warning when `OWNER_IDS` is empty | +| `bot/.env.example` | Placeholder `YOUR_DISCORD_USER_ID_HERE`; foreign IDs removed | +| `dashboard/.env.example` | `ADMIN_IDS` placeholder replaces foreign ID | + +**Post-patch behavior:** No principal receives owner privileges without explicit configuration. Bot emits warning on empty `OWNER_IDS`. + +**Migration:** +```env +OWNER_IDS= +``` + +--- + +### Fix #2 — Jishaku Opt-In + +**Finding:** ZYROX-2026-002 +**Root cause:** Unconditional `load_extension("jishaku")` at startup. + +| File | Change | +|------|--------| +| `bot/utils/config.py` | `JISHAKU_ENABLED` flag (default: `false`) | +| `bot/CodeX.py` | Conditional extension load | +| `bot/.env.example` | Documented opt-in flag | + +**Post-patch behavior:** Jishaku inactive unless `JISHAKU_ENABLED=true`. Recommended for local debugging only. + +--- + +### Fix #3 — Webhook URL Validation + +**Finding:** ZYROX-2026-003 +**Root cause:** Command logging fired on placeholder or empty webhook URLs. + +| File | Change | +|------|--------| +| `bot/utils/config.py` | `_valid_webhook_url()` rejects empty/placeholder values | +| `bot/CodeX.py` | `on_command_completion` early-return when URL invalid | + +**Post-patch behavior:** No outbound command telemetry without fully qualified, operator-configured webhook URL. + +--- + +### Fix #4 — Externalize Log Channel IDs + +**Finding:** ZYROX-2026-004 +**Root cause:** Hardcoded snowflakes (`1396794297386532978`, etc.) in multiple modules. + +| File | Change | +|------|--------| +| `bot/utils/config.py` | `LOG_CHANNEL_ID`, `SERVER_COUNT_CHANNEL_ID`, `USER_COUNT_CHANNEL_ID` | +| `bot/CodeX.py` | Config-driven channel references; stats task gated on config | +| `bot/cogs/events/on_guild.py` | Join/leave logging conditional on `LOG_CHANNEL_ID` | +| `bot/cogs/commands/np.py` | Audit logs use `LOG_CHANNEL_ID` | +| `bot/.env.example` | Optional IDs documented (commented) | + +**Post-patch behavior:** Zero external telemetry channels unless explicitly configured. + +**Migration (optional):** +```env +LOG_CHANNEL_ID= +SERVER_COUNT_CHANNEL_ID= +USER_COUNT_CHANNEL_ID= +``` + +--- + +### Fix #5 — Secure API Defaults + +**Finding:** ZYROX-2026-005 +**Root cause:** API enabled on `0.0.0.0`; tunnel enabled by default. + +| File | Change | +|------|--------| +| `bot/utils/config.py` | `API_ENABLED=false`, `API_HOST=127.0.0.1`, `TUNNEL_ENABLED=false` | +| `bot/CodeX.py` | Bind to `API_HOST`; warn on `0.0.0.0` | +| `bot/.env.example` | Secure defaults documented | + +**Post-patch behavior:** API and tunnel disabled until explicitly enabled. Localhost binding by default. + +**Migration (dashboard use case):** +```env +API_ENABLED=true +API_HOST=127.0.0.1 +DASHBOARD_API_KEY= +``` + +--- + +### Fix #6 — Server-Side API Proxy + +**Finding:** ZYROX-2026-006 +**Root cause:** `NEXT_PUBLIC_DASHBOARD_API_KEY` inlined into browser bundle. + +| File | Change | +|------|--------| +| `dashboard/app/api/proxy/[...path]/route.ts` | **New** — authenticated server-side proxy | +| `dashboard/lib/api.ts` | Client → `/api/proxy`; SSR → direct with server env | +| `dashboard/.env.example` | `DASHBOARD_API_KEY` (server-only); public key removed | + +**Post-patch architecture:** +``` +Browser → GET /api/proxy/guilds/... → Next.js (session) → Bot API + Bearer token +SSR → Bot API direct (process.env.DASHBOARD_API_KEY) +``` + +**Migration:** +```env +DASHBOARD_API_URL=http://127.0.0.1:8000/api/v1 +DASHBOARD_API_KEY= +``` +Remove `NEXT_PUBLIC_DASHBOARD_API_KEY` from any existing `.env`. + +--- + +### Fix #7 — Replace eval() with Safe Parsers + +**Finding:** ZYROX-2026-007 +**Root cause:** Dynamic evaluation of user input and DB-stored strings. + +| File | Change | +|------|--------| +| `bot/utils/safe_parse.py` | **New** — `safe_math_eval()`, `parse_role_id_list()`, `dump_role_id_list()` | +| `bot/cogs/commands/calc.py` | AST-limited arithmetic evaluator | +| `bot/cogs/commands/autorole.py` | JSON / `ast.literal_eval` for list deserialization | + +**Post-patch behavior:** Calculator restricted to `[0-9+\-*/(). ]`. Autorole lists persisted as JSON with legacy read support. + +**Verification:** Unit tests confirm `safe_math_eval('2+2')` succeeds; injection payloads rejected. + +--- + +### Fix #8 — Disable Runtime Package Installation + +**Finding:** ZYROX-2026-008 +**Root cause:** `os.system("pip install ...")` and unsolicited `cloudflared` download. + +| File | Change | +|------|--------| +| `bot/utils/paginators.py` | ImportError with install instructions (no auto-pip) | +| `bot/utils/tunnel.py` | Binary download gated on `TUNNEL_ALLOW_BINARY_DOWNLOAD=true` | +| `bot/.env.example` | `TUNNEL_ALLOW_BINARY_DOWNLOAD=false` | + +**Post-patch behavior:** Dependencies declared in `requirements.txt`; runtime installs removed. + +--- + +### Fix #9 — Remove Deceptive Commands + +**Finding:** ZYROX-2026-009 +**Root cause:** Commands simulating credential theft and server destruction. + +| File | Change | +|------|--------| +| `bot/cogs/commands/general.py` | Removed `hack`, `token`, `wizz`; dead code cleanup | +| `bot/cogs/zyrox/general.py` | Help index updated | + +**Post-patch behavior:** Commands no longer registered. No regression in remaining general commands. + +--- + +### Fix #10 — Discord Permission Enforcement on Bot API + +**Finding:** Extension of ZYROX-2026-005 (identified in follow-up review) +**Root cause:** API accepted bearer token alone; no guild-scoped authorization. + +| File | Change | +|------|--------| +| `bot/api/discord_auth.py` | **New** — token validation, Manage Guild / Admin checks | +| `bot/api/server.py` | Middleware on `/api/v1/guilds`, `/api/v1/admin`, `/api/v1/bot` | +| `bot/api/routes/guilds.py` | `GET /guilds` filtered to authorized guilds | +| `dashboard/lib/api.ts` | Forwards `X-Discord-Access-Token` on SSR | +| `dashboard/app/api/proxy/[...path]/route.ts` | Header passthrough + session enforcement | +| `bot/.env.example` | `DASHBOARD_ADMIN_IDS` documented | +| `README.md`, `bot/README.md`, `dashboard/README.md` | Secure configuration guidance | + +**Post-patch behavior:** Guild-scoped endpoints require valid Discord OAuth token with Manage Guild or Administrator permission on target guild. + +--- + +## 4. Follow-Up Review (2026-07-21) + +Secondary pass on remediation code identified gaps in the initial proxy implementation. All items below were patched same-day. + +| Issue | Severity | Resolution | +|-------|----------|------------| +| API proxy accessible without session | Critical | Session gate + guild/admin validation in proxy route | +| Guild dashboard pages lacking authZ check | High | `guild/[guildId]/layout.tsx` enforces Discord permissions | +| `GET /guilds` returned all bot guilds | High | Proxy filters to user-manageable intersection | +| `on_command_completion` NullPointer on `command is None` | Medium | Guard clause in `CodeX.py` | +| Orphaned `jishaku` import in `bot/core/zyrox.py` | Low | Import removed | +| Admin check relied solely on `NEXT_PUBLIC_ADMIN_IDS` | Medium | Server-side `ADMIN_IDS` supported | + +--- + +## 5. Verification & Test Results + +| Test | Method | Result | +|------|--------|--------| +| Python syntax | `py_compile` on modified modules | Pass | +| Safe parser unit tests | `safe_parse` test suite | Pass — arithmetic OK, injection blocked | +| Hardcoded channel ID grep | Static scan of `bot/` | Pass — no hardcoded snowflakes in code paths | +| Public API key exposure | Grep `NEXT_PUBLIC_DASHBOARD_API_KEY` | Pass — removed from code and examples | +| Proxy auth bypass (manual) | Unauthenticated request to `/api/proxy/*` | Pass — 401/403 | + +**Regression scope:** General commands, guild config API, dashboard OAuth flow. No automated E2E suite present at time of review. + +--- + +## 6. Operator Deployment Checklist + +Execute after pulling patched codebase: + +| Step | Action | Required | +|------|--------|----------| +| 1 | Create/update `bot/.env` with `TOKEN`, `OWNER_IDS` | Yes | +| 2 | Create/update `dashboard/.env` with server-only `DASHBOARD_API_KEY` | Yes | +| 3 | Delete `NEXT_PUBLIC_DASHBOARD_API_KEY` from legacy configs | Yes | +| 4 | Set `LOG_CHANNEL_ID` etc. if logging desired | Optional | +| 5 | Enable `API_ENABLED=true` only when dashboard is deployed | Optional | +| 6 | Set `JISHAKU_ENABLED=true` only for controlled debugging | Optional | + +--- + +## 7. Intentionally Unchanged (Accepted Risk) + +| Item | Rationale | Risk Level | +|------|-----------|------------| +| Developer credits in `mention.py`, `stats.py` | Cosmetic attribution | Informational | +| CodeX file headers | Branding | Informational | +| `discord.gg/codexdev` in welcome templates | Operator-configurable content | Informational | + +These items do not constitute exploitable vulnerabilities under the assessed threat model. + +--- + +## 8. Residual Recommendations + +| Area | Recommendation | Priority | +|------|----------------|----------| +| SQLite at rest | Restrict filesystem permissions on `bot/db/` | P2 | +| Secret rotation | Rotate `DASHBOARD_API_KEY` and `TOKEN` on suspected compromise | P1 | +| Dependency pinning | Lock `requirements.txt` / `package-lock.json` hashes | P2 | +| AutoBlacklist cog | Review before enabling — aggressive auto-ban behavior | P3 | +| Lavalink | Self-host node; avoid third-party defaults (`lavalink.jirayu.net`) | P3 | + +--- + +## 9. Document History + +| Version | Date | Notes | +|---------|------|-------| +| 1.0 | 2026-07-21 | Initial remediation (Fixes #1–#9) | +| 1.1 | 2026-07-21 | Follow-up review + Fix #10 (Discord API authZ) | + +--- + +**End of Advisory** + +*Cross-reference: vulnerability details and threat context in [PROJEKT_ANALYSE.md](PROJEKT_ANALYSE.md).*