HTTPS 보안에 대해서

1. HTTPS란,

  • HTTPS는 Hyper Text Transfer Protocol Secure Socket Layer의 약자로, HTTP over SSL(TLS), HTTP over Secure라고 부른다.
  • 즉, HTTPS는 HTTP+ Secure(보안)이 추가된 프로토콜이다.
  • HTTPS는 HTTP 요청을 SSL 혹은 TLS 라는 알고리즘을 이용해, HTTP 통신을 하는 과정에서 내용을 암호화하여 데이터를 전송하는 방법이다.

1-1. HTTPS 특징

1-1-1. 인증성(Certificate)

  • 데이터를 보내준 서버가 진짜 그 서버인지 인증,확인하는 용도로 사용되어 데이터 제공자 신원 보장한다.
  • 인증서 내용에 서버의 도메인 관련 정보가 있어서 데이터 제공자의 인증을 용이하게 한다.
  • 이러한 인증서를 발급해주는 공인인증서 발급기관이라고 부르고 영어로는 CA(Certificate Authority)라고 한다.
  • 각 브라우저는 자신들이 신뢰하는 기관의 인증서를 가지고 있다.

1-1-2. 비대칭 키 암호화

  • 키 A로 암호화 후 키 B로만 복호화 가능(A와 B는 한쌍)한데 한가지 키는 열쇠구멍 처럼 공개가 되어있는 키 이고, 나머지 키는 비공개키로 이루어진 한 쌍이라 비대칭 키라고 부른다.
  • 공개키를 암호화할 때는 데이터 보안에 중점을 주고,
  • 비공개키를 암호화 할 때에는 인증 과정에 중점을 주었다고 볼 수 있다.

2. Hasing

  • 어떠한 문자열에 ‘임의의 연산’을 적용하여 다른 문자열로 변환하는 것이다.
  • 쉽게 말해, 입력받은 데이터를 고정된 길이의 데이터로 변환할 때 이전의 데이터를 알아볼 수 없게 만드는 것을 의미한다.
  • Hasing 함수는 동일한 input이 들어가면 동일한 output이 나오는 순수 함수이다.
  • 해싱된 값은 복호화가 불가능하다.

2-1. Hasing의 특징

  • 모든 값에 대해 해시 값을 계산하는데 오래걸리지 않아야한다.
  • 최대한 해시 값을 피해야하며, 모든 값은 고유한 해시 값을 가진다.
  • 아주 작은 단위의 변경이라도 완전히 다른 해시 값을 가져야한다.

3. Salt

  • 암호화해야 하는 값에 어떤 ‘별도의 값’을 추가하여 결과를 변형하는 것이다.
  • 암호화만 해놓는다면, Hash된 결과가 늘 동일하여 decoding해버리는 경우가 생기 때문에, 등장한 것이 salt이다.
  • 원본값에 임의로 약속된 ‘별도의 문자열’을 추가하여 해시를 진행한다면, 기존 해시값과 전혀 다른 해시값이 반환되어 알고리즘이 노출되더라도 원본값을 보호할 수 있도록 하는 안전 장치이다.
  • salt는 사용자와 비밀번호 별로 유일한 값을 가지며, 절대 재사용해서는 안된다.
  • 데이터베이스 사용자 테이블에 해싱된 패스워드값과 솔트값을 함께 저장한다.
  • salt를 코드 내에서 찾는다면, 아래와 같다.
const app = express();
app.use(session({
  secret: 'keyboard cat', //!! 여기가 salt!!
  resave: false,
  saveUninitialized: true,
  cookie: { secure: true }
}))

4. Cookie

  • 서버에서 클라이언트에 데이터를 저장하는 방법의 하나이다. (어떤 웹사이트에 들어갔을 때, 서버가 일방적으로 클라이언트에 전달하는 작은 데이터) 그러므로 서버가 원한다면 서버는 클라이언트에서 쿠키를 이용하여 데이터를 가져올 수 있다.
  • 쿠키를 이용하는 것은 단순히 서버에서 클라이언트에 쿠키를 전송하는 것만 의미하지 않고, 클라이언트에서 서버로 쿠키를 전송하는 것도 포함된다.
  • 쿠키의 특성을 이용하여 서버는 클라이언트에 인증정보를 담은 쿠키를 전송하고, 클라이언트는 전달받은 쿠키를 요청과 같이 전송하여 stateless한 인터넷 연결을 stateful하게 유지할 수 있다. 하지만 기본적으로 쿠키는 오랜 시간 동안 유지될 수 있고, 자바스크립트를 이용하여 쿠키에 접근할 수 있기 때문에 쿠키에 민감한 정보를 담는 것은 위험하다. 이런 인증정보를 탈취하여 서버에 요청을 보낸다면 서버는 누가 요청을 보낸건지 상관하지 않고, 인증된 유저의 요청으로 취급하기 때문에 개인유저 정보같은 민감한 정보에 접근이 가능하다.
  • 쿠키의 특징으로 서버가 클라이언트에 데이터를 저장할 수 있다. 그래서 서버는 쿠키를 이용하여 데이터를 저장하고 원할 때 이 데이터를 다시 불러와 사용 할 수 있다. 하지만 데이터를 저장한 이후 아무때나 데이터를 가져올 수 없다. 데이터를 저장한 이후 특정 조건들이 만족하는 경우에만 다시 가져올 수 있다.
  • 이러한 조건들을 쿠키의 옵션으로 설정한다.

4-1. Cookie Options

  1. Domain : 서버와 요청의 도메인이 일치하는 경우 쿠키 전송
    쿠키 옵션에서 도메인은 포트 및 서브 도메인 정보, 세부경로를 포함하지 않는다. (서브 도메인은 www처럼 도메인 앞에 추가로 작성되는 부분이다.)
    만약 쿠키옵션에서 도메인 정보가 존재한다며 클라이언트에서는 쿠키의 도메인 옵션과 서버의 도메인이 일치해야만 쿠키를 전송할 수 있다.
  2. Path : 서버와 요청의 세부경로가 일치하는 경우 쿠키 전송
    세부 경로는 서버가 라우팅할때 사용하는 경로이다. Path 옵션의 특징은 설정된 path를 전부 만족하는 경우 요청하는 path가 추가로 더 존재하더라도 쿠키를 서버에 전송할 수 있다. 즉 path가 /users로 설정되어 있고, 요청하는 세부 경로가 /users/login 인 경우라면 쿠키 전송이 가능하다.
  3. MaxAge or Expires: 쿠키의 유효기간 설정
    쿠키가 유요한 기간을 정하는 옵션이다. MaxAge는 앞으로 몇 초동안 쿠키가 유효한지 설정하는 옵션이다.
    Expires는 MaxAge와 비슷하지만 언제까지 유효한지 date를 지정한다. 이때 클라이언트의 시간을 기준으로 한다. 그리고 지정된 시간, 날짜를 초과하게 되면 쿠키는 자동으로 파괴된다.
    만약 두 옵션이 모두 지정되지 않는 경우에는 브라우저의 탭을 닫아야만 쿠키가 제거된다.
  4. Secure: HTTPS 프로토콜에서만 쿠키 전송 여부 결정
    쿠키를 전송해야 할 때 사용하는 프로토콜에 따른 쿠키 전송 여부를 결정한다. 만약 해당 옵션이 true로 설정된 경우, ‘HTTPS’ 프로토콜을 이용하여 통신하는 경우에만 쿠키를 전송할 수 있다.
  5. HttpOnly: 스크립트의 쿠키 접근 가능 여부 결정 -> 쿠키는 <script>태그로 접근 가능(XSS 공격에 취약)
    자바스크립트에서 브라우저의 쿠키에 접근 여부를 결정한다. 만약 해당 옵션이 true로 설정된 경우, 자바스크립트에서는 쿠키에 접근이 불가하다. 명시되지 않으면 기본 false로 지정되어 있다. 만약, 이 옵션이 false인 경우 자바스크립트에서 쿠키에 접근이 가능하므로 ‘XSS’ 공격에 취약하다.
  6. SameSite: CORS 요청의 경우 옵션 및 매서드에 따라 쿠키 전송 여부 결정
    Cross-Origin 요청을 받은 경우 요청에서 사용한 메소드와 해당 옵션의 조합으로 서버의 쿠키 전송 여부를 결정하게 된다. 사용가능한 옵션으로는 3가지가 있고, 이러한 옵션들을 지정한 다음 서버에서 클라이언트로 쿠키를 처음 전송하게 된다면, 헤더에 Set-Cookie 라는 프로퍼티에 쿠키를 담아 쿠키를 전송하게 된다. 이 후 클라이언트 혹은 서버에서 쿠키를 전송해야 한다면, 클라이언트는 헤더에 cookie라는 프로퍼티에 쿠키를 담아 서버에 쿠키를 전송하게 된다.
    1) Lax: Cross-Origin 요청이면, ‘GET’ 메소드에 대해서만 쿠키를 전송할 수 있다.
    2) Strict : Cross-Origin이 아닌 same-site인 경우에만 쿠키를 전송할 수 있다.
    3) None: 항상 쿠키를 보내 줄 수 있다. 다만 쿠키 옵션 중 secure옵션이 필요하다. 이때, ‘same-site’는 요청을 보낸 origin과 서버의 도메인이 같은 경우를 말한다.

