์‚ฌ์šฉ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ์ทจ์•ฝ์  ์Šค์บ๋„ˆ ์‚ฌ์šฉ GitlabCI์˜ ์ข…์†์„ฑ ํ™•์ธ

์ทจ์•ฝ์„ฑ ๊ด€๋ฆฌ์˜ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์€ ์ตœ์‹  ์‹œ์Šคํ…œ์„ ๊ตฌ์„ฑํ•˜๋Š” ์†Œํ”„ํŠธ์›จ์–ด ๊ตฌ์„ฑ ์š”์†Œ์˜ ๊ณต๊ธ‰๋ง์„ ์ฒ ์ €ํ•˜๊ฒŒ ์ดํ•ดํ•˜๊ณ  ๋ณดํ˜ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Agile ๋ฐ DevOps ํŒ€์€ ์˜คํ”ˆ ์†Œ์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐœ๋ฐœ ์‹œ๊ฐ„๊ณผ ๋น„์šฉ์„ ์ค„์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๋ฉ”๋‹ฌ์—๋Š” ๋‹จ์ ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๋‹ค๋ฅธ ์‚ฌ๋žŒ์˜ ์‹ค์ˆ˜์™€ ์ทจ์•ฝ์„ฑ์„ ๋ฌผ๋ ค๋ฐ›์„ ๊ธฐํšŒ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ถ„๋ช…ํžˆ ํŒ€์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์–ด๋–ค ์˜คํ”ˆ ์†Œ์Šค ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ์•Œ๋ ค์ง„ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒ„์ „์ด ์•Œ๋ ค์ง„ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์†Œ์Šค์—์„œ ๋‹ค์šด๋กœ๋“œ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ์ƒˆ๋กœ ๋ฐœ๊ฒฌ๋œ ์ทจ์•ฝ์ ์ด ํŒจ์น˜๋œ ํ›„ ์—…๋ฐ์ดํŠธ๋œ ๋ฒ„์ „์˜ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ฒŒ์‹œ๋ฌผ์—์„œ๋Š” ์ฝ”๋“œ์—์„œ ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ๊ฒฌ๋˜๋ฉด ๋นŒ๋“œ๋ฅผ ์ค‘๋‹จํ•˜๊ธฐ ์œ„ํ•ด OWASP ์ข…์†์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ใ€Ž์• ์ž์ผ ํ”„๋กœ์ ํŠธ์˜ ๊ฐœ๋ฐœ ๋ณด์•ˆใ€์ด๋ผ๋Š” ์ฑ…์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค๋ช…๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. OWASP ์ข…์†์„ฑ ๊ฒ€์‚ฌ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์‚ฌ์šฉ๋˜๋Š” ๋ชจ๋“  ์˜คํ”ˆ ์†Œ์Šค ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์นดํƒˆ๋กœ๊ทธํ™”ํ•˜๊ณ  ์—ฌ๊ธฐ์— ํฌํ•จ๋œ ์ทจ์•ฝ์ ์„ ๋ณด์—ฌ์ฃผ๋Š” ๋ฌด๋ฃŒ ์Šค์บ๋„ˆ์ž…๋‹ˆ๋‹ค. Java, .NET, Ruby(gemspec), PHP(composer), Node.js, Python์šฉ ๋ฒ„์ „์€ ๋ฌผ๋ก  ์ผ๋ถ€ C/C++ ํ”„๋กœ์ ํŠธ์šฉ ๋ฒ„์ „๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ข…์†์„ฑ ํ™•์ธ์€ Ant, Maven, Gradle ๋“ฑ์˜ ์ผ๋ฐ˜์ ์ธ ๋นŒ๋“œ ๋„๊ตฌ์™€ Jenkins์™€ ๊ฐ™์€ ์ง€์†์ ์ธ ํ†ตํ•ฉ ์„œ๋ฒ„์™€ ํ†ตํ•ฉ๋ฉ๋‹ˆ๋‹ค.

์ข…์†์„ฑ ๊ฒ€์‚ฌ๋Š” NIST์˜ NVD(National Vulnerability Database)์—์„œ ์•Œ๋ ค์ง„ ์ทจ์•ฝ์ ์ด ์žˆ๋Š” ๋ชจ๋“  ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ณด๊ณ ํ•˜๊ณ  NVD ๋‰ด์Šค ํ”ผ๋“œ์˜ ๋ฐ์ดํ„ฐ๋กœ ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค.

๋‹คํ–‰ํžˆ ์ด ๋ชจ๋“  ์ž‘์—…์€ OWASP ์ข…์†์„ฑ ๊ฒ€์‚ฌ ํ”„๋กœ์ ํŠธ์™€ ๊ฐ™์€ ๋„๊ตฌ๋‚˜ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒ์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž๋™์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ธ”๋ž™ ๋•, JFrog ์—‘์Šค๋ ˆ์ด, ์Šค ๋‹ˆํฌ, Nexus ์ˆ˜๋ช…์ฃผ๊ธฐ ์†Œ๋‚˜ํƒ€์ž… ๋˜๋Š” ์ถœ์ฒ˜์ง€์šฐ๊ธฐ.

์ด๋Ÿฌํ•œ ๋„๊ตฌ๋Š” ๋นŒ๋“œ ํŒŒ์ดํ”„๋ผ์ธ์— ํฌํ•จ๋˜์–ด ์˜คํ”ˆ ์†Œ์Šค ์ข…์†์„ฑ์„ ์ž๋™์œผ๋กœ ์ธ๋ฒคํ† ๋ฆฌํ™”ํ•˜๊ณ , ์•Œ๋ ค์ง„ ์ทจ์•ฝ์ ์ด ํฌํ•จ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์˜ค๋ž˜๋œ ๋ฒ„์ „์„ ์‹๋ณ„ํ•˜๊ณ , ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๊ฐ€ ๊ฐ์ง€๋˜๋ฉด ๋นŒ๋“œ๋ฅผ ์ค‘๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

OWASP ์ข…์†์„ฑ ํ™•์ธ

์ข…์†์„ฑ ๊ฒ€์‚ฌ๊ฐ€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ํ…Œ์ŠคํŠธํ•˜๊ณ  ์‹œ์—ฐํ•˜๊ธฐ ์œ„ํ•ด ์ด ์ €์žฅ์†Œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ข…์†์„ฑ ๊ฒ€์‚ฌ ์˜ˆ.

HTML ๋ณด๊ณ ์„œ๋ฅผ ๋ณด๋ ค๋ฉด gitlab-runner์—์„œ nginx ์›น ์„œ๋ฒ„๋ฅผ ๊ตฌ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ตœ์†Œ nginx ๊ตฌ์„ฑ์˜ ์˜ˆ:

server {
    listen       9999;
    listen       [::]:9999;
    server_name  _;
    root         /home/gitlab-runner/builds;

    location / {
        autoindex on;
    }

    error_page 404 /404.html;
        location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }
}

์–ด์…ˆ๋ธ”๋ฆฌ๊ฐ€ ๋๋‚˜๋ฉด ๋‹ค์Œ ๊ทธ๋ฆผ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ์ทจ์•ฝ์  ์Šค์บ๋„ˆ ์‚ฌ์šฉ GitlabCI์˜ ์ข…์†์„ฑ ํ™•์ธ

๋งํฌ๋ฅผ ๋”ฐ๋ผ๊ฐ€์„œ ์ข…์†์„ฑ ๊ฒ€์‚ฌ ๋ณด๊ณ ์„œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

์ฒซ ๋ฒˆ์งธ ์Šคํฌ๋ฆฐ์ƒท์€ ์š”์•ฝ์ด ํฌํ•จ๋œ ๋ณด๊ณ ์„œ์˜ ์ƒ๋‹จ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.

์‚ฌ์šฉ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ์ทจ์•ฝ์  ์Šค์บ๋„ˆ ์‚ฌ์šฉ GitlabCI์˜ ์ข…์†์„ฑ ํ™•์ธ

๋‘ ๋ฒˆ์งธ ์Šคํฌ๋ฆฐ์ƒท์—์„œ๋Š” CVE-2017-5638์„ ์ž์„ธํžˆ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” CVE ์ˆ˜์ค€๊ณผ ์ต์Šคํ”Œ๋กœ์ž‡ ๋งํฌ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ์ทจ์•ฝ์  ์Šค์บ๋„ˆ ์‚ฌ์šฉ GitlabCI์˜ ์ข…์†์„ฑ ํ™•์ธ

์„ธ ๋ฒˆ์งธ ์Šคํฌ๋ฆฐ์ƒท์€ log4j-api-2.7.jar์˜ ์„ธ๋ถ€์ •๋ณด์ž…๋‹ˆ๋‹ค. CVE ์ˆ˜์ค€์€ 7.5์™€ 9.8์ž„์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ์ทจ์•ฝ์  ์Šค์บ๋„ˆ ์‚ฌ์šฉ GitlabCI์˜ ์ข…์†์„ฑ ํ™•์ธ

๋„ค ๋ฒˆ์งธ ์Šคํฌ๋ฆฐ์ƒท์€ commons-fileupload-1.3.2.jar์˜ ์„ธ๋ถ€์ •๋ณด์ž…๋‹ˆ๋‹ค. CVE ์ˆ˜์ค€์€ 7.5์™€ 9.8์ž„์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ์ทจ์•ฝ์  ์Šค์บ๋„ˆ ์‚ฌ์šฉ GitlabCI์˜ ์ข…์†์„ฑ ํ™•์ธ

gitlab ํŽ˜์ด์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‹คํŒจํ•œ ์ž‘์—…์€ ์•„ํ‹ฐํŒฉํŠธ๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ ์˜ˆ https://gitlab.com/anton_patsev/dependency-check-example-gitlab-pages.

๋นŒ๋“œ ์ถœ๋ ฅ: ์•„ํ‹ฐํŒฉํŠธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. HTML ๋ณด๊ณ ์„œ๊ฐ€ ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Artifact: Always๋ฅผ ์‚ฌ์šฉํ•ด ๋ณด์„ธ์š”.

https://gitlab.com/anton_patsev/dependency-check-example-gitlab-pages/-/jobs/400004246

์‚ฌ์šฉ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ์ทจ์•ฝ์  ์Šค์บ๋„ˆ ์‚ฌ์šฉ GitlabCI์˜ ์ข…์†์„ฑ ํ™•์ธ

CVE ์ทจ์•ฝ์  ์ˆ˜์ค€ ๊ทœ์ œ

gitlab-ci.yaml ํŒŒ์ผ์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ค„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

mvn $MAVEN_CLI_OPTS test org.owasp:dependency-check-maven:check -DfailBuildOnCVSS=7

fallBuildOnCVSS ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋Œ€์‘ํ•ด์•ผ ํ•˜๋Š” CVE ์ทจ์•ฝ์„ฑ ์ˆ˜์ค€์„ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ธํ„ฐ๋„ท์—์„œ NIST ์ทจ์•ฝ์  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(NVD) ๋‹ค์šด๋กœ๋“œ

NIST๊ฐ€ ์ธํ„ฐ๋„ท์—์„œ NIST ์ทจ์•ฝ์„ฑ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(NVD)๋ฅผ ์ง€์†์ ์œผ๋กœ ๋‹ค์šด๋กœ๋“œํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ๊ณ  ๊ณ„์…จ์Šต๋‹ˆ๊นŒ?

์‚ฌ์šฉ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ์ทจ์•ฝ์  ์Šค์บ๋„ˆ ์‚ฌ์šฉ GitlabCI์˜ ์ข…์†์„ฑ ํ™•์ธ

๋‹ค์šด๋กœ๋“œํ•˜๋ ค๋ฉด ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค nist_data_mirror_golang

์„ค์น˜ํ•˜๊ณ  ์‹คํ–‰ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

yum -y install yum-plugin-copr
yum copr enable antonpatsev/nist_data_mirror_golang
yum -y install nist-data-mirror
systemctl start nist-data-mirror

Nist-data-mirror๋Š” ์‹œ์ž‘ ์‹œ NIST JSON CVE๋ฅผ /var/www/repos/nist-data-mirror/์— ์—…๋กœ๋“œํ•˜๊ณ  24์‹œ๊ฐ„๋งˆ๋‹ค ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

CVE JSON NIST๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๋ ค๋ฉด nginx ์›น ์„œ๋ฒ„(์˜ˆ: gitlab-runner์—์„œ)๋ฅผ ๊ตฌ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ตœ์†Œ nginx ๊ตฌ์„ฑ์˜ ์˜ˆ:

server {
    listen       12345;
    listen       [::]:12345;
    server_name  _;
    root         /var/www/repos/nist-data-mirror/;

    location / {
        autoindex on;
    }

    error_page 404 /404.html;
        location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }

}

mvn์ด ์‹คํ–‰๋˜๋Š” ๊ณณ์— ๊ธด ์ค„์ด ์ƒ๊ธฐ์ง€ ์•Š๋„๋ก ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ๋ณ„๋„์˜ ๋ณ€์ˆ˜ DEPENDENCY_OPTS๋กœ ์ด๋™ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ตœ์ข… ์ตœ์†Œ ๊ตฌ์„ฑ .gitlab-ci.yml์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

variables:
  MAVEN_OPTS: "-Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true"
  MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true"
  DEPENDENCY_OPTS: "-DfailBuildOnCVSS=7 -DcveUrlModified=http://localhost:12345/nvdcve-1.1-modified.json.gz -DcveUrlBase=http://localhost:12345/nvdcve-1.1-%d.json.gz"

cache:
  paths:
    - .m2/repository

verify:
  stage: test
  script:
    - set +e
    - mvn $MAVEN_CLI_OPTS install org.owasp:dependency-check-maven:check $DEPENDENCY_OPTS || EXIT_CODE=$?
    - export PATH_WITHOUT_HOME=$(pwd | sed -e "s//home/gitlab-runner/builds//g")
    - echo "************************* URL Dependency-check-report.html *************************"
    - echo "http://$HOSTNAME:9999$PATH_WITHOUT_HOME/target/dependency-check-report.html"
    - set -e
    - exit ${EXIT_CODE}
  tags:
    - shell

DevOps ๋ฐ ๋ณด์•ˆ์— ๊ด€ํ•œ ํ…”๋ ˆ๊ทธ๋žจ ์ฑ„ํŒ…
ํ…”๋ ˆ๊ทธ๋žจ ์ฑ„๋„ DevSecOps / SSDLC - ๋ณด์•ˆ ๊ฐœ๋ฐœ

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€