[59일차]HTTPS,Cookie,Session,SQLInjection,CSRF

유태형·2022년 7월 21일
0

코드스테이츠

목록 보기
59/77

오늘의 목표

  1. HTTPS
  2. Cookie
  3. Session
  4. 웹 보안 공격



내용

HTTPS

HTTPS 는 Hyper Text Transfer Protocal Secure Socket layer의 약자입니다. HTTP + Secure이라 생각하시면 될 것 같습니다. HTTPS는 HTTP요청을 SSL 또는 TLS라는 알고리즘을 통해 암호화 하여 전송하는 프로토콜입니다.

HTTPS에서의 암호화는 비대칭 암호화 키를 사용합니다. 여기서 말하는 비대칭이란 암호화 할때 사용된 키와 복호화 할때 사용된 키가 서로 달라 비대칭이라고 부릅니다.

HTTPS는 2단계를 거쳐 암호화를 진행하게 됩니다.

  1. 암호화
  2. 인증서


암호화

HTTPS는 대칭키와 비대칭키를 모두 사용합니다. 먼저 비대칭키를 이용하여 대칭키를 주고 받고 이후 주고받은 대칭키로 서로 암호화를 수행합니다.

비대칭 키는 2가지의 키를 가지고 있습니다. 자기자신만이 가지고 있는 비밀키(private Key)와 공공에게 공개하는 공개키(public key)를 가지고 있습니다. 하나의 키가 아닌 공개할 키, 나만 가질 키를 나누어 가짐으로써 서버가 불특정 다수인 클라이언트에게 암호화된 데이터를 보낼 수 있는 장점이 생깁니다. 반면에 불특정 다수의 클라이언트가 서버로 데이터를 보내는 중 제3자가 탈취하더라도 서버만이 가지고 있는 비밀키가 있어야만 공개키로 암호화된 데이터를 복호화 할 수 있습니다.

비밀키로 암호화 -> 공개키로 복호화 또는 공개키로 암호화 -> 비밀키로 복호화로 비밀키와 공개키는 서로 암호화와 암호화에 대한 복호화를 수행할 수 있습니다.



인증서

서버의 신원을 보증할 수 있는 Certificate Authority(CA)는 엄격하게 공인된 기관들을 의미합니다. CA들은 서버의 공개키와 CA의 비밀키로 암호화된 인증서를 발급하는 역할을 합니다. CA의 공개키로 CA의 비밀키로 암호화된 인증서를 복호화하하면 접속하고자하는 서버의 공개키를 얻을 수 있을 것입니다.(참고로 서버 =/= CA 입니다.)

요약하자면, CA에서 서버 인증서에 서버 공개키를 넣습니다. -> CA에서 서버 인증서를 CA의 비밀키로 암호화 합니다. -> 클라이언트는 CA의 공개키로 서버 인증서를 복호화 합니다. -> 서버 인증서의 서버의 공개키를 얻습니다. 의 과정을 거치게 됩니다.

CA를 통해 클라이언트가 서버의 인증서로 서버의 공개키를 얻는 프로토콜을 TLS 또는 SSL이라고 부릅니다.




쿠키는 서버에서 클라이언트로 데이터를 저장하여 서버와 클라이언트는 실제로 비동기적으로 통신 하지만 저장된 데이터를 이용하여 마치 계속 연결되어 있던 것처럼 이전의 데이터를 활용할 수 있는 방법중 하나입니다.
반대로 서버에서 클라이언트가 가진 쿠키를 이용하여 데이터를 가져올 수도 있습니다.

언제나 어떤 데이터나 서버에서 클라이언트로 데이터를 저장하고 필요할 때마다 데이터를 가져올 수는 없습니다. 특정 조건을 만족해야만 가지고 클라이언트의 쿠키를 가져올 수 있습니다.

조건들은 쿠키옵션으로 표현가능하며 쿠키 옵션에 따라 서버는 클라이언트로부터 데이터를 가지고 갈 수 있습니다.

Set-Cookie: <cookie-name>=<cookie-value>
Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<non-zero-digit>
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>
Set-Cookie: <cookie-name>=<cookie-value>; Path=<path-value>
Set-Cookie: <cookie-name>=<cookie-value>; Secure
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly

Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Strict
Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Lax

