다른 서비스에서 유출된 비밀번호 목록을 그대로 대입해보는 크리덴셜 스터핑 — 비밀번호 하나만 맞으면 로그인되는 구조의 근본적 약점을 재현하고, MFA(2차 인증)가 이를 어떻게 막는지 실제 침투테스트 도구(hydra)로 직접 검증했습니다.
비밀번호 단일 인증만으로 충분하다고 가정하는 로그인 시스템을 만들고 있는 백엔드 개발자용 학습 자료입니다.
비밀번호 일치만으로 로그인을 허용하는 취약한 로그인 API.
// 취약한 로그인 API — 비밀번호가 일치하면 그걸로 끝.
// 다른 서비스에서 유출된 비밀번호 목록을 그대로 대입하는
// 크리덴셜 스터핑 공격에 그대로 뚫림(hydra로 직접 검증).
class PasswordOnlyLogin {
constructor(userDb) {
this.db = userDb; // { username: password }
}
login(username, password) {
if (this.db[username] === password) {
return { status: 'ok' };
}
return { status: 'invalid_credentials' };
}
}
module.exports = { PasswordOnlyLogin };
해결책: 비밀번호가 맞아도 유효한 2차 인증 코드 없이는 로그인을 거부한다.
// 해결책: 비밀번호 + 2차 인증(TOTP류) 둘 다 필요.
// 유출된 비밀번호가 100% 맞아도, 공격자는 실시간으로
// 바뀌는 2차 인증 코드를 모르므로 로그인 불가.
class MfaGuardedLogin {
constructor(userDb, totpProvider) {
this.db = userDb;
this.totp = totpProvider; // .currentCode(username)
}
login(username, password, totpCode) {
if (this.db[username] !== password) {
return { status: 'invalid_credentials' };
}
if (totpCode !== this.totp.currentCode(username)) {
return { status: 'invalid_credentials' }; // 어느쪽이 틀렸는지 알려주지 않음
}
return { status: 'ok' };
}
}
module.exports = { MfaGuardedLogin };
이 상품에 대한 피드백이나 질문이 있으면 알려주세요. 회신을 원하시면 이메일을 남겨주세요(선택).