1. 악성코드 문제

첫 번째로 악성 코드 문제가 있습니다. 그러니까 내 패키지가 의존하는 수많은 하위 패키지 중에 악성코드가 있을 수도 있다는 뜻이죠. 실제로 2017년에는 cross-env라는 유명 패키지와 이름이 비슷한 crossenv라는 패키지에 악성 코드가 들어 있는 경우가 발견된 적도 있습니다.[1] 사용자들이 패키지를 설치할 때 오타를 별로 신경 쓰지 않고 패키지를 설치해버리는 취약점을 공격한 일명 'typo-squatting' 기법을 사용한 경우였는데요.

이 뿐만 아니라 2018년에는 Event-Stream이라는 유명 패키지가 의존하던 Flatmap-Stream이라는 패키지에 비트코인 관련 악성 코드가 포함된 사건도 있었고,[2] 2020년에는 유닉스 시스템의 중요 정보를 빼가는 악성 패키지가 발견되는 사건도 있었습니다.[3]

내가 사용하는 패키지 중에 이런 악성 코드들이 있다고 상상해보면 정말 무섭죠? 물론 패키지들의 보안 검사를 위해 npm 커뮤니티에서 많은 노력을 하고는 있지만, 특정 패키지, 그리고 그것이 의존하는 패키지들이 사용해도 괜찮은 것인지 확인하는 것은 본질적으로 그것을 사용해서 서비스를 만드는 개발자의 책임입니다. 모든 패키지를 본인이 직접 검사하는 것은 현실적으로 어렵겠지만 악성 코드가 있는 패키지를 설치하지 않으려면, 되도록 누구나 알 정도로 공신력있는 패키지들만을 골라서 사용하는 것이 좋습니다.

2. 패키지 내 코드의 취약점 문제

두 번째는 취약점 문제입니다. 어떤 패키지들의 코드에는 보안 측면에서 취약한 부분이 있을 수 있습니다. npm 측과 각종 보안 회사들은 어떤 패키지의 어떤 점이 취약하다고 주기적으로 발표를 하는데요. 이 문제에 관해 우리가 할 수 있는 것은 다음과 같습니다.

(1) npm outdated, npm update 정기적으로 실행하기

먼저, 현재 작업 중인 패키지 안에서 npm outdated, npm update 라는 명령어를 자주 실행해주는 겁니다. npm outdated는 현재 패키지에 설치된 하위 패키지들 중에 버전이 최신이 아닌 것들이 무엇이 있는지 보여주는 명령어입니다. 그리고 npm update는 현재 자신의 패키지에 설치된 모든 패키지들을 최신 패키지로 업데이트해주는 명령어이고요.

본인의 패키지 안에서 npm outdated로 오래된 패키지들이 많지는 않은지 확인해주고, npm update로 이것들을 최신 패키지로 업데이트해주는 작업을 정기적으로 수행해주면 좋습니다. 참고로 npm update는 package.json 파일의 dependencies 필드에 표시된 해당 패키지의 Version Range Syntax가 허용하는 범위 내에서만 업데이트를 해줍니다. 현재 설치된 버전이 1.5.2고, 최신 버전은 3.0.0인 패키지가 있다고 해도 이 패키지에 의존 중인 패키지의 package.json 파일에서 dependencies 필드에 ~1.8.3 이라고 써있다면 1.9.0 미만의 최신 버전까지로만 업데이트해주는 겁니다.

어쨌든 최신 버전의 패키지들을 사용할수록 일반적으로 보안상 더 안전하기 때문에 위 작업을 주기적으로 실행해주는 게 좋습니다. 이때 일부 패키지의 경우, 최신 버전으로 업데이트하기 전에 별도의 검토가 필요해서 모든 패키지를 최신의 것으로 바꾸면 안 되는 경우에는

npm update [패키지명]

을 실행해서 원하는 패키지만 업데이트해줘도 됩니다. 만약 최신보다 약간 이전의 버전을 원하면

npm update [패키지명]@[버전]

이런 식으로 특정 버전을 지정해주고 실행하면 됩니다.

(2) npm audit, npm audit fix으로 취약점 점검하기

