
폼은 사용자와 서버가 만나는 자리라서 보안과 UX 가 같은 곳에서 결정됩니다. 그리고 '보안을 위해' 라며 넣은 장치가 오히려 보안을 해치는 경우가 많습니다 — 비밀번호 붙여넣기 금지가 대표적입니다. 로그인·결제·설정 변경 폼을 만들 때 지켜야 할 기본을 정리합니다.

1. CSRF — 남의 사이트에서 내 폼을 보내지 못하게

CSRF(교차 사이트 요청 위조)는 로그인된 사용자가 다른 사이트의 페이지를 여는 순간 그 사이트가 몰래 우리 서버로 '비밀번호 변경' 같은 요청을 보내는 공격입니다. 방어는 서버가 발급한 토큰을 폼에 넣고 요청 때 확인하는 것이고, 대부분의 프레임워크가 기본으로 제공합니다. 세션 쿠키에 SameSite=Lax(또는 Strict) 를 두면 브라우저 단에서 한 겹 더 막힙니다. 그리고 상태를 바꾸는 요청은 GET 으로 만들지 않습니다 — GET 은 링크 하나로 실행되니까요.
2. autocomplete 속성 — 비밀번호 관리자를 돕는다
<input type="text" name="id" autocomplete="username">
<input type="password" name="pw" autocomplete="current-password">
<!-- 비밀번호 변경·가입 -->
<input type="password" name="new_pw" autocomplete="new-password">
<!-- 문자 인증 코드 -->
<input type="text" inputmode="numeric" autocomplete="one-time-code">
이 속성이 맞게 붙어 있으면 브라우저와 비밀번호 관리자가 올바른 칸에 올바른 값을 채우고, 새 비밀번호를 생성·저장해 줍니다. 비밀번호 관리자를 쓰는 사용자는 더 길고 고유한 비밀번호를 쓰므로, 이 한 줄이 곧 보안입니다.
3. 비밀번호 입력 UX 가 곧 정책

붙여넣기를 막으면 사용자는 짧고 외우기 쉬운 비밀번호를 쓰게 됩니다. 최대 길이를 16자로 두면 긴 문장형 비밀번호를 못 씁니다. '보기' 토글이 있으면 입력 실수가 줄어 잠금도 줄어듭니다. 로그인 실패 메시지는 아이디 존재 여부를 알려 주지 않는 문구로 통일합니다.
4. 검증은 서버에서 다시
HTML 의 required, pattern, maxlength 는 사용자를 돕는 장치이지 보안 장치가 아닙니다. 개발자 도구로 모두 바꿀 수 있습니다. 같은 검증을 서버에서 반드시 다시 합니다.
5. 속도 제한과 잠금
로그인·비밀번호 찾기·인증 코드 폼은 자동화 공격의 표적입니다. IP·계정 기준으로 횟수를 제한하고, 몇 번 실패하면 짧은 지연이나 추가 확인을 넣습니다. 인증 코드는 시도 횟수를 꼭 제한합니다 — 6자리 숫자는 제한이 없으면 금방 맞춥니다.
좋은 폼은 비밀번호 관리자가 잘 작동하고, 남의 사이트에서 보낼 수 없고, 서버가 다시 확인하는 폼입니다. 화려한 검증 메시지보다 이 셋이 먼저입니다.
댓글