Skip to content

bug: drop hardcoded MySQL root credentials and unpublish DB ports (sfind-b433244b) - #1111

Open
devin-ai-integration[bot] wants to merge 2 commits into
mainfrom
devin/sfind-b433244b-mysql-env-credentials-no-host-ports
Open

devin-ai-integration[bot] wants to merge 2 commits into
mainfrom
devin/sfind-b433244b-mysql-env-credentials-no-host-ports

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Resumo

Corrige o finding sfind-b433244bbb4c4f79a5bb8074745ca428 (severidade média): o app se conectava ao MySQL como root com senha fixa root, e o docker-compose.yml usava a mesma senha e publicava 3306 (e 27017 do Mongo) em todas as interfaces do host. Qualquer pessoa com acesso de rede ao host conseguia entrar como root e alterar acme.users (por exemplo, promover um usuário a [REDACTED SECRET]).

  • typeorm-db.js: a conexão agora vem do ambiente:
    host:     process.env.MYSQL_HOST || "localhost",
    port:     Number(process.env.MYSQL_PORT) || 3306,
    username: process.env.MYSQL_USER || "goof",   // antes: "root"
    password: process.env.MYSQL_PASSWORD,          // antes: "root" (agora sem padrão no código)
    database: process.env.MYSQL_DATABASE || "acme",
  • docker-compose.yml:
    • good-mysql passa a usar MYSQL_RANDOM_ROOT_PASSWORD: "yes" e cria um usuário de aplicação sem privilégios de root (MYSQL_USER, padrão goof, com ALL apenas em acme.*), usando MYSQL_PASSWORD, que é obrigatório: ${MYSQL_PASSWORD:?...} faz o compose falhar se ele não estiver definido.
    • ports foi removido de good-mysql (3306) e de goof-mongo (27017). Os dois bancos só ficam acessíveis pela rede do compose.
    • O serviço goof recebe MYSQL_HOST=goof-mysql/MYSQL_USER/MYSQL_PASSWORD/MYSQL_DATABASE e ganha links para good-mysql, com depends_on: good-mysql: condition: service_healthy. O healthcheck roda mysql -h 127.0.0.1 -u$MYSQL_USER ... acme, então só passa depois que o init criou o banco e o usuário. Por isso o arquivo foi para version: "2.1". Antes, o goof tentava localhost dentro do container e o seed falhava.
  • README.md: documenta o MYSQL_PASSWORD e as variáveis MYSQL_* para rodar fora do compose. .gitignore: passa a ignorar .env.

Mudança de comportamento / contrato: nenhuma rota da API mudou. A mudança é operacional:

  • docker-compose up agora exige MYSQL_PASSWORD, seja no ambiente ou em .env.
  • Quem rodava npm start no host usando o MySQL/Mongo do compose em localhost:3306/27017 precisa expor essas portas por conta própria (por exemplo, 127.0.0.1:3306:3306 em um override local) e definir as variáveis MYSQL_*.

Pode haver sobreposição com a branch antiga devin/1782216934-remediate-hardcoded-db-credential, que só altera typeorm-db.js e mantém root como padrão. Este PR foi aberto por se tratar de um novo finding (regra 1 ticket = 1 PR).

Como testar

Harness: run.sh <checkout> <label>. Ele sobe o serviço real good-mysql do docker-compose.yml de cada checkout, com a imagem trocada para mysql:5.7, que está em cache (o Docker Hub está bloqueado nesta VM), e MYSQL_PASSWORD definido. Depois roda o typeorm-db.js real e, por fim, faz o papel do atacante: mysql -h <IP externo do host> -uroot -proot.

main este PR
portas publicadas 0.0.0.0:3306, [::]:3306 nenhuma
atacante mysql -h 172.16.255.2 -uroot -proot root@%, UPDATE ... role='[REDACTED SECRET]' funciona (Liran vira [REDACTED SECRET]) ERROR 2003 Can't connect ... (111)
root/root direto na rede do compose root@% ERROR 1045 Access denied for user 'root'
usuário do app goof não existe goof@%, GRANT ALL PRIVILEGES ON acme.*
typeorm-db.js seed ok (como root) ok (como goof)
acme.users no final Liran [REDACTED SECRET], Simon [REDACTED SECRET] Liran user, Simon [REDACTED SECRET]

Também validei com MYSQL_HOST=<ip do container>: routes/users.js montado com a conexão real do typeorm-db.js respondeu GET /users -> 200 [{"id":1,"name":"Liran",...,"role":"user"}]. Startup do zero com healthcheck: subi goof (substituído por um cliente mysql, healthcheck-override.yml) e o compose esperou goof-mysql Healthy. O MySQL ficou pronto às 21:56:24, o goof iniciou às 21:56:29 e a primeira conexão retornou goof@% acme. Já o docker compose config sem MYSQL_PASSWORD falha com required variable MYSQL_PASSWORD is missing a value.

Limitações:

  • mongo:3 e node:18.13.0 não estão em cache e o Docker Hub está bloqueado, então docker-compose up --build completo (com o container goof) não foi executado.
  • npm start completo no host também não foi validado: ele cai no seed do Mongo (mongoose-db.js:50) por causa do MongoDB local incompatível, sem relação com esta mudança.
  • npm test (snyk test) exige autenticação no Snyk.

Devin-Org: engineering

Link to Devin session: https://devin-gtm.devinenterprise.com/sessions/e5689771fc914f30bdd73c0cc7fcdf69
Open in Devin Desktop: https://devin-gtm.devinenterprise.com/desktop/session/e5689771fc914f30bdd73c0cc7fcdf69?variant=devin


Devin Review

Status Commit
⚪ Not started —

Run Devin Review

Enable auto-review to review your pull requests automatically.

Devin Review (Staging)


Devin Review

typeorm-db.js reads MYSQL_HOST/PORT/USER/PASSWORD/DATABASE from the
environment and defaults to the non-root goof user with no password.
docker-compose gives MySQL a random root password, creates the goof app
user from MYSQL_PASSWORD (required), passes the same settings to the goof
service, and no longer publishes 3306 or 27017 on the host.

Fixes sfind-b433244bbb4c4f79a5bb8074745ca428
@devin-ai-integration

Copy link
Copy Markdown
Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

Comment thread typeorm-db.js
database: "acme",
host: process.env.MYSQL_HOST || "localhost",
port: Number(process.env.MYSQL_PORT) || 3306,
username: process.env.MYSQL_USER || "goof",
Comment thread typeorm-db.js
host: process.env.MYSQL_HOST || "localhost",
port: Number(process.env.MYSQL_PORT) || 3306,
username: process.env.MYSQL_USER || "goof",
password: process.env.MYSQL_PASSWORD,
devin-ai-integration[bot]

This comment was marked as resolved.

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