튜토리얼: 의존성 스캔 설정

Tier: Ultimate Offering: GitLab.com

의존성 스캔은 소프트웨어 의존성에서 보안 취약점을 자동으로 찾아내며 응용 프로그램을 개발하고 테스트하는 동안 이러한 작업을 수행합니다. 예를 들어, 의존성 스캔을 사용하면 의도하지 않은 보안 취약점이 있는 외부(오픈 소스) 라이브러리를 사용하는지 알 수 있습니다. 그런 다음 응용 프로그램을 보호하기 위해 조치를 취할 수 있습니다.

이 튜토리얼에서는 샘플 취약한 응용 프로그램을 생성한 다음 다음을 수행합니다.

  • 응용 프로그램의 의존성에서 취약점을 감지, 분류 및 해결하는 방법.
  • Merge Request에서 취약점을 감지하는 방법.

의존성 스캔 설정:

시작하기 전에

Gitpod가 활성화되어 있는지 확인하세요. Gitpod는 온디맨드 클라우드 개발 환경입니다. 자세한 내용은 Gitpod을 참조하세요. 그렇지 않으면 자체 개발 환경을 사용할 수 있습니다. 이 경우 Yarn과 Node.js가 설치되어 있어야 합니다.

예제 응용 프로그램 파일 생성

먼저 새 프로젝트에서 파이프라인을 구성하고 새로 검사할 수 있는 의존성을 추가하는 파일을 생성하세요.

  1. 기본값을 사용하여 빈 프로젝트를 생성하세요.

  2. main 브랜치에 다음 파일을 생성하세요.

    파일명: .gitlab-ci.yml

    stages:
    - build
    - test
       
    include:
    - template: Jobs/Dependency-Scanning.gitlab-ci.yml
       
    # 의존성 스캔 작업을 재정의합니다.
    gemnasium-dependency_scanning:
      tags: [ saas-linux-large-amd64 ]
      rules:
        - if: $CI_COMMIT_BRANCH == "main"
        - if: $CI_MERGE_REQUEST_IID
    

    파일명: index.js

    // Require the framework and instantiate it
    const fastify = require('fastify')({ logger: true })
    const path = require('path')
    //const fetch = require('node-fetch')
       
    fastify.register(require('fastify-static'), {
      root: path.join(__dirname, 'public'),
      prefix: '/'
    })
       
    fastify.register(require('./routes'), {
      message: "hello"
    })
       
    // fastify.register(require('fastify-redis'), { url: constants.redisUrl, /* other redis options */ })
       
    // Run the server!
    const start = async () => {
      try {
        await fastify.listen(8080, "0.0.0.0")
        fastify.log.info(`server listening on ${fastify.server.address().port}`)
         
      } catch (error) {
        fastify.log.error(error)
        //process.exit(1)
      }
    }
    start()
    

    파일명: package.json

    {
      "dependencies": {
        "fastify": "2.14.1",
        "fastify-static": "2.0.0"
      }
    }
    

    파일명: yarn.lock

    Yarn lockfile 섹션에 표시된 내용을 사용하세요.

  3. 빌드 > 파이프라인로 이동하여 최신 파이프라인이 성공적으로 완료되었는지 확인하세요.

파이프라인에서 의존성 스캔이 실행되고 취약점이 자동으로 감지됩니다.

취약점 분류

취약점 보고서는 취약점에 대한 중요한 정보를 제공합니다. 일반적으로 조직 정책에 따라 취약점을 분류합니다. 본 튜토리얼에서는 중간 심각도의 취약점을 보고서에서 필터링하고 높은 심각도의 취약점만 남도록 만듭니다.

