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

Tier: Ultimate Offering: GitLab.com

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

이 튜토리얼에서는 샘플 취약한 응용 프로그램을 만드는 방법과 다음을 보여줍니다.

  • 응용 프로그램의 의존성에서 취약점을 감지하고, 체크하고, 해결하는 방법.
  • 병합 요청에서 취약점을 감지하는 방법.

의존성 스캔을 설정하려면:

시작하기 전에

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 */ })
    
    // 서버 실행!
    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. 코드 > 병합 요청으로 이동한 후 병합 요청 생성을 선택하십시오.
  10. 새 병합 요청 페이지로 스크롤하여 병합 요청 생성을 선택하십시오. 병합 요청 파이프라인이 완료될 때까지 기다리십시오.
  11. 페이지를 새로 고침한 후 병합을 선택하십시오.
  12. 파이프라인이 성공적으로 완료될 때까지 기다리십시오.
  13. 보안 > 취약점 보고서로 이동하십시오.
  14. 높은 취약점의 설명을 선택하십시오.

배너가 나와 해당 취약점이 main 브랜치에서 해결되었음을 확인합니다. 일반적으로는 yarn.lock 파일에서 지정된 fastify 패키지의 버전을 수동으로 확인하지만, 본 튜토리얼에서는 이 단계를 생략할 수 있습니다.

  1. 상태 드롭다운 목록에서 해결을 선택하고, 상태 변경을 선택하십시오.
  2. 보안 > 취약점 보고서로 이동하십시오.

이제 취약점 보고서에는 _취약점이 없음_이 표시되어야 합니다.

병합 요청에서 취약점 감지 테스트

이제 취약점을 진단하고 해결하는 방법을 알게되었습니다. 이제 새로운 잠재적인 취약점을 감지하는 방법을 보려면 병합 요청에 이미 취약점이 있는 의존성을 추가하세요.

새로운 취약점을 추가하려면 다음 단계를 따르세요:

  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. 터미널 창에서 package.json 파일에 추가된 종속성을 설치하려면 다음 명령을 실행합니다.

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

    git add package.json yarn.lock
    git commit -m "Add dependency"
    git push --set-upstream origin add_dependency
    
  8. GitLab 브라우저 탭으로 전환합니다.
  9. 코드 > 병합 요청으로 이동한 다음 병합 요청 만들기를 선택합니다.
  10. 새 병합 요청 페이지로 이동하여 페이지 아래쪽으로 스크롤한 다음 병합 요청 만들기를 선택합니다.

병합 요청 파이프라인이 완료될 때까지 기다린 후 페이지를 새로 고쳐주세요. 병합 요청 보안 위젯은 새로운 잠재적인 취약점을 경고합니다. 이러한 취약점은 add_dependency 브랜치에만 있으며 main 브랜치에는 없습니다.

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

  • 애플리케이션의 종속성에서 취약점을 감지할 수 있습니다.
  • 취약점을 진단하고 해결할 수 있습니다.
  • 병합 요청에서 새로운 취약점을 감지할 수 있습니다.

Yarn 잠금 파일 내용

```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#674f3f3180e8b055e5