// Multiple directives are also possible, for example:
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly

쿠키의 문법입니다.

Set-Cookie: 프로퍼티에 <cookie-name>=<cookie-value>; 쿠키의 이름, 값, 경로등의 쿠키 데이터를 저장하고 ; 옵션 = <옵션값> 으로 쿠키 옵션을 지정할 수 있습니다.(;를 이용하여 여러 옵션 지정도 가능)



Domain

URL은 스키마://도메인/경로 구조를 가집니다. 쿠키옵션으로 Domain을 사용하게 된다면 URL의 도메인만 일치하면 뒤의 경로는 상관하지 않고 해당 쿠키를 서버로 전송합니다.



Path

URL의 스키마://도메인/경로에서 세부경로를 비교하여 옵션값으로 경로가 URL에 포함된다면 쿠키를 전송합니다. 예를들어 path의 옵션 값이 /users/users/velog는 실행 되지만, /account/velog는 실해되지 않습니다.



MaxAge, Expire

쿠키의 유효기간을 정하는 옵션입니다. 쿠키가 클라이언트에 그대로 계속 남아 있게 된다면 탈취하기 쉬워지기 때문에 일정 기간을 정해두고 해당 기간이 만료된다면 자동으로 삭제될 수 있도록 하는 옵션입니다.

MaxAge는 몇 초동안 쿠키가 유효할 것인지 정하는 옵션입니다. Expires는 쿠키가 언제까지 유효할찌 Date를 지정합니다.(클라이언트 기준)

세션 쿠키: MaxAge 또는 Expires옵션이 없는 쿠키, 브라우저 종료시 자동 삭제
영속성 쿠키 : 브라우저의 종료 여부와 상관없이 MaxAge 또는 Expires에 지정된 유효시간 만큼 사용가능한 쿠키



Secure

프로토콜에 따라 쿠키를 전송할 지 여부를 결정합니다. Secure 옵션이 true인 경우 HTTPS에서는 쿠키를 전송하지만 HTTP에서는 쿠키를 전송하지 않습니다.



HttpOnly

프론트엔드의 자바스크립트에서는 쿠키에 접근이 가능합니다. 따라서 <script> 태그로 접근 가능하여 XSS공격에 취약해질 수 있습니다. true지정 시 HTTP로만 접근할 수 있도록 설정하는 옵션은 HttpOnly입니다.

옵션을 지정하지 않을 시 false로 지정되어 있습니다.



SameSite

CSRF는 A서버가 B서버인척 클라이언트에게 B서버의 쿠키를 요청하는 공격을 의미합니다.
쿠키에 저장된 URL의 도메인, 프로토콜, 포트가 쿠키를 요청하는 서버가 같다면 SameSite, 다르면 Cross-Origin이라고 합니다. SameSite 옵션으로 Cross-Origin으로부터 요청을 제한하거나 거절할 수 있습니다.

  • LAX : Cross-Origin 요청은 GET메서드에 대해서만 쿠키를 전송할 수 있습니다.
  • STRICT : Cross-Origin 요청은 거절하고 SameSite인 경우에만 쿠키를 전송합니다.
  • None : HTTPS 프로토콜에서만 Cross-Origin 요청에 항상 쿠키를 전송할 수 있습니다.



Session

서버가 Client에 유일하고 암호화된 ID를 부여하고 데이터를 서버에 데이터를 저장하고 클라이언트의 쿠키에는 ID만 암호화해서 전달합니다.

  1. 서버는 인증(Authentication)에 성공했다고 판단할 경우 암호화된 session_id를 클라이언트에게 쿠키에 담아서 전달합니다.

  2. 이미 로그인하여 인증을 한 상황이기에 클라이언트는 가지고 있던 session_id를 통하여 신분증 처럼 재차 로그인할 필요 없이 작업을 수행합니다.

  3. 서버는 session_id를 확인하고 작업을 업데이트 합니다. 업데이트 후 session_id를 통해 작업을 수행하였던 클라이언트에 결과 응답을 전달합니다.

