우리가 매일 사용하는 웹사이트는 편리하지만, 그 이면에는 수많은 보안 위협이 도사리고 있습니다. 뉴스에서 "OO 사이트 개인정보 유출" 같은 소식을 접할 때마다 불안함을 느끼셨을 텐데요. 사실 이러한 해킹 사고의 상당수는 웹 개발 단계에서 기본적인 보안 수칙만 잘 지켜도 예방할 수 있는 것들입니다.
오늘은 현대 웹 보안에서 가장 악명이 높은 두 가지 공격 방식인 XSS(Cross-Site Scripting)와 CSRF(Cross-Site Request Forgery)가 무엇인지, 그리고 이를 어떻게 하면 완벽하게 막아낼 수 있는지 일반인도 이해하기 쉽게 심층적으로 다뤄보겠습니다.
1. XSS: 내 게시글에 몰래 침투한 악성 스크립트
XSS는 공격자가 웹사이트에 악의적인 자바스크립트 코드를 삽입하는 공격입니다. 가장 큰 특징은 공격의 대상이 웹 서버 자체가 아니라, 그 사이트를 이용하는 '사용자(내 브라우저)'라는 점입니다.
공격 시나리오: "누가 내 쿠키를 훔쳤을까?"
어느 평범한 날, 유명한 게시판에 "이 글을 읽으면 선물을 드립니다"라는 제목의 글이 올라왔다고 가정해 봅시다. 당신이 그 글을 클릭하는 순간, 화면에는 아무런 변화가 없지만 백그라운드에서는 공격자가 심어놓은 스크립트가 실행됩니다. 이 스크립트는 당신의 로그인 세션 쿠키를 공격자의 서버로 전송합니다. 이제 공격자는 당신의 비밀번호를 몰라도 당신의 계정으로 로그인할 수 있게 됩니다.
XSS의 주요 유형 세 가지
- Stored XSS (저장형): 악성 코드가 서버의 데이터베이스에 저장되는 방식입니다. 게시판의 글이나 댓글이 대표적이며, 해당 글을 읽는 모든 사용자가 피해자가 됩니다.
- Reflected XSS (반사형): 악성 코드가 URL 파라미터에 포함되어 서버에 전달되었다가 다시 브라우저로 돌아오는 방식입니다. 주로 피싱 메일에 포함된 링크를 통해 발생합니다.
- DOM-based XSS (DOM 기반): 서버를 거치지 않고 브라우저 내에서 자바스크립트가 데이터를 처리할 때 발생하는 취약점입니다.
개발자가 실천해야 할 XSS 방어 수칙
가장 강력한 방어는 "모든 입력값을 믿지 않는 것"입니다. 사용자가 입력한 데이터를 화면에 뿌려줄 때, <script> 태그 등이 실행되지 않도록 안전한 문자로 바꾸어주어야 합니다.
// 안전한 문자열 변환 예시
const rawInput = "<script>alert('hacked')</script>";
const safeOutput = rawInput
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">");
// 이제 브라우저는 이 코드를 실행하지 않고 글자 그대로 보여줍니다.
또한, 최신 기술인 CSP(Content Security Policy)를 설정하면, 우리 사이트가 아닌 낯선 곳에서 오는 스크립트는 실행 자체가 되지 않도록 차단할 수 있습니다.
2. CSRF: 내가 누르지 않은 '송금' 버튼
CSRF는 사용자가 의도하지 않은 요청을 강제로 보내게 만드는 공격입니다. XSS가 사용자의 '정보를 훔치는 것'에 집중한다면, CSRF는 사용자의 '권한을 이용해 사고를 치는 것'에 집중합니다.
공격 시나리오: "클릭 한 번에 비밀번호가 바뀌다"
당신이 은행 웹사이트에 로그인한 채로 탭을 열어두고 다른 사이트를 구경하고 있다고 합시다. 그런데 어떤 배너를 클릭하자마자 보이지 않는 투명한 폼이 제출되면서 은행 서버에 "내 돈 100만 원을 공격자에게 송금해"라는 요청을 보냅니다. 은행 서버는 당신이 로그인한 상태임을 확인하고, 이 요청을 당신이 직접 보낸 것으로 믿고 승인해버립니다.
CSRF를 완벽하게 차단하는 두 가지 열쇠
첫째, CSRF 토큰(Token)을 사용해야 합니다. 사용자가 사이트에 접속할 때마다 서버가 무작위로 생성한 암호표(토큰)를 주고, 요청을 보낼 때 이 암호표가 없으면 "가짜 요청"으로 간주하여 거절하는 방식입니다.
둘째, 쿠키의 SameSite 속성을 활용하는 것입니다. 이 설정을 Lax나 Strict로 해두면, 다른 사이트에서 우리 사이트로 보내는 요청에는 로그인 정보(쿠키)가 자동으로 포함되지 않습니다. 이는 현재 웹 표준에서 가장 권장되는 방식입니다.
중요한 업무(뱅킹, 쇼핑)를 마친 후에는 반드시 '로그아웃'을 하는 습관을 들여야 합니다. 로그아웃을 하면 브라우저에 남은 세션 정보가 사라지기 때문에 CSRF 공격의 위협에서 벗어날 수 있습니다.
3. 결론: 안전한 웹 생태계를 위하여
보안은 어느 한 쪽의 노력만으로 완성되지 않습니다. 개발자는 입력을 검증하고 최신 보안 헤더를 적용해야 하며, 사용자는 의심스러운 링크를 경계하고 보안 습관을 유지해야 합니다. eleslog.work는 이러한 보안 철학을 바탕으로 사용자의 데이터가 안전하게 보호될 수 있도록 최선을 다하고
있습니다.
앞으로도 기술의 발전과 함께 공격 수법은 정교해지겠지만, 기본을 지키는 방어 전략이 있다면 우리는 더 안심하고 웹의 편리함을 누릴 수 있을 것입니다. 다음 포스팅에서는 서버의 근본적인 안전을 지키는 HTTPS 보안 연결에 대해 자세히 알아보겠습니다.