Skip to content

fix(EverCore): require MinIO credentials from environment (CWE-798)#206

Open
sebastiondev wants to merge 1 commit intoEverMind-AI:mainfrom
sebastiondev:fix/cwe798-docker-compose-hardcoded-0857
Open

fix(EverCore): require MinIO credentials from environment (CWE-798)#206
sebastiondev wants to merge 1 commit intoEverMind-AI:mainfrom
sebastiondev:fix/cwe798-docker-compose-hardcoded-0857

Conversation

@sebastiondev
Copy link
Copy Markdown

Summary

methods/EverCore/docker-compose.yaml ships with the literal MinIO vendor defaults (minioadmin / minioadmin) hardcoded as MINIO_ACCESS_KEY / MINIO_SECRET_KEY for the memsys-milvus-minio service. The same compose file publishes the MinIO ports 9000 and 9001 to the host (the default bind is 0.0.0.0). Anyone who follows the EverCore quickstart and runs docker compose up from a fresh clone exposes a MinIO instance on the network with credentials that are publicly known and continuously scanned for by automated bots.

This PR makes the credentials required environment variables so compose refuses to start until the operator sets explicit values.

  • CWE: CWE-798: Use of Hard-coded Credentials
  • File: methods/EverCore/docker-compose.yaml (the memsys-milvus-minio service block)
  • Severity: High — default credentials grant full S3-compatible read/write on the Milvus object store the moment ports 9000/9001 are reachable.

Fix

-      MINIO_ACCESS_KEY: minioadmin
-      MINIO_SECRET_KEY: minioadmin
+      MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:?Set MINIO_ACCESS_KEY in your .env file}
+      MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:?Set MINIO_SECRET_KEY in your .env file}

The ${VAR:?message} form is a Compose/Bash interpolation that aborts startup with a clear error if the variable is unset or empty — failing closed instead of silently inheriting the insecure default.

methods/EverCore/env.template is updated with placeholder entries (change-me-...) and a comment pointing at the compose requirement, so the existing cp env.template .env workflow continues to work — the operator just has to substitute values.

What I tested

  • docker compose -f methods/EverCore/docker-compose.yaml config with no .env: aborts with the Set MINIO_ACCESS_KEY in your .env file message (fail-closed verified).
  • Same command with MINIO_ACCESS_KEY / MINIO_SECRET_KEY set in .env: renders the expected configuration with the operator-supplied values.
  • No other service in the compose file references MINIO_ACCESS_KEY / MINIO_SECRET_KEY (Milvus reads the bucket through its own client config), so this change is self-contained.

Why it's exploitable in practice

The preconditions are minimal:

  1. An operator runs docker compose up against methods/EverCore/docker-compose.yaml without overriding the credentials (the documented quickstart path).
  2. The MinIO ports become reachable to an attacker — typical scenarios include developer laptops on shared LAN/Wi-Fi, cloud VMs where security groups expose the port, Docker bypassing host firewalls (a well-known footgun), or accidental public exposure on a demo box.

When both hold, the attacker uses minioadmin:minioadmin against http://target:9000 and gets full bucket access — read/write/delete of any objects Milvus stores there. Internet-wide scanners actively probe for exactly this credential pair.

Scope note

There is a separate hardcoded-credentials issue with the MongoDB service in the same file. I'm keeping that change in its own PR so each fix can be reviewed and reverted independently.

Adversarial review

Before submitting I tried to disprove this — looked for an existing mitigation that would make the report moot. There isn't one: the compose file has no 127.0.0.1: host binding on the MinIO ports, no override file ships defaults from the environment, and env.template did not previously contain MINIO_* entries, so an operator copying the template would not be prompted to change them. The credentials really are the literal vendor default that bots scan for, and they really are reachable on whatever interface Docker binds to. The fix is the minimal change that converts a silent insecure default into a loud, fail-fast configuration error.

cc @lewiswigmore

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant