CodeStates 45th

Section 4. [인증/보안] 기초

jeonniu 2023. 7. 17. 22:01

HTTP

Hyper Text Transfer Protocol

- 하이퍼텍스트(HTML) 문서 교환을 위해 만들어진 프로토콜 (통신 규약)

- TCP/IP 기반

- request(요청)/response(응답) 구조

 

🙁 문제점

- 서버에서부터 브라우저로 전송되는 정보가 암호화되지 않음

=> 데이터 유출, 도난 위험 발생

 

😎 해결 방법

- HTTP 통신 과정에서 데이터를 암호화해서 전송해보자

=> HTTPS를 사용하자!

 

HTTPS

Hyper Text Transfer Protocol Secure Socket Layer

- HTTP 통신 과정에서 데이터를 암호화하여 전송하는 방식 

- 대칭키, 비대칭키 방식 혼용하여 사용

 

🔸 대칭키 방식

- 양쪽이 공통의 비밀 키를 공유 => 데이터를 암호화/복호화하는 것

 

🔸 비대칭키 방식

- 각각 공개키와 비밀키를 가지고 상대가 나의 공개키로 암호화한 데이터를 개인이 가진 비밀키로 복호화 하는 것 

 

◻ Server - Client 통신

- 대칭키 방식 사용

 

◻ 대칭키 간의 통신

- 비대칭키 방식 사용

 

- 브라우저가 서버의 응답과 함께 전달된 인증서를 확인 가능 => 서버의 신원을 보증

보증할 수 있는 제삼자: Certificate Authority, CA (인증서를 발급해주는 공인된 기관들)

 

🔸 SSL/TLS 프로토콜

- 서버, 클라이언트 간의 CA 통해 서버를 인증하고 데이터를 암호화하는 과정

 

 

📒 Homework

- 인증서 발급 및 HTTPS 서버 구현

 

- mkcert 프로그램으로 PKCS12 형식의 인증서 발급받기 (Window 환경 - wsl)

$ cd ~ # 홈에서 아래 단계를 진행한 뒤 mv 명령어로 인증서 파일을 이동시킬 수 있습니다.
혹은
$ cd {프로젝트 저장 위치} # /mnt로 이동하면 윈도우 파일 시스템에 접근할 수 있습니다.
-------------------------
$ sudo apt update # 설치 불가능할 경우, 이 명령어 수행
$ sudo apt install libnss3-tools
$ wget -O mkcert https://github.com/FiloSottile/mkcert/releases/download/v1.4.3/mkcert-v1.4.3-linux-amd64
$ chmod +x mkcert
$ sudo cp mkcert /usr/local/bin/

 

- 인증서 생성

$ mkcert -install
$ mkcert -pkcs12 localhost

 

mkcert 인증서 저장 위치 확인

 

◼ WSL -> Windows로 파일 전송
cp test.txt /mnt/c/Users/[사용자이름]/Desktop/.

◼ Windows -> WSL로 파일 전송
cp /mnt/c/Users/[사용자이름]/Desktop/test.txt ./

 

localhost.p12 인증서: wsl -> Windows 파일 전송

 

생성된 인증서 src/main/resources/ 넣기

 

server.ssl.key-store=classpath:localhost.p12  #  -> 인증서 경로를 적습니다.
server.ssl.key-store-type=PKCS12              #  -> 인증서 형식을 적습니다.
server.ssl.key-store-password=changeit        #  -> 인증서 비밀번호를 적습니다.

# 여기서 비밀번호인 changeit은 비밀번호를 설정하지 않았을 때의 기본값입니다.
# 인증서 비밀번호는 인증서를 생성할 때 설정하거나 생성 후 변경해줄 수 있습니다.

- application.properties에 관련 설정 추가 

 

Spring Boot HTTPS 서버 작동 확인

 

 


해싱

- 암호화만 가능, 복호화 XX


해시 함수 사용
- 항상 같은 길이 문자열을 리턴
- 다른 문자열에 동일한 해시 함수 사용하더라도 - > 다른 결과값 나옴
- 같은 문자열에 동일한 해시 함수 사용하면 -> 같은 결과값 나옴

🙁 문제
- 해싱이 되었더라도 해싱 이전의 값을 유추할 수 있기에 보안상 위험 발생!!

salt
- 해싱 이전 값에 임의의 값을 더해 데이터가 유출되더라도 해싱 이전의 값을 알아내기 더욱 어렵게 만드는 방법

목적
- 데이터 자체를 사용하는 것 X

- 동일한 값의 데이터를 사용하고 있는지의 여부를 확인하는 것이 목적

- 민감한 데이터를 다루어야 하는 상황에서 데이터 유출의 위험성 줄이고
- 데이터의 유효성을 검증하기 위해서 사용되는 단방향 암호화 방식

 

Cookie
- 서버에서 클라이언트에 데이터를 저장하는 방법 

"쿠키를 이용한다" 
- 단순히 서버 => 클라이언트에게 쿠키를 전송 하는것이 아닌 클라이언트에서 => 서버로 쿠키를 전송하는 것도 포함

서버가 클라이언트에 데이터를 저장할 수 있다.
=> 데이터를 저장한 후에는 특정 조건이 만족해야만 다시 가져올 수 있음 

- 자주 사용되는 쿠키 옵션들
1. Domain
- 서버에 접속할 수 있는 이름
- http://www.localhost.com:3000/users/login이라 하면, 여기에서 Domain은 localhost.com
- 쿠키의 도메인 옵션 == 서버의 도메인 옵션 이어야만 쿠키를 전송할 수 있음

