Week3 회고
서론
이번주는 여러가지 많은 것들을 경험해볼 수 있던 한주였다. 해킹을 당해서 DB를 털려보기도 하고, 토큰과 쿠키에대해 이해도가 생기게된 사건도 있었다. 그리고 웹프레임워크로 Express js를 쓰고 있는데, 정말 필요한 기능들이 잘 구현되어있는거 같아서 점점 좋아지고 있다. 쨌든 이번에는 아래와 같은 순서로 진행하고자 한다.
- RESTful API의 개념
- Express js의 package.json그리고 node_moduls 디렉토리에 대한 설명
- 토큰과 쿠키의 개념
- 해킹 당했던 경험과 대처
본론
A. RESTful API의 개념
1. 대략적인 RESTful API의 정의
- Representational State Transfer"의 약자
- 자원(resource)의 표현(representation)에 의한 상태전달
- 자원: 해당 소프트웨어가 관리하는 모든 것(ex. 문서, 그림, 데이터, 등등)
- 표현: 자원을 표현하기 위한 이름(ex. DB에 학생정보가 자원일때, "Students"를 자원의 표현이라고 한다.)
- 상태전달(정보전달): 데이터가 요청되면 자원의 상태(정보)를 전달하는것을 말함. JSON혹은 XML을 통해 데이터를 주고 받는것이 일반적이다(요즘엔 JSON을 대세로 본다.)
- REST는 기본적으로 웹의 기존 기술과 HTTP프로토콜을 그대로 활용하므로 웹의 장점을 최대한 활용할 수 있는 아키텍처 스타일이다.
- REST는 네트워크 상에서 Client와 Server사이의 통신 방식 중 하나이다.
- HTTP URI(Uniform Resource Identifier)를 통해 자원(Resource)을 명시하고,
HTTP Method(POST, GET, PUT, DELETE)를 통해 해당자원에 대한 CRUD Operation을 적용하는 것을 의한다. - CRUD Poeration
- Create: 생성(POST method를 통해 구현)
- Read: 조회(GET method를 통해 구현)
- Update: 수정(PUT또는 POST method를 통해 구현)
- Delete: 삭제(DELETE method를 통해 구현)
B. Express.js의 package.json파일, node_moduls 디렉토리
1. package.json파일
Express.js를 통해 간단한 웹개발을 해본 분들은 아시겠지만, package.json파일이 설치가 되어있을 것이다.
- package.json 예시
{
"name": "experss_00",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"crypto-js": "^4.1.1",
"dotenv": "^16.0.0",
"express": "^4.17.3",
"express-validator": "^6.14.0",
"jquery": "^3.6.0",
"jsonwebtoken": "^8.5.1",
"moment": "^2.29.1",
"moment-timezone": "^0.5.34",
"mongoose": "^6.2.7",
"nodemon": "^2.0.15"
}
}
- package.json이란 무엇인가?
- 생성된 프로젝트의 정보와 프로젝트가 의존하고있는(설치된) 모듈들에 대한 정보들을 json형태로 모아놓은 파일이다.
- package.json을 왜 사용하는가?
만약 package.json을 사용하지 않을 경우 다음과 같은 문제를 야기한다.- 프로젝트에서 사용하는 외부 모듈들이 많아지게 되면 관리하기가 어려워진다.
- 각 모듈에대한 버전을 편하게 확인 하기가 어렵다.(명령어로 하나씩 찍어야 한다.)
- 프로젝트마다 자주쓰는 모듈이 있다면 매번 npm명령어로 설치해야하는 번거로움이 있다.
- package.json파일만 있으면 npm install 명령어만 입력하면 package.json파일에 명시된 모듈들이 전부 설치된다!! 정말 개발환경 구축하기가 편하다는것이다!!
프로젝트의 개발환경을 빠르게 구축가능함과 모듈버전의 명시성을 위해서 사용한다.
2. node_moduls 디렉토리
- node_modules란 무엇인가?
- node_modules 디렉토리에는 package.json에 있는 모듈 뿐만 아니라, package.json에 있는 모듈이 의존하고 있는 모든 모듈을 포함하고 있다. 그래서 node_modules 디렉토리안에는 정말 많은 모듈들이 들어가 있다. npm으로 새로운 모듈(패키지)를 설치하게 되면, package.json과 node_modules에 추가된다.
- 참고로 커밋할때는 해당디렉토리를 제외하고 올리는것이 좋다. package.json파일이 있다면 npm install로 node_moduls 디렉토리를 현재 컴퓨터환경에 맞게 다시 설치가 되어야 개발에 있어서 충돌이 없기 때문이다.
3. package-lock.json
- package-lock.json이란 무엇인가?
- package-lock.json은 이 package-lock.json이 생성되는 시점의 의존성 트리(node_modules)에 대한 정보를 가지고 있는 파일을 말한다.
- 의존성 트리는 package.json에 등록된 모듈과 그 모듈들이 의존하고 있는 모듈 전부를 포함하고 있기 때문에, 결국 package-lock.json도 이 모든 모듈들을 가지고 있다.
- npm을 사용해서 node_modules나 package.json을 수정하게 되면, package-lock.json 또한 자동으로 업데이트가 된다.
- package-lock.json은 왜 사용하는가?
- 예로 들어 express버전, package.json파일 이렇게 2개가 같은 시기에 설치되어 버전충돌이 없는데, express만 어느날 최신버전으로 업데이트를 해버리면 package.json과 그에따른 node_modules버전이 express버전과 맞지 않아 충돌이 일어난다.
- 하지만! express의 업데이트가 일어날때 package-lock.json파일이 업데이트를 감지하고 package.json과 package-lock.json에 있는 모듈이 같은 버전으로 업데이트가 되고, 이때 package-lock.json 때문에 node_modules(의존성 트리)가 재생성되어, 3개의 파일에 있는 모듈이 모두 같은 버전으로 맞춰지게 되어 오류가 안나게 된다.
C. 토큰과 쿠키의 개념
1. 토큰
- 토큰
- 토큰이란 흔히 말하는 표현으로는 놀이공원에서 자유이용권티켓 이라고 생각하면 된다.
- 토큰중에서도 jwt토큰을 사용했는데, 해당 토큰의 구조는 header.payload.signature로 .을 기준으로 구분되어있으면 실제 예시는 낙독화된 숫자와 알파벳으로 구성된다.
- header: 해당토큰의 타입, 암호화알고리즘이 들어간다.
- payload: 사용자의 id, 토큰발급일자, 만료시간, 발급자, 발급대상자 등등 덜민감한 정보들이 들어간다.
- signature: 헤더와 페이로드, 시크릿키를 해시함수에 넣고 암호화한다. 시크릿 키는 서버만 가지고 있는 256bit비밀키이다. 클라이언트가 서버로 전송한 토큰을 urlsafe64디코더로 복호화하면 헤더와 페이로더가 드러나고 이것을 시크릿키와함께 암호화해서나온 결과값과 토큰에 명시되어있던 signature와 일치여부를 대조하여 위변조 여부를 검증할 수 있다. 여기서 핵심은 시크릿 키는는 서버만 가지고 있는 키이며 해시함수는 결과값으로 입력값을 추론할수없는 일방향 함수이다.
- jwt토큰은 누구나 탈취해서 복호화할수가 있는데, 이때 header, payload에 있는 정보가 그대로 노출된다. 따라서 여기엔 중요한 개인정보는 담으면 안된다.
2. 쿠키
- 브라우저에 있는 작은 저장소이다.
- 토큰은 쿠키에 저장되어서 클라이언트가 서버에 로그인검증이 필요한 작업을요청할때 요청정보와 함께 토큰이 전송된다.
D. 해킹당한 경험과 대처
1. 사건경위
어느날 내가만든 게시판 사이트에 모든 게시글이 삭제된 것이다... 그래서 나는 내가 테스트하다가 디비를 한번 날렸나?? 했다. 디비를 보니 0.05비트를 어떤 지갑주소로 전송하면 너의 데이터를 풀어주겠다는 내용이 디비에 저장되어있었다...
이번 해킹이 충격적이였던건 무려 아마존 ec2에 있는 db가 털린것이다... 따라서 범인의 흔적을 조사하고자 mongodb log파일을 열어봐서 예상 사건발생시간대를 내 아이피를 제외한 아이피가 디비의 테이블(컬렉션)을 드랍한 것을 찾아보았다. 역시나 내가 건든적없는 시간대에 어떤 아이피가 내 디비에 접속하여 테이블을 드랍한것을 찾아볼 수 있었다.
2. 대처
예상되는 시나리오는 디비 접근 포트를 anywhere로 개방해두어서 내 컴퓨터가 아니여도 디비의 관리자 계정을 무작위 공격으로 탈취하여 컨트롤을 하게된거같다... 따라서 ec2대시보드에서 인바운드 규칙에서 디비포트(27017)를 내 공인아이피로(보안을 위해 파란색 박스로 가림)만 접속할 수 있도록 수정 하였다.
3. 교훈
아무리 대기업서비스를 이용하더라도 내가 개방적으로 보안에 허술한 모습을 보이면 충분히 털릴 수 있다는 것과 어떻게 하면 안털릴지를 고민하고 찾아보는 계기가 되었다. 참고로 해당사례는 사람이 아닌 봇이 보안 취약점이 있는 서버의 디비를 무작위공격으로 계정탈취하여 조작하는 것이라는 내용을 쉽게 점할 수 있었다.
아래 링크에서 비슷한 경험자분의 분석글이니 시간나는분들은 읽어보는걸 추천합니당~
https://whackur.tistory.com/177
결론
이번주 경험은 뜻깊은 경험을 리스크 없이 해본 특별한 주차라고 생각한다. 덕분에 약간은 보안에 대해서 호기심이 생겼고 중요성 또한 인지하게되었다. 보안이라는게 아이러니한점이 안뚫리면 이거 제대로 작동하는거맞나?하는 생각이든다. 아무일이없기 때문이다. 하지만 뚫리면 그때는 난리가 난다는 점이다. 앞으로는 개발할때 보안에 관련된 요소 중 내가 구현할 수 있는것부터 하나씩 해보고 보안에 취약한 행동을 최대한 자제하도록 하고 싶다.
Author And Source
이 문제에 관하여(Week3 회고), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@xkskxhtm96/Week3-회고저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)