Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
da8542a
docs: add security audit
Scetrov Feb 14, 2026
9cd8e56
SEC-04: Remove INTERNAL_SECRET default value
Scetrov Feb 14, 2026
11d1ac9
SEC-01: Add OAuth2 state parameter for CSRF protection
Scetrov Feb 14, 2026
c698cb3
SEC-03: Externalize Murmur ICE secrets and remove weak defaults
Scetrov Feb 14, 2026
a7ee560
SEC-02: Remove JWT from URL redirect
Scetrov Feb 14, 2026
cd39eed
SEC-06: Run containers as non-root user
Scetrov Feb 14, 2026
c692a82
SEC-07: Sanitize database error responses
Scetrov Feb 14, 2026
25ec865
SEC-09: Add Content-Security-Policy and security headers
Scetrov Feb 14, 2026
9c67121
SEC-08: Add TTL validation to wallet nonces
Scetrov Feb 14, 2026
fd0b9d7
SEC-10: Add input length validation
Scetrov Feb 14, 2026
7d85b86
SEC-11: Configure Dependabot for automated dependency and action updates
Scetrov Feb 14, 2026
4805787
SEC-12: Remove is_super_admin from JWT claims and re-validate in get_me
Scetrov Feb 14, 2026
34a4e3c
SEC-05: Add rate limiting to authentication endpoints
Scetrov Feb 14, 2026
cb69a3c
fix: Remove empty environment stanzas from docker-compose.yml
Scetrov Feb 14, 2026
44c8687
docs: Add Docker Compose deployment guide
Scetrov Feb 14, 2026
c6d08e3
fix: Point docker-compose to workspace root .env file
Scetrov Feb 14, 2026
3e3269f
fix: Gracefully handle missing git in frontend vite.config
Scetrov Feb 14, 2026
ae8ed8b
fix: Use SmartIpKeyExtractor for rate limiting in Docker
Scetrov Feb 14, 2026
0d947b0
docs: Add comprehensive security audit remediation report
Scetrov Feb 14, 2026
9597282
docs: Update environment variable documentation for security audit re…
Scetrov Feb 14, 2026
2ae3a5c
fix: tidy up remediation doc
Scetrov Feb 14, 2026
9a94aed
fix: Murmur authenticator ICE secret and rate limiter Docker compatib…
Scetrov Feb 14, 2026
a346d05
fix: Increase auth code TTL and use API_URL config in callback
Scetrov Feb 14, 2026
4e86184
feat: Add /ping endpoint to replace /docs for health checks
Scetrov Feb 14, 2026
cc9da50
docs: fix inconsistencies in security documentation
Scetrov Feb 15, 2026
cad3533
fix(backend): prevent unbounded memory growth in auth token storage
Scetrov Feb 15, 2026
d40cbcd
fix(murmur): make ICE secret configuration idempotent
Scetrov Feb 15, 2026
ab7f522
fix(e2e): update test fixtures for authorization code exchange flow
Scetrov Feb 15, 2026
50533f6
fix: Address PR #20 review comments - CSP and grammar consistency
Scetrov Feb 15, 2026
47bc4e4
fix: tidy up env
Scetrov Feb 15, 2026
997abfe
fix: finish clean up
Scetrov Feb 15, 2026
36d31c8
fix: prevent React Strict Mode double auth exchange & sed delimiter i…
Scetrov Feb 15, 2026
15c4aa0
fix: address PR #20 review comments
Scetrov Feb 15, 2026
165737d
docs: formatting
Scetrov Feb 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,20 @@ SUPER_ADMIN_AUDIT_WEBHOOK=
# Defaults to "Fire" if not set
MUMBLE_REQUIRED_TRIBE=Fire

# Shared Secrets for Internal Service Communication
# These must match between Backend and Murmur (if running)
INTERNAL_SECRET=change_me_to_random_string
ICE_SECRET=change_me_to_random_string
# =============================================================================
# REQUIRED Security Secrets
# =============================================================================
# Generate strong random secrets using: openssl rand -base64 32
# The application will FAIL TO START if these are not set.