2. Path
- 세부 경로는 서버가 라우팅 할 때 사용하는 경로
- http://www.localhost.com:3000/users/login인 경우라면 여기에서 Path, 세부 경로는 /users/login
- path를 전부 만족하는 경우: 요청하는 Path가 추가로 더 존재해도 쿠키 전송 가능
-  Path가 /users로 설정되어 있고, 요청하는 세부 경로가 /users/codestates인 경우라면 쿠키 전송이 가능
- /posts/codestates로 전송되는 요청은 Path 옵션(/users)을 만족하지 못하기 때문에 서버로 쿠키를 전송 불가능

3. MaxAge & Expires
- 쿠키의 유효 기간을 정하는 옵션
- MaxAge: 몇 초 동안 쿠키가 유효한지 설정하는 옵션
- Expires: 쿠키가 언제까지 유효한지 Date 지정 (클라이언트의 시간을 기준으로 ..)

위 옵션에 따라 세션/영속성 쿠키로 나눔
- 세션 쿠키: MaxAge 혹은 Expires 옵션이 X, 브라우저가 실행 중일 때 사용할 수 있는 임시 쿠키 => 브라우저 종료 시 쿠키 삭제
- 영속성 쿠키: 브라우저 종료 여부와 상관 X, MaxAge 혹은 Expires에 지정된 유효시간 만큼 사용 가능

4. Secure
- 쿠키 전송 시 사용해야 하는 프로토콜에 따른 쿠키 전송 여부 결정
- 해당 옵션: True => HTTPS 프로토콜 이용하여 통신하는 경우에만 쿠키 전송 가능
if) Secure 옵션 X ==>  프로토콜 상관 없이 http://www.codestates.com 또는 https://www.codestates.com에 모두 쿠키를 전송 O


5. HttpOnly
- 자바스크립트에서 브라우저의 쿠키에 접근 여부를 결정
- 해당 옵션: True => 자바 스크립트에서는 쿠키에 접근 불가능
- 옵션 명시되지 않은 경우 기본적으로 False로 지정됨
- if) 해당 옵션: False => 자바스크립트에서 쿠키 접근이 가능 => 'XSS' 공격에 취약
'XSS 공격?': 웹 애플리케이션에서 일어나는 취약점으로 관리자가 아닌 권한이 없는 사용자가 웹 사이트에 스크립트를 삽입하는 공격 기법을 의미
- 자바스크립트를 사용하여 공격하는 경우가 가장 많고, 사용자의 세션을 공격자의 서버로 전송해서 탈취하거나 악성코드가 있는 페이지로 리다이렉트 시키는 방식으로 공격이 주로 행해집니다. 그 외에도 자바스크립트를 활용해서 내부 네트워크 포트스캔과 같은 공격도 가능합니다.


6. SameSite
- Cross-Site 요청 받을 시: 요청에 사용한 메서드와 해당 옵션의 조합을 기준으로 서버의 쿠키 전송 여부를 결정
> Cross-Origin: 서버의 도메인, 프로토콜, 포트 중 하나라도 다른 경우
http://codestates.com vs https://codestates.com ⇒ 프로토콜이 다르므로 Cross-Origin
https://codestates.com:443 vs https://codestates.com ⇒ https의 기본 포트는 443입니다. 따라서 도메인, 프로토콜, 포트가 모두 같은 Same-Origin

> Cross-Site: eTLD+1이 다른 경우 Cross-Site로 구분
eTLD+1 이란, .com, .org과 같이 도메인의 가장 마지막 부분을 TLD(Top Level Domain, 최상위 도메인)
이 최상위 도메인의 바로 왼쪽의 하위 레벨 도메인을 합한 것을 eTLD+1 이라고 함

http://codestates.com vs https://codestates.com ⇒ 두 주소 모두 TLD는 .com, eTLD+1은 codestates.com으로 같으므로 Same-Site
https://code.github.io vs https://states.github.io ⇒ 두 주소 모두 TLD는 .io, eTLD는 github.io이며 , eTLD+1은 각각 code.github.io, states.github.io로 다르므로 Cross-Site

- SamSite에서 사용할 수 있는 옵션
> Lax: Cross-Site 요청이면 Get 메서드에 대해서만 쿠키 전송 가능
> Strict: Same-Site 경우에만 쿠키 전송 가능 (Cross-Site 는 아예 불가능.. 가장 엄격한 요청)
> None: Cross-Site에 대해 가장 관대한 옵션 => 항상 쿠키를 보내줄 수 있음 (쿠키 Secure 옵션 필요)



domain - 서버와 요청의 도메인이 일치하는 경우 쿠키 전송
path - 서버 요청의 세부 경로가 일치하는 경우 쿠키 전송
maxage/expires - 쿠키의 유효기간 설정
httpOnly - 스크립트의 쿠키 접근 가능 여부 설정
secure - HTTPS에서만 쿠키 전송 여부 설정
sameSite - 같은 사이트에서만 쿠키를 사용할 수 있게 하는 설정


SQL Injection
- DB에서 임의의 SQL 문을 실행할 수 있도록 명령어를 삽입하는 공격 유형
=> DB 비정상적으로 조작 => 데이터 삭제 및 유출 위험 가능

> 대응 방안 
1. 입력(요청)값 검증 
- 해당 키워드가 들어올 시 다른 값으로 치환
2. Prepared Statement 구문 사용
- 사용자의 입력이 SQL문으로부터 분리됨 ==> SQL Injection 방어 가능
- 사용자 입력값 전달되기 전, DB가 미리 컴파일 => SQL 바로 실행 X 대기 ==> 단순 텍스트로 일단 인식 <== SQL 문 아닌 텍스트문으로 인식되어 공격 실패
3. Error Message 노출 금지
- 에러 발생한 SQL문 등의 에러 내용이 노출되지 않도록 에러 핸들링 필요