패키지 내의 보안을 유지하는 또 다른 방법은 npm audit이라는 커맨드를 사용하는 건데요. 현재 자신의 패키지 안에서 npm audit이라는 커맨드를 실행하면, npm이 현재 설치된 패키지들의 이름과 버전을 보고, 발표된 취약점이 있는 것들은 그 정보를 출력해줍니다. 저도 제 패키지에서 npm audit을 실행해봤더니

이렇게 취약점 하나가 발견되었습니다. 이때 npm install fix라는 명령어를 실행하면 npm이 Version Range Syntax를 준수하면서도, 취약점이 해결된 더 최신 버전의 패키지를 자동으로 설치해줍니다. 하지만 이 npm install fix 만으로는 문제를 해결하지 못하는 경우도 있는데요. 이럴 때는 More info에 있는 URL로 들어가서 필요한 해결 조치를 보고 직접 수행해주면 됩니다.

방금 말한 방법들을 사용하면 보안상 취약한 패키지들을 사용하게 될 가능성은 작아지겠죠?

3. 패키지의 가용성(Availability) 문제

세 번째로 문제점은 사용 중이던 패키지가 갑자기 사라져버리거나 관리되지 않고 방치될 수도 있다는 점입니다. 실제로 2016년에는 left-pad라고 하는 패키지의 주인이 npm 저장소에서 그 패키지를 삭제해버린 사건이 있었습니다.[4] 이 때문에 당시 left-pad에 의존하고 있던, React나 Babel 같은 대형 프로젝트들에도 큰 문제가 발생했었는데요. 다행히 이 문제는 잘 해결되었지만, 이 사건은 당시 수많은 패키지들의 의존 생태계가 단 한 순간에 무너져버릴 수도 있다는 공포감을 개발자들에게 심어주었습니다. 그리고 단순한 기능 정도는 패키지를 굳이 쓰지 말자는 의식의 전환을 가져다주기도 했죠. 왜냐하면 당시 left-pad의 코드는 아래와 같이 단순한 코드였기 때문입니다.

module.exports = leftpad;

function leftpad (str, len, ch) {
  str = String(str);
  var i = -1;
  if (!ch && ch !== 0) ch = ' ';
  len = len - str.length;
  while (++i < len) {
    str = ch + str;
 }
  return str;
}

이런 작은 코드 조각이 수많은 회사들을 당황하게 만든 겁니다. 놀라운 사실이죠?

현재, npm 저장소에 한 번 올린 패키지는, 올리고 나서 72시간이 지나면 함부로 삭제할 수 없도록 되어 있습니다. 그래서 이제 그런 문제는 발생할 수 없겠지만 내가 사용하는 패키지가 앞으로도 잘 관리될 패키지인지를 확인하는 것은 여전히 중요합니다. 이 부분은 패키지의 인기도, 패키지를 관리하는 주체 등을 보고 스스로 잘 판단해야겠죠?
자, 이때까지 다른 패키지들에 의존함으로써 발생할 수 있는 문제들을 살펴봤습니다. 어떤 플랫폼도 마찬가지지만, 특히 Node.js의 패키지 생태계는 다양하고 유용한 패키지들이 아주 많이 존재한다는 점이 매력적입니다. 하지만 이렇게 다양한 패키지들을 자유롭게 사용하는 편리함을 누리는 만큼, 그 대가로 우리는 사용하는 패키지에 대해

  • 이상한 코드는 없는지,
  • 외부의 공격에 취약한 부분은 없는지,
  • 앞으로도 꾸준한 업데이트가 이루어질지를

잘 고민하고 사용해야 합니다. 특정 분야에서 사실상 표준(de facto standard)처럼 존재하는 패키지가 있는 경우라면 상관없지만, 그렇지 않은 경우에 어떤 패키지를 사용하려고 한다면, 방금 위에서 설명한 기준들을 충족하는지 잘 판단하고 사용 여부를 결정하세요.

'develop > Node' 카테고리의 다른 글

패키지를 npm 공개 저장소에 올리기  (0) 2023.11.28
package.json 필드정리  (0) 2023.11.28
패키지가 로드되는 두가지 방법  (1) 2023.11.28
20231122_TIL  (0) 2023.11.23
node 프로젝트에 mysql 연동 & 테이블 생성  (1) 2023.11.22

이번 노트에서는 이전 영상에서 제가 직접 만든 패키지를 npm 공개 저장소에 업로드해보겠습니다. 혹시 자신이 만든 패키지를 업로드하고 싶은 분은 아래 절차를 따라 해보세요.

