민감 정보의 평문 저장

민감 정보의 평문 저장

설명

비밀번호, 토큰, API 키, 세션 식별자 같은 민감 정보를 파일이나 브라우저 저장소에 평문으로 저장하면 디스크, 백업, 로컬 스토리지, 로그성 파일을 통해 비밀 값이 유출될 수 있습니다. 공격자는 유출된 값을 이용해 인증 우회, 세션 탈취, 내부 API 접근을 시도할 수 있습니다.

잠재적 영향

  • 파일 시스템이나 백업에 남은 평문 비밀 값이 유출될 수 있습니다.
  • 브라우저 저장소에 저장된 장기 토큰이 XSS나 로컬 접근으로 탈취될 수 있습니다.
  • 평문 비밀번호 저장은 한 번의 유출로 여러 서비스의 계정 탈취로 이어질 수 있습니다.

해결 방법

  • 비밀번호는 Argon2id, bcrypt, scrypt 같은 비밀번호 전용 해시로 저장하세요.
  • 토큰, API 키, 세션 값은 가능한 저장하지 말고 필요한 경우 서버 측 vault 또는 암호화 저장소를 사용하세요. 키와 데이터의 접근 권한은 분리하세요.
  • 브라우저 localStorage와 sessionStorage에는 장기 인증 토큰을 저장하지 마세요.
  • 쿠키에 민감 값을 넣어야 하면 최소 Secure, HttpOnly, SameSite 속성을 함께 설정하고 값 자체도 최소화하세요. 쿠키 속성은 값 자체를 암호화하지 않습니다.

예시

users는 애플리케이션의 저장 계층이며, 입력 검증과 오류 처리는 생략했습니다. bcrypt의 72바이트 입력 제한과 비용을 확인하고, 로그인 검증에도 동일한 입력 정책을 적용하세요.

변경 전

javascript
const fs = require("fs");

function save(req, res) {
  fs.writeFileSync("/tmp/password.txt", req.body.password);
}

변경 후

javascript
const bcrypt = require("bcrypt");

async function save(req, res) {
  const passwordHash = await bcrypt.hash(req.body.password, 12);
  await users.save({ passwordHash });
}

설명:

  • 변경 전: 비밀번호를 평문 파일에 써서 디스크나 백업 유출 시 그대로 재사용될 수 있게 합니다.
  • 변경 후: 비밀번호를 전용 해시로 변환하고 원문을 저장하지 않습니다.

서명된 JWT도 내용이 암호화되는 것은 아닙니다. 쿠키의 전송·스크립트 접근 보호와 저장할 데이터의 민감성을 각각 확인하세요.

참조