ai-forever / ai-forever/giga_agent

Security audit: hardcoded secrets, auth hardening, permissive config, and vulnerable dependencies

Abierto
#116 1 comentario 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
Python
Estrellas
201
Forks
45
Métricas de merge de PR
Sin PR fusionados en 30 d

Descripción

## Security audit findings

This is a point-in-time security review of the repository covering four areas: hardcoded secrets/credentials, unsafe handling of user input, overly permissive configuration, and dependencies with known vulnerabilities. Findings are ranked by severity. No secret values are reproduced in this report.

Scope note: several items are intentional trade-offs for local/self-hosted single-tenant dev use. They are still flagged because the same code paths ship in the Docker deployment assets and can be exposed if the service is put on a network. Please confirm the intended deployment/threat model.

---

### Critical

**C1. Vulnerable `jupyter-server` (stored XSS + path traversal) bundled in the code-execution image**
- Where: `backend/pyproject.toml` optional `jupyter` / `jupyter-full` extras (`jupyter-server>=2.0.0`), locked at `2.17.0` in `backend/uv.lock`.
- Issue: `2.17.0` is affected by CVE-2026-44727 (stored XSS, critical), CVE-2026-35397 (path traversal), CVE-2026-40110, CVE-2026-40934. This runs inside the sandbox that executes agent/user-supplied code, so the blast radius is significant.
- Remediation: bump to `jupyter-server>=2.20.0` and rebuild the sandbox image.

---

### High

**H1. Known-vulnerable security-critical dependencies (backend)**
- Where: `backend/uv.lock` / `backend/pyproject.toml`.
- Issue (highest-impact, from OSV.dev against locked versions):
- `pyjwt 2.12.1` — CVE-2026-48526 (forged HS256) and related; JWT is the core auth mechanism (`modules/auth/security.py`). Fixed in `2.13.0`.
- `starlette 0.50.0` — CVE-2026-48818 (SSRF) + others; fixed in `1.3.1` (major; coordinate with `fastapi ~=0.127.0`).
- `python-multipart 0.0.26` — CVE-2026-53539 / CVE-2026-42561 (DoS on multipart parsing, reachable via file-upload endpoints). Fixed in `0.0.31`.
- `urllib3 2.6.3` — CVE-2026-44432 / CVE-2026-44431. Fixed in `2.7.0`.
- `cryptography 46.0.7` — GHSA-537c-gmf6-5ccf (bundled OpenSSL). Fixed in `48.0.1`.
- `aiohttp 3.13.5`, `mako 1.3.11`, `mistune 3.2.0`, `msgpack 1.1.2`, `tornado 6.5.5`, `langchain-classic 1.0.4`, `langsmith 0.7.32`, `pydantic-settings 2.13.1`, `idna 3.11`, `nltk 3.9.4` (no fix yet) also flagged.
- Remediation: run `pip-audit` in CI, then upgrade. Prioritize `pyjwt`, `python-multipart`, `starlette`, `urllib3`, `cryptography`.

**H2. Known-vulnerable dependencies (frontend), incl. auth-token leakage in axios**
- Where: `front/package.json` / lockfile. `npm audit` reports 25 vulns (9 high, 15 moderate).
- Issue (high): `axios 1.15.0` (credential/proxy leak, prototype-pollution MITM, ReDoS, SSRF); `@modelcontextprotocol/sdk 1.17.0` (ReDoS, cross-client data leak, DNS-rebind); `vite 8.0.8` (`server.fs.deny` bypass); `react-router(-dom) 7.10.x` (XSS via open redirects, SSR XSS); transitive `form-data`, `path-to-regexp`, `picomatch`, `langsmith` (JS).
- Remediation: 23 of 25 resolve with `npm audit fix`; `react-syntax-highlighter` needs a major bump to `16.1.1` (clears transitive `prismjs`/`refractor` DOM-clobbering).

**H3. JWT access tokens never expire**
- Where: `backend/giga_agent/modules/auth/security.py:9` — `ACCESS_TOKEN_EXPIRE_MINUTES = None` (`# None = tokens never expire`); `create_access_token` omits `exp` when no delta is passed, and login (`modules/auth/api.py`) passes none.
- Issue: a leaked token (logs, browser history, proxy, XSS) is valid forever. There is no expiry and no server-side revocation/rotation, so the only remediation for a leak is rotating `GIGA_AGENT_SECRET_KEY`, which invalidates every user. A `jti` is embedded but not checked against any denylist.
- Remediation: set a finite `exp` (e.g. hours/days), add refresh-token rotation, and/or a `jti` revocation list.