# REQUIRED: Shared secret for Backend-to-Murmur authenticator API calls
# Must match the INTERNAL_SECRET in the Murmur authenticator
INTERNAL_SECRET=

# REQUIRED (if running Mumble): ICE secrets for Murmur server communication
# Must match the values in Murmur configuration
ICE_SECRET_READ=
ICE_SECRET_WRITE=

# Frontend Configuration (if running frontend locally with this .env)
# URL of the backend API
Expand Down
40 changes: 34 additions & 6 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,44 @@
version: 2
updates:
- package-ecosystem: "cargo"
directory: "/src/rust"
# GitHub Actions - automatically update and SHA-pin per SEC-11
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 10
commit-message:
prefix: "ci"
include: "scope"
labels:
- "dependencies"
- "github-actions"
- "security"

- package-ecosystem: "npm"
directory: "/src/sui"
# Backend Rust dependencies
- package-ecosystem: "cargo"
directory: "/src/backend"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 10
commit-message:
prefix: "deps(backend)"
include: "scope"
labels:
- "dependencies"
- "rust"

- package-ecosystem: "github-actions"
directory: "/"
# Frontend npm dependencies (Bun)
- package-ecosystem: "npm"
directory: "/src/frontend"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 10
commit-message:
prefix: "deps(frontend)"
include: "scope"
labels:
- "dependencies"
- "javascript"
60 changes: 60 additions & 0 deletions .github/prompts/security-audit.prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
description: Security Audit Prompt: VoID Electronic Identity (eID)
---

**Role:** You are a Senior Security Researcher and DevSecOps Engineer specializing in Rust (Axum/SQLx), React, and Docker security.

**Objective:** Conduct a deep-dive security audit of the VoID eID project. Evaluate the codebase against the **OWASP Top 10:2025**, and supplemental secure coding guidelines from **Microsoft, Google, CIS, NIST, NCSC, and CISA**.

**Scope of Analysis:**

1. **Backend (Rust):** Authentication logic, JWT handling, SQLx queries, CORS configuration, and internal API secrets.
2. **Frontend (React/Vite):** Environment variable usage, routing guards, and wallet connection security.
3. **Infrastructure:** `docker-compose.yml`, GitHub Actions CI/CD workflows, and Murmur/Mumble authenticator scripts.

**Instructions:**

1. Identify specific violations with **file paths** and **line numbers**.
2. Provide a description of the vulnerability and its potential impact.
3. Map each finding to the **MITRE ATT&CK Framework**.
4. Provide actionable **remediation guidance** for developers.
5. Summarize findings in the **Standardized Security Audit Report** format provided below.

---

### Audit Criteria & High-Priority Checks

- **OWASP A01:2025 – Broken Access Control:** Check `src/backend/src/auth.rs` and `roster.rs`. Ensure `AuthenticatedUser` extractor properly validates sessions and that admin-only routes (like `grant_admin`) verify the `is_admin` flag in the database, not just the token.
- **OWASP A02:2025 – Cryptographic Failures:** Evaluate the JWT implementation in `auth.rs`. Check for hardcoded secrets, weak signing algorithms, or lack of expiration validation. Inspect Sui wallet signature verification in `wallet.rs`.
- **OWASP A03:2025 – Injection:** Verify that all SQLx queries use parameterized inputs and not string interpolation (check `01_init.sql` through `04_unique_wallets_address.sql` and `db.rs`).
- **OWASP A05:2025 – Security Misconfiguration:** Review `docker-compose.yml` for insecure defaults (e.g., SQLite file permissions, exposed ports). Check `main.rs` for overly permissive CORS policies.
- **OWASP A07:2025 – Identification and Authentication Failures:** Analyze the Discord OAuth2 flow in `auth.rs`. Check for "State" parameter usage to prevent CSRF in OAuth.
- **Supply Chain Security:** Review `.github/workflows/ci.yml` for insecure action versions or lack of integrity checks.

---

### Standardized Security Audit Report Format

#### 1. Executive Summary