1. npm 회원가입

1> 먼저 npm 공식 홈페이지에서 화면 우측 상단의 Sign up 버튼을 누르세요.

2> 그다음 사용할 사용자 이름(Username)과 이메일 주소, 비밀번호를 입력한 후, '약관 동의' 버튼에 체크하고, Create an Account 버튼을 클릭하세요.

3> 회원 가입을 마쳤으면, Sign in 버튼을 클릭해서 로그인하세요.

4> 사용자 이름과 비밀번호를 입력하고 Sign In 버튼을 클릭하세요.

5> 그럼 이렇게 화려한 메인 화면이 보이는데요. 관심이 있는 분들은 화면의 여러 기능을 직접 사용해보세요.

화면 상단을 보면 아직 제가 이메일 인증을 하지 않았다는 경고 문구가 보입니다. 이메일 인증까지 마쳐야 나중에 패키지를 업로드할 수 있습니다. 화면 상단의 'Do you need us to send it again?' 부분을 클릭하고, 회원가입할 때 입력했던 이메일로 가세요.

6> 그럼 이렇게 인증 링크가 담긴 이메일이 와있을 겁니다. 인증 링크를 클릭하세요.

7> 이제 이메일 인증이 완료되었습니다. Continue 버튼을 누르세요.

8> 그럼 다시 메인 화면으로 돌아갑니다.

자, 이제 제 패키지를 업로드해봅시다.

2. 패키지 업로드(publish)

(1) 패키지 업로드

1> 먼저 터미널을 실행합시다.(VScode의 내장 터미널을 사용하셔도 됩니다) 그리고

 

 

npm login

 

이라고 쓰고 엔터를 쳐보세요. 그럼 사용자 이름과 비밀번호를 입력할 수 있는데요. 방금 가입할 때 썼던 아이디와 비밀번호를 입력하고 엔터를 치세요. 비밀번호는 입력해도 입력된 것처럼 보이지 않으니까 그냥 입력하고 엔터를 치면 됩니다.

2> 그럼 로그인이 완료됩니다. 그다음

 
npm whoami

라고 쓰고 실행해보면 지금 인증된 사용자가 누구인지 확인할 수 있습니다. codeit-teacher라고 잘 뜨죠? 여러분은 여러분의 사용자 이름이 뜰 겁니다.

3> 자, 이제 바로 패키지를 npm 저장소에 공개할 수 있습니다.

 
npm publish

라는 명령어를 쓰고 엔터를 쳐보세요.

자, 이렇게 codeit_node_study@1.0.0이라는 패키지가 npm 저장소에 업로드되었습니다. 이미 첫 번째로 codeit_node_study라는 패키지를 올린 수강생 분이 있다면 더 이상 같은 이름의 패키지는 업로드할 수 없습니다. 따라서 package.json 파일에서 패키지 이름 부분을 여러분이 원하는 대로 다른 이름으로 수정하고 업로드해주세요! 참고로 이렇게 [패키지 이름]@[버전] 형식의 명칭으로 하나의 고유한 패키지를 식별할 수 있다는 점을 기억하세요.

4> 정말로 공개가 잘 되었는지 홈페이지에서 직접 확인해보겠습니다.

codeit-node-study라고 검색했더니 정말로 패키지가 잘 보이네요.

자, 이렇게 간단하게 자신의 패키지를 업로드할 수 있다는 게 정말 신기하죠? 앞으로 자바스크립트와 Node.js 공부를 열심히 하고 여러분 나름의 멋진 패키지를 만들어서 이렇게 npm 공개 저장소에 올리는 걸 목표로 해보는 건 어떨까요?

(2) 패키지 버전 업데이트

하나의 패키지는 시간이 지날수록 발전합니다. 패키지에 새로운 코드와 파일들이 추가되거나 기존의 코드가 수정되는 작업이 반복되면서 말이죠. 이때 이전 노트에서 설명했던 것처럼 그 내용에 맞게 Semantic Version을 업데이트해줘야 하는데요. 이렇게 버전을 업데이트한 후에는 npm 저장소에도 새 버전의 패키지를 올려주면 좋겠죠? 그 방법을 한번 알아보겠습니다.

