Ethan Hur's blog

Security 101 - npm audit으로 알아보는 Vulnerability Scan

2019-06-27

Security 101 - Vulnerability Scan

우리는 개발을 하면서 많은 라이브러리들을 가져다 쓴다. 이런 라이브러리들은 우리가 바퀴를 재발명하지 않고 우리가 해결해야 할 문제들을 편리하게 해결하도록 한다.

하지만 오픈소스 라이브러리를 쓰면서 이를 잘 관리하기는 쉽지 않다. 특히 프로덕션에 나간 안정적인 라이브러리를 꾸준히 업데이트하는 것은 쉬운 일이 아니다. 많은 개발자들이 보안에 신경을 잘 쓰지 않는 점도 있다.

그러나 지속적으로 해당 라이브러리를 관리하고 업데이트하지 않으면 작게는 Denial Of Service 의 위험에 노출될 수도 있고, 정말 심하게는 비트코인 지갑주소를 탈취당할 수도 있다.

이처럼 다양한 오픈소스 라이브러리들의 알려진 취약점을 분석해주는 것을 Vulnerability Scan, 또는 Dependency Scan 이라고 한다. (정확하게 정의된 명칭은 없고 다들 비스무리하게 부르는 것 같다) 대부분의 보안 솔루션들은 지원하는 기능이기도 하다.

Node의 경우 굳이 보안 솔루션까지 쓰지 않더라도 npm 6 버전 이상을 쓴다면 자체적으로 audit 기능이 있어, 이를 활용하면 dependency 에 어떤 문제가 있는지 확인하기 쉽다. npm 에 관련 기능이 내장되게 되면서 사용성이 훨씬 좋아진 듯 하다. 테스트를 위해 충분히 예전 버전의 express 와 request 를 깔아보았다.

1
2
npm install express@4.15.1
npm install request@2.81.0

그 후 npm audit 을 해보면 다음과 같은 리포트가 뜨게 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
=== npm audit security report ===
# Run npm install express@4.17.1 to resolve 8 vulnerabilities
...
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ High │ Regular Expression Denial of Service │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package │ fresh │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ express │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path │ express > fresh │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info │ https://npmjs.com/advisories/526 │
└───────────────┴──────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ High │ Regular Expression Denial of Service │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package │ fresh │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ express │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path │ express > send > fresh │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info │ https://npmjs.com/advisories/526 │
└───────────────┴──────────────────────────────────────────────────────────────┘
...
# Run npm install request@2.88.0 to resolve 4 vulnerabilities
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Moderate │ Prototype Pollution │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package │ hoek │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ request │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path │ request > hawk > boom > hoek │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info │ https://npmjs.com/advisories/566 │
└───────────────┴──────────────────────────────────────────────────────────────┘
...
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Moderate │ Prototype Pollution │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package │ hoek │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ request │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path │ request > hawk > sntp > hoek │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info │ https://npmjs.com/advisories/566 │
└───────────────┴──────────────────────────────────────────────────────────────┘

어떤 취약점이 있는지까지 자세하게 설명해준다. (Regular Expression DoS 를 이번에 처음 들어봤다) 이를 고치고 싶으면 npm audit fix 를 해서 고치면 편-안 하게 업데이트 해준다.

일을 하기 싫을 때 가끔씩 돌려서 security report 를 받아보자. 보안 패치는 분명 귀찮은 일이지만 만에 하나 사고가 발생하면 누가 책임져줄 수 없다.

npm 버전이 낮다면 retire.js 가 거의 비슷한 기능을 CLI 로 제공하니 그쪽을 써도 무방하다. (물론 솔루션을 써도 된다)

이미 하고 있다면 당신은 훌륭한 사람이다


참조