- Overall Risk Rating (Critical/High/Medium/Low)
- Summary of top 3 critical risks.

#### 2. Detailed Findings

| ID | Vulnerability Name | Severity | Location (File:Line) | OWASP 2025 Mapping | MITRE ATT&CK ID |
| ------ | --------------------- | -------- | -------------------------- | ------------------ | --------------- |
| SEC-01 | [e.g., SQL Injection] | Critical | `src/backend/src/db.rs:45` | A03:2025 | T1190 |

**Description:** [Detailed explanation of the vulnerability]
**Impact:** [What an attacker can achieve]
**Guidance/Fix:** [Code snippet or configuration change to resolve the issue]

#### 3. Infrastructure & CI/CD Review

- **Docker Security:** Analysis of `Dockerfile` and `docker-compose.yml`.
- **CI/CD Pipeline:** Analysis of `ci.yml` (e.g., secrets handling, binary signing).

#### 4. Compliance Check

- Adherence to **NIST SP 800-53** (Access Control) or **CIS Benchmarks** (Docker/Linux).
22 changes: 21 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
{
"chat.tools.terminal.autoApprove": {
"bun": true
}
},
"cSpell.words": [
"appuser",
"backdoors",
"changeme",
"chrono",
"CISA",
"clickjacking",
"Dockerfiles",
"eprintln",
"HEALTHCHECK",
"HSTS",
"icesecretread",
"icesecretwrite",
"jlumbroso",
"nosniff",
"Referer",
"sigstore",
"trixie",
"urlencoding"
]
}
21 changes: 0 additions & 21 deletions deploy/compose/.env.sample

This file was deleted.

128 changes: 128 additions & 0 deletions deploy/compose/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Void eID Docker Compose Deployment

## Quick Start

This deployment uses the workspace root `.env` file.

1. **Ensure `.env` is configured** in the workspace root (two levels up from this directory)
- The `.env` file should already exist with your configuration
- If not, copy from `.env.example` in the workspace root

2. **Start the services:**
```bash
docker compose up -d
```

## Environment Configuration

This compose file references `../../.env` (the workspace root `.env` file).

### Required Discord OAuth Configuration

Register an application at https://discord.com/developers/applications

- **`DISCORD_CLIENT_ID`**: Your Discord Application's Client ID
- Found in: OAuth2 → General → Client ID

- **`DISCORD_CLIENT_SECRET`**: Your Discord Application's Client Secret
- Found in: OAuth2 → General → Client Secret
- Click "Reset Secret" if needed

- **OAuth2 Redirect URL**: Add this to your Discord app:
- `http://localhost:5038/api/auth/discord/callback`
- Found in: OAuth2 → Redirects

### Required Admin Configuration

- **`INITIAL_ADMIN_ID`**: Your Discord User ID
- Enable Developer Mode in Discord (Settings → Advanced → Developer Mode)
- Right-click your username → Copy User ID

### Required Secrets (Generate Random Values)

Generate secure random strings for these values using `openssl rand -base64 32`:

- **`JWT_SECRET`**: Secret for signing JWT tokens

```bash
openssl rand -base64 32
```

- **`IDENTITY_HASH_PEPPER`**: Secret pepper for hashing denylisted identifiers

```bash
openssl rand -base64 32
```

- **`INTERNAL_SECRET`**: **REQUIRED** - Shared secret for backend-to-Murmur authenticator API calls

```bash
openssl rand -base64 32
```

⚠️ The application will **fail to start** if this is not set.

- **`ICE_SECRET_READ`**: **REQUIRED for Mumble** - ICE read secret for Murmur server

```bash
openssl rand -base64 32
```

- **`ICE_SECRET_WRITE`**: **REQUIRED for Mumble** - ICE write secret for Murmur server
```bash
openssl rand -base64 32
```

### Optional Configuration

- **`SUPER_ADMIN_DISCORD_IDS`**: Comma-separated Discord IDs for super admins
- Example: `123456789,987654321`
- Leave empty if only using `INITIAL_ADMIN_ID`

