icon
13장 : 웹 보안과 성능 최적화

웹 보안 기초 (HTTPS, XSS, CSRF)


우리는 지금까지 웹 개발의 전반적인 과정을 학습했습니다. HTML, CSS, JavaScript로 프론트엔드 UI를 구축하고, React와 같은 프레임워크로 복잡한 SPA를 효율적으로 관리했습니다. 또한 Node.js와 Express.js를 사용하여 백엔드 서버를 만들고, RESTful API를 통해 클라이언트와 서버가 통신하며, 데이터베이스에 데이터를 영구적으로 저장하고 관리하는 방법까지 익혔습니다.

이제 여러분은 기본적인 웹 애플리케이션을 개발할 수 있는 역량을 갖추게 되었습니다. 하지만 실제 서비스를 운영할 때는 단순히 기능 구현뿐만 아니라, 보안(Security)성능(Performance Optimization) 이라는 두 가지 중요한 요소를 반드시 고려해야 합니다.

사용자의 개인 정보가 유출되거나, 서비스가 해킹당해 데이터가 손상되거나, 비정상적인 접근으로 서비스가 마비된다면, 아무리 좋은 기능과 디자인을 가진 애플리케이션이라도 사용자들의 신뢰를 잃고 큰 피해를 입을 수 있습니다. 마찬가지로, 아무리 기능이 많아도 느리고 버벅이는 웹 서비스는 사용자에게 외면받기 쉽습니다.

13장 "웹 보안과 성능 최적화"에서는 이러한 중요한 요소들을 심층적으로 다룰 것입니다. 그 첫 번째 장으로, 웹 애플리케이션을 개발하고 운영할 때 반드시 알아야 할 웹 보안의 기초 개념과, 개발자가 흔히 마주치는 주요 웹 공격 유형 및 이에 대한 방어 전략에 대해 상세히 알아보겠습니다.

웹 보안은 웹 애플리케이션과 사용자의 데이터를 악의적인 공격으로부터 보호하는 일련의 행위와 기술을 의미합니다. 웹은 개방된 인터넷 환경에서 동작하므로 항상 다양한 위협에 노출되어 있으며, 개발자는 이러한 위협을 인지하고 적절한 방어책을 마련해야 할 책임이 있습니다.


왜 웹 보안이 중요한가?

  • 사용자 데이터 보호: 개인 정보(이름, 이메일, 주소, 전화번호), 금융 정보(신용카드 번호), 민감한 정보(건강 기록 등) 등 사용자의 중요한 데이터를 보호해야 합니다. 데이터 유출은 금전적 손실뿐만 아니라 기업 이미지에도 치명적인 영향을 미 미칠 수 있습니다.
  • 서비스 신뢰성 유지: 서비스가 해킹당하거나 오작동하면 사용자는 해당 서비스를 신뢰하지 않게 됩니다. 이는 고객 이탈과 비즈니스 손실로 이어질 수 있습니다.
  • 법적 책임: 개인 정보 보호법(GDPR, 국내 개인정보보호법 등)과 같은 법규를 준수하지 않을 경우, 법적인 처벌을 받을 수 있습니다.
  • 서비스 가용성 보장: DDoS(Distributed Denial of Service) 공격 등으로 서비스가 마비되는 것을 방지하여, 사용자가 언제든 서비스를 이용할 수 있도록 해야 합니다.

주요 웹 공격 유형 및 방어 전략

수많은 웹 공격 유형이 있지만, 개발자가 가장 흔하게 접하고 방어해야 할 몇 가지 중요한 공격들을 살펴보겠습니다.

XSS (Cross-Site Scripting)

  • 개념: 공격자가 웹 사이트에 악성 스크립트(주로 JavaScript)를 삽입하여, 다른 사용자의 웹 브라우저에서 해당 스크립트가 실행되도록 하는 공격입니다. 이를 통해 세션 쿠키 탈취, 개인 정보 유출, 피싱 페이지로 리다이렉트 등의 피해를 입힐 수 있습니다.
  • 공격 예시
    • 게시판에 <script>alert(document.cookie);</script> 같은 코드를 삽입.
    • URL 쿼리 파라미터에 악성 스크립트를 포함시켜 반사(Reflected) XSS 공격.
  • 방어 전략
    • 입력 값 검증 및 살균(Sanitization): 사용자로부터 입력받는 모든 데이터(게시물 내용, 댓글, 검색어 등)에 대해 <script>, <img> 태그 내 onerror 속성 등 잠재적으로 위험한 문자나 HTML 태그를 필터링하거나 제거합니다.
    • 출력 시 이스케이프(Escaping): 사용자 입력 값을 HTML 문서에 출력할 때는 반드시 &, <, >, ", ' 등의 특수 문자를 HTML 엔티티(예: &amp;, &lt;, &gt;)로 변환하여 브라우저가 스크립트로 해석하지 못하도록 합니다. 프레임워크(React, Vue)는 기본적으로 XSS 방어 기능(자동 이스케이프)을 제공하지만, dangerouslySetInnerHTML 같은 기능 사용 시 주의해야 합니다.
    • CSP (Content Security Policy): 신뢰할 수 있는 소스로부터만 웹 페이지 리소스를 로드하도록 브라우저에 지시하는 보안 정책입니다. 외부 악성 스크립트 실행을 차단합니다. HTTP 응답 헤더에 Content-Security-Policy를 설정합니다.