1> 일단 현재 패키지가 업그레이드되었다고 가정하고 패키지 버전을 업데이트해보겠습니다. 패키지의 버전을 업데이트 하려면

 
npm version

이라고 쓰고 그 뒤에 새로운 버전을 써주면 됩니다. 저는 원래 1.0.0 버전이었으니까 패치 버전만 업데이트해서 1.0.1이라고 한번 써볼게요.

그리고 나서는 쉽습니다. 그냥 또

 
npm publish

를 해주면 됩니다.

그럼 마찬가지로 새로운 버전의 패키지도 npm 공개 저장소에 잘 업로드됩니다.

2> 원래의 패키지 화면을 새로고침하고 Versions 라는 탭을 클릭해보면, 이때까지의 패키지 히스토리를 볼 수 있습니다. 이전에 올린 1.0.0 버전과 방금 올린 1.0.1 버전이 잘 보이죠?

3> 그다음 저는 버전을 1.0.0 → 1.0.1 → 1.1.0 → 2.0.1 로 계속 올리고 매번 publish를 해봤는데요. 그리고 나서 다시 확인해보면 아래 이미지처럼 각 버전이 모두 잘 보입니다.

(3) 공개된 패키지 다시 내리기

1> 만약 공개된 패키지를 다시 npm 저장소에서 없애고 싶다면 어떻게 해야 할까요? 만약 특정 버전의 패키지만 없애고 싶다면

 
npm unpublish [패키지 이름]@[버전]

형식의 명령어를 입력해주면 됩니다. codeit_node_study 패키지 1.0.1 버전을 npm 저장소에서 없애볼게요.

그다음 확인해보면(반영되는데 시간이 좀 걸릴 수도 있습니다)

2> 1.0.1 버전만 깔끔하게 사라진 것을 확인할 수 있습니다.

3> 그렇다면 만약 모든 버전의 패키지를, 없애고 싶다면 어떻게 해야 할까요? 그럴 때는

 
npm unpublish [패키지 이름] --force

라고 쓰면 됩니다. 패키지의 모든 버전을 npm 저장소에서 삭제하는 건 위험한 작업이기 때문에 --force(강제로 실행하다) 옵션을 줘야 실행할 수 있는데요. 실행해보면,

"I sure hope you know what you are doing(당신이 지금 무슨 작업을 하는지를 알고 있기를 바랍니다)"이라는 경고 문구가 뜨네요.

다시 웹 페이지에서 확인해보면

같은 URL을 새로고침했는데 이제는 codeit_node_study 패키지가 존재하지 않는다고 뜨네요. 공개한 패키지를 삭제하는 것도 어렵지 않죠?

'develop > Node' 카테고리의 다른 글

패키지 간 의존 관계의 위험성  (1) 2023.11.28
package.json 필드정리  (0) 2023.11.28
패키지가 로드되는 두가지 방법  (1) 2023.11.28
20231122_TIL  (0) 2023.11.23
node 프로젝트에 mysql 연동 & 테이블 생성  (1) 2023.11.22

패키지 안에 있는 package.json 파일에는 해당 패키지에 관한 의미있는 정보들이 담겨있습니다. 이번 노트에서는 package.json에 등장할 수 있는 주요 필드들에 대해서 설명해드리겠습니다. 하나하나 꼼꼼하게 읽어보세요.

1. name

패키지의 이름입니다. 우리가 특정 패키지를 사용하기 위해 코드에서 require 함수의 인자로 넣는 것이 바로 여기에 적힌 이름입니다.

2. version

패키지의 버전입니다. 하나의 패키지는 그 안의 코드 등이 개선될수록 버전이 업데이트되는데요. 바로 위의 name 필드와 이 version 필드를 결합하면 특정 패키지특정 버전을 나타낼 수 있습니다.

3. description

패키지에 대한 설명입니다. 패키지를 검색할 때 여기 있는 내용도 검색 기준으로 활용되기 때문에 자신의 패키지가 잘 검색되도록 하려면 여기에 알맞은 설명을 써두는 게 좋습니다.

4. keywords

패키지에 대한 키워드들입니다. 우리가 SNS에서 이미지를 올릴 때 함께 적는 해시태그 같은 거라고 생각하시면 됩니다. keywords도 description처럼 검색 기준으로 활용되기 때문에 적절한 키워드들을 써주면 좋습니다.