- **`SUPER_ADMIN_AUDIT_WEBHOOK`**: Discord webhook URL for super admin audit logs
- Leave empty to disable

- **`MUMBLE_REQUIRED_TRIBE`**: Tribe required for Mumble account creation
- Default: `Fire`

## Pre-configured Values (No Changes Needed)

The following are already set correctly in `.env.example` (repository root):

- `DISCORD_REDIRECT_URI=http://localhost:5038/api/auth/discord/callback`
- `FRONTEND_URL=http://localhost:5173`
- `DATABASE_URL=sqlite:///data/void-eid.db?mode=rwc`
- `BACKEND_URL=http://backend:5038/api/internal/mumble`
- `VITE_API_URL=http://localhost:5038`
- `PORT=5038`

## Starting the Services

```bash
docker compose up -d
```

## Checking Logs

```bash
# All services
docker compose logs -f

# Specific service
docker compose logs -f backend
docker compose logs -f frontend
docker compose logs -f murmur
```

## Stopping the Services

```bash
docker compose down
```

## Security Notes

- **Never commit `.env` to version control** (it's in `.gitignore`)
- Generate unique secrets for each deployment
- Use strong random values for all secret keys
- Restrict `SUPER_ADMIN_DISCORD_IDS` to trusted users only
10 changes: 4 additions & 6 deletions deploy/compose/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ services:
image: ghcr.io/scetrov/void-eid/void-eid-backend:latest
ports:
- "5038:5038"
env_file: .env
env_file: ../../.env
environment:
- PORT=5038
volumes:
Expand All @@ -17,8 +17,7 @@ services:
ports:
- "64738:64738/tcp"
- "64738:64738/udp"
env_file: .env
environment:
env_file: ../../.env
volumes:
- murmur-data:/data
restart: unless-stopped
Expand All @@ -31,9 +30,8 @@ services:
frontend:
image: ghcr.io/scetrov/void-eid/void-eid-frontend:latest
ports:
- "5173:80"
env_file: .env
environment:
- "5173:8080"
env_file: ../../.env
restart: unless-stopped
networks:
- shared_net
Expand Down
2 changes: 1 addition & 1 deletion deploy/quadlet/void-frontend.container
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ After=void-network.service void-backend.service
ContainerName=frontend
Image=ghcr.io/scetrov/void-eid/void-eid-frontend:main
Pull=newer
PublishPort=5173:80
PublishPort=5173:8080
AutoUpdate=registry
Network=void.network
GroupAdd=keep-groups
Expand Down
23 changes: 18 additions & 5 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

![VoID eID Logo](../src/frontend/public/logo.png)


A modern web application integrating Discord authentication with Sui blockchain wallet verification, featuring a Rust backend and a React frontend.

## Overview
Expand Down Expand Up @@ -35,14 +34,28 @@ Void eID provides a seamless way to link Discord identities with Sui Wallets. It
### Backend Setup

1. Navigate to `src/backend`.
2. Copy `.env.example` to `.env` (create one if missing) and populate:
2. Copy `.env.example` to `.env` and populate **required** variables:

```env
DATABASE_URL=sqlite:void-eid.db
DISCORD_CLIENT_ID=your_id
DISCORD_CLIENT_SECRET=your_secret
JWT_SECRET=your_jwt_secret
DISCORD_CLIENT_ID=your_discord_client_id
DISCORD_CLIENT_SECRET=your_discord_client_secret
DISCORD_REDIRECT_URI=http://localhost:5038/api/auth/discord/callback
JWT_SECRET=your_jwt_secret_minimum_32_characters
IDENTITY_HASH_PEPPER=your_random_pepper_string
INTERNAL_SECRET=your_random_internal_secret
PORT=5038
```

**Generate secrets** using: `openssl rand -base64 32`

If running **Mumble**, also set:

```env
ICE_SECRET_READ=your_ice_read_secret
ICE_SECRET_WRITE=your_ice_write_secret
```

3. Run the backend:
```bash
cargo run
Expand Down
Loading
Loading