SQL Injection

  • 개념: 공격자가 데이터베이스 쿼리를 조작하는 SQL 구문(데이터베이스 명령)을 웹 애플리케이션의 입력 필드(로그인 폼, 검색 폼 등)에 삽입하여, 데이터베이스를 비정상적으로 조작하거나 데이터를 탈취하는 공격입니다.
  • 공격 예시
    • 로그인 ID 입력 필드에 ' OR 1=1 --를 입력하여 비밀번호 없이 로그인 성공.
    • 검색 필드에 '; DROP TABLE users; --를 입력하여 테이블 삭제 시도.
  • 방어 전략
    • Prepared Statement / 파라미터화된 쿼리 (Parameterized Queries): 사용자 입력 값을 SQL 쿼리 문자열에 직접 삽입하는 대신, 플레이스홀더(Placeholder)를 사용하고 입력 값을 별도의 파라미터로 바인딩하여 쿼리를 실행합니다. 이는 입력 값이 SQL 구문의 일부가 아닌 '데이터'로 인식되도록 하여 SQL 주입을 원천적으로 차단합니다. Node.js의 데이터베이스 드라이버/ORM(예: Sequelize, TypeORM, Mongoose)은 기본적으로 Prepared Statement를 지원합니다.
    • 입력 값 검증: 사용자 입력 값의 타입, 길이, 허용 문자 등을 백엔드에서 엄격하게 검증합니다.
    • 최소 권한 원칙: 데이터베이스 사용자에게 필요한 최소한의 권한만 부여합니다. (예: SELECT 권한만 필요한 계정은 DROP 권한을 주지 않음)

CSRF (Cross-Site Request Forgery)

  • 개념: 사용자가 로그인된 상태의 웹 사이트를 이용하고 있을 때, 공격자가 만든 악성 웹 페이지(또는 악성 스크립트)를 통해 사용자의 의지와 무관하게 특정 요청(예: 비밀번호 변경, 계좌 이체, 게시물 삭제)을 해당 웹 사이트에 보내도록 유도하는 공격입니다.
  • 공격 예시
    • 사용자가 로그인된 상태에서 악성 사이트 방문 시, 해당 사이트 내 숨겨진 폼이나 스크립트가 은행 사이트의 계좌 이체 URL로 요청을 보냄.
  • 방어 전략
    • CSRF 토큰 (CSRF Token): 서버에서 요청 시 고유한 토큰(Token)을 발행하여 웹 페이지에 숨겨진 필드로 삽입하고, 클라이언트가 폼을 제출할 때 이 토큰을 함께 전송하도록 합니다. 서버는 요청이 올 때마다 이 토큰이 유효한지 검증합니다. 공격자는 이 토큰 값을 알 수 없으므로 위조된 요청을 보낼 수 없습니다.
    • SameSite 쿠키 속성: 쿠키에 SameSite 속성(Strict, Lax, None)을 설정하여, 다른 도메인에서 요청이 왔을 때 쿠키가 자동으로 전송되는 것을 제한합니다. Strict는 가장 강력하며, Lax는 일반적인 링크 클릭 등은 허용하지만 CSRF 공격을 막는 데 효과적입니다.
    • Referer 검증: HTTP Referer 헤더를 검사하여 요청이 신뢰할 수 있는 도메인에서 왔는지 확인합니다. (완벽하지는 않음)