취약점을 분류하려면 다음을 수행하세요.

  1. 보안 > 취약점 보고서로 이동하세요.
  2. 각 중간 심각도 취약점의 확인란을 선택하세요.
  3. 상태 설정 드롭다운 디렉터리에서 기각함을 선택하세요. 기각 사유 드롭다운 디렉터리에서 테스트에서 사용을 선택하고 “테스트에서 사용” 주석을 추가한 다음 상태 변경을 선택하세요.

    중간 심각도 취약점은 보고서에서 필터링되어 높은 심각도 취약점만 남게 됩니다.

  4. 높은 취약점 설명을 선택하세요.

    권장 솔루션은 fastify 패키지를 업그레이드하는 것입니다. 일반적으로 이를 더 조사하지만 이 튜토리얼에서는 이 취약점을 확인한 것으로 간주할 수 있습니다.

  5. 상태 드롭다운 디렉터리에서 확인을 선택한 다음 상태 변경을 선택하세요.

높은 심각도 취약점 해결

해결해야 할 취약점은 높은 심각도의 취약점만 남습니다. 분류 단계에서 fastify 패키지를 업그레이드해야 한다는 것을 이미 알고 있습니다.

취약점을 해결하려면 다음을 수행하세요.

  1. 왼쪽 사이드바에서 검색 또는 이동을 선택하고 프로젝트를 찾으세요.
  2. 오른쪽 상단에서 편집 > Gitpod을 선택하고 새 탭에서 Gitpod를 열어주세요.
  3. 프롬프트가 표시되면 GitLab 사용 계속을 선택한 다음 인증을 선택하세요.
  4. 새 워크스페이스 페이지에서 계속을 선택하세요.
  5. 터미널 창에서 다음 명령을 입력하여 새 브랜치를 생성하세요.

    git checkout -b update_packages main
    
  6. 터미널 창에서 yarn upgrade --latest 명령을 실행하세요. 이 명령은 프로젝트의 의존성 및 yarn.lock 파일을 업데이트합니다.
  7. 터미널 창에서 다음 명령을 실행하여 변경 사항을 커밋하세요. 이는 CI/CD 파이프라인을 트리거합니다.

    git add package.json yarn.lock
    git commit -m "패키지 버전 업데이트"
    git push --set-upstream origin update_packages
    
  8. GitLab 브라우저 탭으로 전환하세요.
  9. 코드 > Merge Request로 이동한 다음 새 Merge Request 만들기를 선택하세요.
  10. 새 Merge Request 페이지에서 아래로 스크롤하여 Merge Request 만들기를 선택하세요. Merge Request 파이프라인이 완료될 때까지 기다리세요.
  11. 페이지를 새로고침한 다음 Merge을 선택하세요.
  12. 파이프라인이 성공적으로 완료되길 기다리세요.
  13. 보안 > 취약점 보고서로 이동하세요.
  14. 높은 취약점 설명을 선택하세요.

    배너가 main 브랜치에서 취약점이 해결되었음을 확인합니다. 일반적으로 이를 매뉴얼으로 확인하여 yarn.lock 파일에서 지정된 fastify 패키지 버전을 검증해야 합니다. 본 튜토리얼에서는 검증 단계를 건너 뛸 수 있습니다.

  15. 상태 드롭다운 디렉터리에서 해결을 선택한 다음 상태 변경을 선택하세요.
  16. 보안 > 취약점 보고서로 이동하세요.

    이제 취약점 보고서에 나열된 취약점이 _없음_으로 표시됩니다.

Merge Request에서 취약점 감지 테스트

이제 취약점을 분류하고 해결하는 방법을 알게 되었습니다. 이제 Merge Request에서 새로운 잠재적인 취약점을 감지하는 방법을 확인해보세요. 취약점이 있는 의존성을 추가합니다.

새 취약점을 추가하려면 다음을 수행하세요.

  1. Gitpod 탭으로 전환하세요. 만약 시간 초과되었다면 워크스페이스 열기를 선택하세요.
  2. 터미널 창에서 다음 명령을 실행하여 로컬 main 브랜치를 업데이트하세요.

    git checkout main
    git fetch origin
    git rebase origin/main
    
  3. 터미널 창에서 다음 몤령을 실행하여 새 브랜치를 생성하세요.

    git checkout -b add_dependency main
    
  4. 파일 탐색기 사이드바에서 package.json 파일을 선택하세요.
  5. package.json 파일의 dependencies 섹션에 다음 줄을 추가하세요.

    "axios": "0.21.0",
    
  6. 터미널 창에서 다음 명령을 실행하여 추가된 의존성을 설치하세요.

    yarn install
    
  7. 터미널 창에서 다음 명령을 실행하여 변경 사항을 커밋하세요. 이는 GitLab에서 CI/CD 파이프라인을 트리거합니다.

    git add package.json yarn.lock
    git commit -m "의존성 추가"
    git push --set-upstream origin add_dependency
    
  8. GitLab 브라우저 탭으로 전환하세요.
  9. 코드 > Merge Request로 이동한 다음 새 Merge Request 만들기를 선택하세요.
  10. 새 Merge Request 페이지에서 아래로 스크롤하여 Merge Request 만들기를 선택하세요.

Merge Request 파이프라인이 완료될 때까지 기다린 다음 페이지를 새로 고칩니다. Merge 요청 보안 위젯이 새로운 잠재적인 취약점을 경고합니다. 이러한 취약점은 main 브랜치가 아닌 add_dependency 브랜치에만 존재합니다.

이제 다음을 알게 되었습니다.

  • 응용 프로그램의 의존성에서 취약점을 감지하는 방법.
  • 취약점을 분류하고 해결하는 방법.
  • Merge Request에서 새로운 취약점을 감지하는 방법.