session은 cookie와 다르게 중요한 정보를 클라이언트가 아닌 서버에 저장하고 클라이언트에겐 cookie(도구)로 session_id만 전달하여 인증만 간단하게 할 수 있도록 합니다.

최초의 로그인 인증을 거쳐 얻은 session_id로 재차 인증을 할 필요 없이 바로 작업을 수행했지만, session_id 인증정보는 쿠키로 클라이언트에 저장되므로 로그아웃을 수행해야합니다.

  • 서버는 로그아웃시 세션 정보를 삭제해야 합니다.
  • 클라이언트는 쿠키를 갱신해야 합니다. -> 서버가 클라이언트에게 의미없는 값의 session_id를 부여함으로써 더 이상 인증을 못하게 합니다.



웹 보안 공격

웹 보안을 공격하는 방법으로 여러가지가 존재하지만 저는 보안,해킹 쪽을 배우는게 아닌지라 간단히 대표적인 것만 알아 보았습니다 :)



SQL Injection

로그인시 ID와 비밀번호를 입력하게 되고 이 비밀번호와 이이디를 문자열로 이용하여 SQL로 활용하게 됩니다.

예를들어 http라는 테이블에 id = "abc" 와 비밀번호 = "1234"를 조건으로 찾기 위해서는 다음과 같은 SQL문을 실행할 것입니다.

SELECT *
FROM http
WHERE auth = "user"
AND id = "abc" and pw = "1234";

만일 공격하는 해커가 입력양식에 비밀번호에 ' OR '1' = '1 을 입력하여 보낸다면 아래와 같은 SQL문으로 변형될 것입니다.

SELECT *
FROM http
WHERE auth = "user"
AND id = "" and pw = '' OR '1' = '1';

ORAND보다 우선순위가 낮기 때문에 WHERE 절은 '1' = '1'은 항상 참이므로 참이 됩니다. 따라서 항상 로그인이 가능합니다.

또한 DROP TABLE를 활용하여 패스워드에 ' OR '1' = '1'; DROP TABLE http;--' 와 같이 입력한다면 로그인 정보를 모두 삭제함으로써 막대한 피해도 끼칠 수 있습니다.

SELECT *
FROM http
WHERE auth = "user"
AND id = "" and pw = '' OR '1' = '1';DROP TABLE http;--';

SQL Injection을 방지하기 위해서는 입력값에 대한 유효성 검증(@Valid)를 통해 아이디나 패스워드가 올바른 형태인지 확인함으로 써 방지할 수도 잇고

Prepared Statement 구문을 입력하면 SQL문과 입력데이터를 분리하여 미리 실행하지 않고 입력 값을 단순 텍스트로 보관하므로 방지할 수 있습니다.



CSRF(Cross Site Request Forgery)

Cross-Origin에서 유저가 보내는 요청을 조작하는 행위입니다. 다른 오리진이기 때문에 직접 데이터에는 접근할 수 없는 특징이 있습니다.

쿠키를 사용하여 로그인할 수 있는 경우, 또 요청이나 파라미터가 예측가능할 때 공격할 수 있습니다.

해커가 클라이언트에게 악성 이메일등으로 request 요청을 훔쳐 훔친 요청을 조작하여 클라이언트인 척 하며 서버에서 필요한 자원을 빼내는 행위를 들 수 있습니다.

CSRF를 대처하는 방법은 2가지가 존재합니다.

CSRF 토큰을 유저의 브라우저와 웹 앱에만 제공하여 조합으로 생성된 요청에만 성공적으로 응답합니다.

Same-site 쿠키옵션을 이용하여 같은 사이트에서만 응답하게 합니다.




후기

한동안 Spring 실습 위주로 학습하다가 오랜만에 CS관련 이론을 학습하니까 새롭고 긴장되었습니다. 보안과 관련하여 쿠키, 세션, 암호화 등에 대하여 학습하였고 HTTPS 프로토콜이 중요하다는 점을 알았습니다. 쿠키와 세션을 잘 응용하여 현업에서도 보안 문제가 없도록 해야 겠습니다.




GitHub

없음!

profile
오늘도 내일도 화이팅!

0개의 댓글