5. Session

  • Session(세션)은 사용자가 인증에 성공한 상태이다.
  • 인증에 따라 리소스의 접근 권한(authorization)이 달라진다.
  • 접근 권한을 다르게 하기 위해서, 서버는 사용자가 인증에 성공했음을 알고 있어야하고, 반대로 클라이언트는 인증성공을 증명할 수단이 필요할 것이다.
  • 이를 위해 세션이 만들어지면, 각 세션을 구분할 수 있는 세션 아이디도 서버에서 만들어져 쿠키에 저장되어 클라이언트에 전달된다.
  • 이 후, 다시 클라이언트가 무언가를 하고자 서버에 요청을 할 때, 쿠키를 통해 유효한 세션 아이디가 서버에 전달되고, 서버는 세션 아이디를 보고 접근 가능 여부를 판단한다.
  • 서버는 in-memory 또는 세션 스토어(redis 등과 같은 트랜잰션이 빠른 DB)에 세션을 저장하는데,
    • 쿠키에 있는 세션 아이디가 세션 스토어에 존재한다면, 접근 가능
    • 쿠키에 유효한 세션 아이디 정보가 없으면 해당 요청이 인증되지 않았다고 알게 된다.

5-1. Cookie VS Session

  1. 쿠키는 그저 http의 stateless 한 것을 보완해주는 도구이고, 세션은 접속 상태를 서버가 파악하고, 접속 상태와 권한 부여하기 위해 세션아이디를 쿠키로 전송하는 것이다.
  2. 접속상태를 저장하는 경로가 다르다. 쿠키는 클라이언트에서 하고, 세션은 서버에서 한다.
  3. 쿠키의 장점으로는 서버의 부담을 덜어주는 것이 있고, 단점은 쿠키로는 인증이 불가능 하다는 것이다.
  4. 세션의 장점으로는 신뢰할 수 있는 유저인지 서버에서 추가로 확인이 가능하다는 것이고, 단점으로는 하나의 서버에서만 접속 상태를 가지므로 분산에는 불리하다는 것이다.

5-2. 로그아웃 구현하기

  • 세션 아이디가 담긴 쿠키는 클라이언트에 저장되어 있고, 서버는 세션을 저장하고 있다. 서버는 세션 아이디로만 인증된 사용자의 요청인지 아닌지를 판단한다.
  • 그래서 로그아웃을 구현하려면, 두가지 작업을 해야한다.
    • 서버의 세션 정보를 삭제한다.
    • 클라이언틔 쿠키를 갱신해야한다.
  • 하지만 서버가 클라이언트의 쿠키를 임의로 삭제할 수는 없다. 대신, set-cookie로 세션 아이디의 키값을 무효한 값을 갱신해야한다.

5-3. express-session

  • 이러한 세션을 대신 관리해주는 모듈이 express-session이다.

6. CSRF(Cross Site Request Forgery)

  • 다른 사이트에서 유저가 보내는 요청(request)을 조작(forgery) 하는 것이다. CSRF의 예시로, 이메일에 첨부된 링크를 누르면 내 은행계좌의 돈이 빠져 나가는 범죄가 있다.

좋은 웹페이지 즐겨찾기