**H4. Default admin credentials, weak default, and plaintext credential logging**
- Where: `backend/giga_agent/conf.py:107-113` (`admin@example.com` / `giga_agent_admin`); `backend/giga_agent/modules/auth/module.py:52` logs `f"Admin user created: {admin_email}:{admin_password}"`.
- Issue: on first boot a superuser is auto-created with well-known, guessable credentials, and the plaintext password is written to application logs. If the instance is reachable before the operator changes it, this is a full account takeover; the log line also persists the secret wherever logs are shipped.
- Remediation: require the admin password to be set explicitly (fail closed / force a random password printed once), never log the password, and force a change-password on first login.

---

### Medium

**M1. Docker socket mounted read-write into the app container (host-root escalation)**
- Where: `docker-compose.yml` — `giga-agent` service mounts `/var/run/docker.sock:/var/run/docker.sock` and sets `DOCKER_HOST=unix:///var/run/docker.sock`.
- Issue: full access to the host Docker daemon is effectively host root. Combined with an RCE in the app (or the agent's code-execution features), this is a container-escape to the host.
- Remediation: if the local-docker sandbox provider is not needed, remove the mount; otherwise use a rootless/proxied Docker socket (e.g. a socket-proxy restricting the API surface) and document the risk.

**M2. TLS certificate verification disabled on outbound calls**
- Where: `backend/giga_agent/connectors/gigachat.py:99,109,121,135`; `backend/giga_agent/embeddings/gigachat.py`; `backend/giga_agent/generators/image/gigachat.py:67` (`httpx.AsyncClient(verify=False)`).
- Issue: `verify_ssl_certs=False` / `verify=False` disables certificate validation, exposing API traffic (including bearer credentials) to MITM. This is a common pattern for GigaChat's Russian root CA, but hardcoding it removes the option to verify.
- Remediation: ship/trust the proper CA bundle and make verification configurable (default on), rather than hardcoding `False`.

**M3. Default database passwords in Docker deployment**
- Where: `docker-compose.yml` — both Postgres services use `POSTGRES_USER=postgres` / `POSTGRES_PASSWORD=postgres`, and connection URLs use `sslmode=disable`.
- Issue: default `postgres:postgres` creds and unencrypted DB connections. Low risk while the DB is confined to the internal compose network, but dangerous if a port is published or the network is shared.
- Remediation: parameterize credentials via env/secrets with no insecure default, and prefer TLS for DB connections in non-loopback deployments.

**M4. Hardcoded dev secret key**
- Where: `backend/start_aegra.py:24` — `os.environ["GIGA_AGENT_SECRET_KEY"] = "secret"`.
- Issue: this dev launcher forces the JWT signing key to the literal `secret`. Any token signed under it is trivially forgeable. It is a dev-only entrypoint, but there is no guard preventing it from being used outside dev.
- Remediation: read from env and fail if unset (as `core/agent/base.py` already does elsewhere); do not hardcode a signing key even in dev helpers.

---

### Low / informational

**L1. `verify_password` timing / no account lockout**
- Where: `backend/giga_agent/modules/auth/api.py` login handler.
- Issue: bcrypt is used correctly, but there is no rate limiting / lockout on the token endpoint, enabling online password brute force (relevant given the weak default admin password in H4).
- Remediation: add rate limiting / exponential backoff on failed logins (a `rate_limits` route already exists to build on).

**L2. Positive: no obvious injection in reviewed code**
- SQL access uses SQLAlchemy with parameterized `text(... :param ...)` bindings (e.g. `models/migrations/...`), no string-formatted SQL found.
- No `eval`/`exec` on user input; the `local_functions` directory picker (`routes/local_functions.py`) uses fixed argv lists (no shell, no user-controlled args).
- Sandbox `subprocess` usage passes argument lists (no `shell=True` with user input observed). Kept here so reviewers know these were checked, not skipped.

---

### Suggested next steps
1. Add `pip-audit` (backend) and `npm audit`/Dependabot (frontend) to CI to catch H1/H2/C1 continuously.
2. Address auth hardening together: token expiry + revocation (H3) and admin bootstrap (H4).
3. Decide the deployment threat model and gate M1/M3/M2 accordingly (loopback-only dev vs. network-exposed).

_Line references are against the audited commit; verify before patching. This report intentionally contains no secret values._

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.