5. homepage

패키지 관련 사이트의 URL입니다. 패키지 관련 커뮤니티의 홈페이지 주소가 있는 경우가 많습니다.

6. bugs

패키지를 사용하다가 발생하는 버그들을 신고할 수 있는 URL이나 이메일 주소가 적혀있습니다. 여러분도 패키지를 사용하다가 이상한 점이 있다면 이 필드를 보고 신고하면 좋겠죠?

7. license

패키지의 라이센스 정보가 담겨있습니다. 패키지가 가질 수 있는 라이센스의 종류에 대해 알고 싶다면 이 링크를 참조하세요.

8. author, contributors

author는 패키지를 만든 사람, contributors는 패키지를 만드는데 기여하는 사람들입니다. 이 모두가 모여 패키지를 점점 더 개선해나가는 것입니다.

9. main

이 패키지를

 
require('패키지 이름')

로 로드했을 때 실제로 로드되는 파일의 이름이 적혀있는 필드입니다. 이전 영상에서 require 함수가 모듈을 로드하는 절차를 설명할 때 이야기했던 필드인데요.

예를 들어, A라는 패키지가 있고, A 패키지의 package.json 파일의 내용 중, main 필드에 start.js라는 값이 적혀있다고 합시다.

그럼 해당 프로젝트에 있는 다른 어떤 자바스크립트 파일 안에서 require('A') 코드는 결국 start.js 파일을 로드한다는 뜻이고, 이 start.js 파일 내의 코드에서 exports, module.exports 등으로 외부에 공개한 객체를 가져오게 되는 겁니다. 대부분의 패키지가 이런 방식으로 사용되기 때문에 보통 package.json 파일에는 main 필드가 존재합니다. 만약 main 필드가 없다면, 이전 영상에서 배운 것처럼 작업 디렉토리 안에서 index.js라는 파일을 찾아서 로드합니다.

main 필드는 꼭 정확하게 기억해두세요!

10. man

이 패키지의 사용 설명서가 담긴 파일들의 경로가 적혀있습니다.

11. repository

이 패키지의 코드가 관리되고 있는 레포지토리(repository)의 주소를 나타냅니다. 보통 버전 관리 시스템의 저장소 URL(GitHub URL 등)이 여기 적혀있습니다. 레포지토리가 정확히 무엇인지 알고 싶은 분들은 코드잇의 'Git' 토픽에서 이 영상을 참고하세요.

12. scripts

여기에는 npm으로 간편하게 실행할 수 있는 스크립트 파일들의 정보가 담겨있습니다. 만약 이 필드에

 
"scripts" : { 
  "test" : "실행할 커맨드 A"
}

이런 식으로 적혀있으면 터미널에서

 
npm run test

라고 쓰고 실행했을 때 '실행할 커맨드 A'가 실행됩니다.

예를 들어, sample.js라는 파일에

 
console.log('Test Completed!');

라고 쓰고 저장한 다음, scripts 필드에는

 
"scripts" : { 
  "test" : "node sample.js"
}

라고 쓰고 저장하면

터미널에서 npm run test라고 쓰고 실행했을 때,

'node sample.js'가 실행되고 그 결과가 잘 출력됩니다.

잠깐 express 패키지의 package.json 파일의 scripts 필드를 예시로 보면

이렇게 다양한 단어들이 보이는데요. 대부분 코드 테스트에 관한 커맨드인 것 같죠? 이렇게 scripts 필드는 특히 길이가 긴 명령어를 즐겨찾기해두고 좀 더 편하게 호출하기 위해 사용하는 필드입니다. 나중에 npm을 능숙하게 다루게 됐을 때 자주 찾아보게 될 필드니까 잘 기억해두세요.

scripts 필드에 대해 더 자세히 알고 싶은 분은 이 링크를 참조하세요.

13. dependencies

현재 패키지가 의존하고 있는 다른 패키지들이 나열되어 있는 필드입니다. 이전 영상에서 제가 강조했던 필드죠? 이 필드는 Node.js 패키지 생태계의 핵심이 되는 필드라고 했습니다. 왜냐하면 어떤 패키지를 설치할 때 결국, 이 필드가 있어야, 필요한 하위 패키지들을 설치할 수 있기 때문입니다. 잠깐 express 패키지의 dependencies를 볼까요?