```yaml # 이 파일은 자동 생성된 파일입니다. 직접 편집하지 마십시오. # yarn lockfile v1

abstract-logging@^2.0.0: version “2.0.1” resolved “https://registry.yarnpkg.com/abstract-logging/-/abstract-logging-2.0.1.tgz#6b0c371df212db7129b57d2e7fcf282b8bf1c839” integrity sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==

ajv@^6.10.2, ajv@^6.11.0, ajv@^6.12.0: version “6.12.6” resolved “https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4” integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal “^3.1.1” fast-json-stable-stringify “^2.0.0” json-schema-traverse “^0.4.1” uri-js “^4.2.2”

archy@^1.0.0: version “1.0.0” resolved “https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40” integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==

atomic-sleep@^1.0.0: version “1.0.0” resolved “https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b” integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==

avvio@^6.3.1: version “6.5.0” resolved “https://registry.yarnpkg.com/avvio/-/avvio-6.5.0.tgz#d2cf119967fe90d2156afc29de350ced800cdaab” integrity sha512-BmzcZ7gFpyFJsW8G+tfQw8vJNUboA9SDkkHLZ9RAALhvw/rplfWwni8Ee1rA11zj/J7/E5EvZmweusVvTHjWCA== dependencies: archy “^1.0.0” debug “^4.0.0” fastq “^1.6.0”

cookie@^0.4.0: version “0.4.2” resolved “https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432” integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==

debug@2.6.9: version “2.6.9” resolved “https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f” integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms “2.0.0”

debug@^4.0.0: version “4.3.4” resolved “https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865” integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms “2.1.2”

deepmerge@^4.2.2: version “4.2.2” resolved “https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955” integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==

depd@~1.1.2: version “1.1.2” resolved “https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9” integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==

destroy@~1.0.4: version “1.0.4” resolved “https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80” integrity sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==

ee-first@1.1.1: version “1.1.1” resolved “https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d” integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==

encodeurl@~1.0.2: version “1.0.2” resolved “https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59” integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==

escape-html@~1.0.3: version “1.0.3” resolved “https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988” integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==

etag@~1.8.1: version “1.8.1” resolved “https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887” integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==

fast-decode-uri-component@^1.0.0: version “1.0.1” resolved “https://registry.yarnpkg.com/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz#46f8b6c22b30ff7a81357d4f59abfae938202543” integrity sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==

fast-deep-equal@^3.1.1: version “3.1.3” resolved “https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525” integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==

fast-json-stable-stringify@^2.0.0: version “2.1.0” resolved “https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633” integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==

fast-json-stringify@^1.18.0: version “1.21.0” resolved “https://registry.yarnpkg.com/fast-json-stringify/-/fast-json-stringify-1.21.0.tgz#51bc8c6d77d8c7b2cc7e5fa754f7f909f9e1262f” integrity sha512-xY6gyjmHN3AK1Y15BCbMpeO9+dea5ePVsp3BouHCdukcx0hOHbXwFhRodhcI0NpZIgDChSeAKkHW9YjKvhwKBA== dependencies: ajv “^6.11.0” deepmerge “^4.2.2” string-similarity “^4.0.1”

fast-redact@^2.0.0: version “2.1.0” resolved “https://registry.yarnpkg.com/fast-redact/-/fast-redact-2.1.0.tgz#dfe3c1ca69367fb226f110aa4ec10ec85462ffdf” integrity sha512-0LkHpTLyadJavq9sRzzyqIoMZemWli77K2/MGOkafrR64B9ItrvZ9aT+jluvNDsv0YEHjSNhlMBtbokuoqii4A==

fast-safe-stringify@^2.0.7: version “2.1.1” resolved “https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884” integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==

fastify-plugin@^1.2.0: version “1.6.1” resolved “https://registry.yarnpkg.com/fastify-plugin/-/fastify-plugin-1.6.1.tgz#122f5a5eeb630d55c301713145a9d188e6d5dd5b” integrity sha512-APBcb27s+MjaBIerFirYmBLatoPCgmHZM6XP0K+nDL9k0yX8NJPWDY1RAC3bh6z+AB5ULS2j31BUfLMT3uaZ4A== dependencies: semver “^6.3.0”

fastify-static@2.0.0: version “2.0.0” resolved “https://registry.yarnpkg.com/fastify-static/-/fastify-static-2.0.0.tgz#674f3f3180e8b055e5e1ee1bcee68114cfb09a8f” integrity sha512-8YQ4QWcSR3YJTFLpExXIej2GzCHThowyLUUxt1uZN8rBEEI2T2ZcaRXPmkaNcaUiKzLXceGjdbJm5yByp5dlkA== dependencies: fastify-plugin “^1.2.0” readable-stream “^3.0.2” send “^0.16.0”

fastify@2.14.1: version “2.14.1” resolved “https://registry.yarnpkg.com/fastify/-/fastify-2.14.1.tgz#2946e8e9adebcd1b4f634178c8fb7162fb816cf4” integrity sha512-nSL8AgIdFCpZmFwjqB5Zzv+3/1KpwwVtB/h88Q4Og8njYbkddKGpuQlQ2tHUULXPTJrLZ7wop6olzx6HEbHdpw== dependencies: abstract-logging “^2.0.0” ajv “^6.12.0” avvio “^6.3.1” fast-json-stringify “^1.18.0” find-my-way “^2.2.2” flatstr “^1.0.12” light-my-request “^3.7.3” middie “^4.1.0” pino “^5.17.0” proxy-addr “^2.0.6” readable-stream “^3.6.0” rfdc “^1.1.2” secure-json-parse “^2.1.0” tiny-lru “^7.0.2”

fastq@^1.6.0: version “1.13.0” resolved “https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c” integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== dependencies: reusify “^1.0.4”

find-my-way@^2.2.2: version “2.2.5” resolved “https://registry.yarnpkg.com/find-my-way/-/find-my-way-2.2.5.tgz#86ce825266fa28cd962e538a45ec2aaa84c3d514” integrity sha512-GjRZZlGcGmTh9t+6Xrj5K0YprpoAFCAiCPgmAH9Kb09O4oX6hYuckDfnDipYj+Q7B1GtYWSzDI5HEecNYscLQg== dependencies: fast-decode-uri-component “^1.0.0” safe-regex2 “^2.0.0” semver-store “^0.3.0”

flatstr@^1.0.12: version “1.0.12” resolved “https://registry.yarnpkg.com/flatstr/-/flatstr-1.0.12.tgz#c2ba6a08173edbb6c9640e3055b95e287ceb5931” integrity sha512-4z