Brute Force Attack (무작위 대입 공격)

  • 개념: 공격자가 비밀번호, 핀 번호 또는 암호화 키를 찾아내기 위해 가능한 모든 조합을 시도하는 공격입니다. 특히 로그인 페이지에서 자주 발생합니다.
  • 방어 전략
    • 계정 잠금 (Account Lockout): 일정 횟수 이상 로그인 실패 시 계정을 일시적으로 잠급니다.
    • 재시도 제한 (Rate Limiting): 특정 IP 주소에서 일정 시간 동안 허용된 요청 횟수를 제한합니다. (예: 1분당 로그인 시도 5회 제한)
    • 캡차 (CAPTCHA): 자동화된 프로그램이 아닌 실제 사람임을 인증하는 절차(예: 그림 맞추기, 왜곡된 문자 입력)를 추가합니다.
    • 강력한 비밀번호 정책: 사용자에게 길고 복잡한 비밀번호(특수문자, 숫자, 대소문자 조합)를 사용하도록 강제하고, 주기적인 비밀번호 변경을 권장합니다.

DDoS (Distributed Denial of Service)

  • 개념: 여러 대의 좀비 PC(봇넷)를 사용하여 특정 서버에 대량의 트래픽을 동시에 발생시켜, 서버의 자원을 고갈시키고 정상적인 서비스가 불가능하게 만드는 공격입니다.
  • 방어 전략
    • CDN (Content Delivery Network): Cloudflare와 같은 CDN 서비스는 DDoS 공격을 분산시키고 필터링하는 데 도움을 줍니다.
    • 방화벽 (Firewall): 비정상적인 트래픽을 탐지하고 차단합니다.
    • 로드 밸런서 (Load Balancer): 트래픽을 여러 서버에 분산시켜 한 서버에 부하가 집중되는 것을 막습니다.
    • 클라우드 서비스 활용: AWS, Azure, GCP 등 클라우드 서비스는 대규모 인프라를 통해 DDoS 공격에 대한 방어 능력이 뛰어납니다.

중요 보안 고려 사항

  • HTTPS 사용: 모든 통신에 HTTPS(Hypertext Transfer Protocol Secure) 를 사용해야 합니다. HTTP는 평문으로 데이터를 전송하여 중간에서 가로채기(Man-in-the-Middle) 공격에 취약합니다. HTTPS는 SSL/TLS 암호화를 통해 통신 내용을 보호하고, 서버의 신원을 인증합니다. (무료 인증서: Let's Encrypt)
  • 비밀번호 암호화: 사용자 비밀번호는 절대 평문으로 데이터베이스에 저장해서는 안 됩니다. 단방향 해시 함수(예: bcrypt, scrypt) 와 솔트(Salt)를 사용하여 암호화해야 합니다.
  • 입력 값 검증 (Input Validation): 모든 사용자 입력 값은 클라이언트와 서버 양쪽에서 엄격하게 검증해야 합니다. 클라이언트 측 유효성 검사는 사용자 경험을 위한 것이며, 서버 측 유효성 검사는 보안을 위한 필수적인 조치입니다.
  • 오류 메시지 최소화: 사용자에게 불필요한 자세한 오류 메시지(예: 데이터베이스 에러 메시지)를 노출하지 않도록 합니다. 이는 공격자에게 시스템 정보를 제공할 수 있습니다.
  • 보안 헤더 설정: HTTP 응답 헤더에 X-Content-Type-Options, X-Frame-Options, Strict-Transport-Security 등 보안 관련 헤더를 설정하여 다양한 공격을 방어합니다.
  • 정기적인 보안 업데이트: 사용하는 프레임워크, 라이브러리, 운영체제 등을 항상 최신 버전으로 유지하여 알려진 취약점을 패치합니다.

마무리하며

이번 장에서는 웹 애플리케이션을 개발하고 운영하는 데 있어 가장 중요한 요소 중 하나인 웹 보안의 기초 개념과 주요 위협 및 방어 전략을 학습했습니다.

여러분은 XSS, SQL Injection, CSRF, Brute Force, DDoS와 같은 대표적인 웹 공격 유형들을 이해하고, 이에 대한 구체적인 방어 전략(입력 값 검증/이스케이프, Prepared Statement, CSRF 토큰, 재시도 제한, HTTPS 사용, 비밀번호 암호화 등)을 배웠습니다.

웹 보안은 개발 초기 단계부터 염두에 두어야 할 필수적인 고려 사항이며, 한 번의 설정으로 완벽해지는 것이 아니라 지속적인 관심과 업데이트가 필요합니다. 이 장에서 배운 기본 지식들을 바탕으로 안전하고 신뢰할 수 있는 웹 서비스를 구축하기 위해 노력하시길 바랍니다.