Repository navigation
bug: remove hard-coded default [REDACTED SECRET] credential, hash passwords (sfind-1a5ebd13) - #1100
devin-ai-integration[bot] wants to merge 6 commits into
Conversation
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Signed-off-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…hash tests Existing deployments still hold the previously published admin password in plaintext. Unset any User password that is not an scrypt hash before seeding the admin from ADMIN_PASSWORD. Refs: sfind-1a5ebd13023045bdaab4dabc8cfa0342
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
…ykCode SARIF Refs: sfind-1a5ebd13023045bdaab4dabc8cfa0342
…ine numbers Refs: sfind-1a5ebd13023045bdaab4dabc8cfa0342
| if (err) return next(err); | ||
| if (!user) return res.status(401).send(); | ||
|
|
||
| passwordHash.verifyPassword(req.body.password, user.password, function (err, verified) { |
There was a problem hiding this comment.
🟨 Password guesses exhaust scrypt workers
Repeated requests for an existing username make verifyPassword run scrypt on every guessed password. Without login rate limiting, unauthenticated clients can saturate crypto workers and delay legitimate requests.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Valid concern, but I'm leaving it out of this PR on purpose. This PR fixes the hard-coded [REDACTED SECRET] credential (sfind-1a5ebd13).
/loginhad no rate limiting or lockout before this change either. Unlimited guessing was already possible; it was just cheaper per request.crypto.scryptis async and runs on the libuv threadpool, so it doesn't block the event loop. Heavy traffic can still fill the 4 default workers, which is the amplification you describe.- The right fix is per-IP/per-account throttling, ideally at the proxy or with
express-rate-limit. That's a new dependency and a policy decision (limits, lockout, storage across instances), so it should be its own change rather than part of a credential fix.
I'm leaving this thread open so the maintainers can decide whether to track login throttling as a follow-up.
…snyk.io Changing ADMIN_USERNAME created a second admin and left the old one able to log in (Devin Review). Keep a single fixed admin account. Refs: sfind-1a5ebd13023045bdaab4dabc8cfa0342
|
Teste no navegador (app real com um banco MongoDB em memória, porque o Mongoose 4.2.4 não conecta ao MongoDB 7):
O harness e2e foi executado de novo no ae6f190 (remoção de |
Resumo
Corrige o finding sfind-1a5ebd13 (alta): ao subir, o
mongoose-db.jscriava[REDACTED SECRET]@snyk.iocom a senha publicada no repositório (SuperSecretPassword) e a gravava em texto puro. Com isso, quem tivesse lido o repo conseguia fazer login como [REDACTED SECRET] viaPOST /loginem qualquer deploy que manteve o padrão.O que muda:
ADMIN_PASSWORDestá definido (usuário fixo[REDACTED SECRET]@snyk.io; não há maisADMIN_USERNAME, para evitar que um [REDACTED SECRET] antigo continue ativo após renomear). Se a variável não existir, nenhum [REDACTED SECRET] é criado. O valor deADMIN_PASSWORDprevalece: se ele mudar, a senha é rotacionada na próxima inicialização.crypto.scryptnativo, salt aleatório de 16 bytes) empassword-hash.js, aplicado por um hookpre('save')emUser.routes/index.js):User.findOne({ username })+verifyPassword(timingSafeEqual). A senha deixou de entrar na query e precisa ser string. Isso também fecha o login por{"$gt": ""}.SuperSecretPassword(e qualquer outra em texto puro) que deploys antigos já gravaram. Essas senhas não serviriam mais para login de qualquer forma.sarif.json(SARIF estático enviado pelo workflowsnyk code manual test): removido o resultadojavascript/Sqlido login, que foi corrigido, e os demais resultados deroutes/index.jsforam re-ancorados nas novas linhas (+1/+5). Sem isso, o check SnykCode abre alertas novos.docker-compose.yml/app.jsonrepassamADMIN_PASSWORD. O README eexploits/nosql-exploits.shagora usam$ADMIN_PASSWORD.Mudança de comportamento / contrato: o login de [REDACTED SECRET] com a senha publicada deixa de funcionar. Para ter [REDACTED SECRET] é preciso subir com
ADMIN_PASSWORD=.... Os passos do README que demonstram a NoSQL injection no login foram atualizados, porque ela foi corrigida junto.Duplicata: os 2 primeiros commits são cherry-pick da branch
devin/1793687194-hash-[REDACTED SECRET]-password(e há outras branches/PRs antigos com a mesma ideia, como o #629 para sfind-3edb37df). Só um deve ser mergeado. Este PR acrescenta a limpeza das senhas em texto puro já gravadas e testes tap.Como testar
O Mongoose 4.2.4 não conversa com o mongod 7 local (OP_QUERY removido) e a imagem
mongo:3não está disponível. Por isso oapp.jsreal roda com um shim em memória que respeita$gt/$exists/$not/$unsete executa os hooks de save do schema.e2e.sh <checkout> <label> <porta> [ADMIN_PASSWORD]fazPOST /logincom a credencial publicada:SuperSecretPasswordADMIN_PASSWORD{"$gt":""}UserfinalADMIN_PASSWORDscrypt$...ADMIN_PASSWORDscrypt$...$exists/$not: /^scrypt\$/também foi verificado contra um mongod 7.0 real (driver 3.5.9): apaga só a senha em texto puro e mantém o hash e o usuário sem senha.node_modules/.bin/tap tests/password-hash.test.js: 2/2 (salt aleatório, verify ok/erro, rejeita valor em texto puro gravado e senha que não é string).Devin-Org: engineering
Link to Devin session: https://devin-gtm.devinenterprise.com/sessions/86bbea1031d64698a0a32d268e61bd99
Open in Devin Desktop: https://devin-gtm.devinenterprise.com/desktop/session/86bbea1031d64698a0a32d268e61bd99?variant=devin
Devin Review