express 모듈 하나도 정말 많은 모듈에 의존하고 있네요. 그리고 자세히보면, 각 dependency의 정보로는,

  • 왼쪽에 모듈의 이름, 오른쪽에 모듈의 버전 정보

가 적혀있습니다. 버전 정보의 경우 빨간 박스 안을 보면

총 세 개의 숫자로 이루어져 있고 맨 앞에 물결 모양 표기가 있는 것도 있는데요.

버전 정보에 대한 이야기는 다음 노트에서 하겠습니다.
자, 이때까지 package.json 파일의 각 필드에 대해서 살펴봤습니다. package.json 파일은 꽤 중요한 파일이기 때문에 각 필드의 기본적인 의미를 기억해둬야 합니다. package.json 파일에 등장하는 모든 필드에 대해서 알고 싶다면 공식 문서의 내용을 참고하세요.

서드파티 패키지를 로드하면 빨간색 화살표가 표시된 순서대로 과정이 진행된다.

마지막 index.js 에는 표시가 되어있지 않아도 될 텐데 표시된 이유는

package.json 파일이 존재하지 않는 경우뿐만 아니라 package.json 파일이 존재하는 경우라도 그 내용중에 main vlfemrk djqtdmaus index.js파일이 로드되기 때문

 

또한 패키지 안에 package.json 파일이 있을 때, package.json 파일의 내용 중 main 필드가 존재하면 거기에 적힌 파일을 로드하고 main 필드가 존재하지 않으면 index.js 파일을 로드한다.

'develop > Node' 카테고리의 다른 글

패키지를 npm 공개 저장소에 올리기  (0) 2023.11.28
package.json 필드정리  (0) 2023.11.28
20231122_TIL  (0) 2023.11.23
node 프로젝트에 mysql 연동 & 테이블 생성  (1) 2023.11.22
express 로 서버 실행 예시  (0) 2023.11.20

오늘 할 일 

  • db 테이블 검토 (수정)
  • 팀원들 코드 수정

느낀점

우리 팀원들이 참 열심히 해서 기쁘다

2023.11.22 - [sparta/Node] - node 프로젝트에 mysql 연동 & 테이블 생성

 

node 프로젝트에 mysql 연동 & 테이블 생성

1. sequelize 설치 npm i sequelize mysql2 2. 개발단계에서 sequelize 명령어를 사용하기 위한 패키지 설치 npm i -D sequelize-cli 3. sequelize 를 사용하도록 필요한 파일 설치 npx sequelize init 4. 소스관리를 위해 config

sunalog.tistory.com

내일 할 일 

  • 팀에서 하는 백엔드 개발은 마무리시키기
  • 백엔드 개발부분 검토 후 수정
  • 챌린지반 수업 듣기
  • 알고리즘 스터디

'develop > Node' 카테고리의 다른 글

package.json 필드정리  (0) 2023.11.28
패키지가 로드되는 두가지 방법  (1) 2023.11.28
node 프로젝트에 mysql 연동 & 테이블 생성  (1) 2023.11.22
express 로 서버 실행 예시  (0) 2023.11.20
.prettierrc 파일 예시  (1) 2023.11.20

1. sequelize 설치

npm i sequelize mysql2

2. 개발단계에서 sequelize 명령어를 사용하기 위한 패키지 설치

npm i -D sequelize-cli

3. sequelize 를 사용하도록 필요한 파일 설치 

npx sequelize init

4. 소스관리를 위해 config.json파일 변경

5. config를 사용해 db 접속

npx sequelize db:create --config config/config.cjs

6. sequelize 를 사용한 테이블 생성 (ex:users테이블)

//테이블 모델링
npx sequelize model:generate --name users --attributes email:string,password:string,name:string

//테이블 생성
npx sequelize db:migrate --config config/config.cjs

 

'develop > Node' 카테고리의 다른 글

패키지가 로드되는 두가지 방법  (1) 2023.11.28
20231122_TIL  (0) 2023.11.23
express 로 서버 실행 예시  (0) 2023.11.20
.prettierrc 파일 예시  (1) 2023.11.20
[Node.js] 환경변수 파일 .env 생성하기  (0) 2023.11.03

+ Recent posts